use of io.github.microcks.domain.Resource in project microcks by microcks.
the class ServiceServiceTest method testImportServiceDefinitionMainAndSecondary.
@Test
public void testImportServiceDefinitionMainAndSecondary() {
List<Service> services = null;
try {
File artifactFile = new File("target/test-classes/io/github/microcks/service/weather-forecast-raw-openapi.yaml");
services = service.importServiceDefinition(artifactFile, null, new ArtifactInfo("weather-forecast-raw-openapi.yaml", true));
} catch (MockRepositoryImportException mrie) {
mrie.printStackTrace();
fail("No MockRepositoryImportException should have be thrown");
}
assertNotNull(services);
assertEquals(1, services.size());
// Inspect Service own attributes.
Service importedSvc = services.get(0);
assertEquals("WeatherForecast API", importedSvc.getName());
assertEquals("1.1.0", importedSvc.getVersion());
assertEquals("weather-forecast-raw-openapi.yaml", importedSvc.getSourceArtifact());
assertNotNull(importedSvc.getMetadata());
assertEquals(1, importedSvc.getOperations().size());
assertNull(importedSvc.getOperations().get(0).getResourcePaths());
// Inspect and check resources.
List<Resource> resources = resourceRepository.findByServiceId(importedSvc.getId());
assertEquals(1, resources.size());
Resource resource = resources.get(0);
assertEquals("WeatherForecast API-1.1.0.yaml", resource.getName());
assertEquals("weather-forecast-raw-openapi.yaml", resource.getSourceArtifact());
// Inspect and check requests.
List<Request> requests = requestRepository.findByOperationId(IdBuilder.buildOperationId(importedSvc, importedSvc.getOperations().get(0)));
assertEquals(0, requests.size());
// Inspect and check responses.
List<Response> responses = responseRepository.findByOperationId(IdBuilder.buildOperationId(importedSvc, importedSvc.getOperations().get(0)));
assertEquals(0, responses.size());
try {
File artifactFile = new File("target/test-classes/io/github/microcks/service/weather-forecast-postman.json");
services = service.importServiceDefinition(artifactFile, null, new ArtifactInfo("weather-forecast-postman.json", false));
} catch (MockRepositoryImportException mrie) {
mrie.printStackTrace();
fail("No MockRepositoryImportException should have be thrown");
}
// Inspect Service own attributes.
importedSvc = services.get(0);
assertEquals("WeatherForecast API", importedSvc.getName());
assertEquals("1.1.0", importedSvc.getVersion());
assertEquals("weather-forecast-raw-openapi.yaml", importedSvc.getSourceArtifact());
assertNotNull(importedSvc.getMetadata());
assertEquals(1, importedSvc.getOperations().size());
assertEquals(DispatchStyles.URI_ELEMENTS, importedSvc.getOperations().get(0).getDispatcher());
assertEquals(5, importedSvc.getOperations().get(0).getResourcePaths().size());
// Inspect and check resources.
resources = resourceRepository.findByServiceId(importedSvc.getId());
assertEquals(1, resources.size());
resource = resources.get(0);
assertEquals("WeatherForecast API-1.1.0.yaml", resource.getName());
assertEquals("weather-forecast-raw-openapi.yaml", resource.getSourceArtifact());
// Inspect and check requests.
requests = requestRepository.findByOperationId(IdBuilder.buildOperationId(importedSvc, importedSvc.getOperations().get(0)));
assertEquals(5, requests.size());
for (Request request : requests) {
assertEquals("weather-forecast-postman.json", request.getSourceArtifact());
}
// Inspect and check responses.
responses = responseRepository.findByOperationId(IdBuilder.buildOperationId(importedSvc, importedSvc.getOperations().get(0)));
assertEquals(5, requests.size());
for (Response response : responses) {
assertEquals("weather-forecast-postman.json", response.getSourceArtifact());
}
}
use of io.github.microcks.domain.Resource in project microcks by microcks.
the class ProtobufImporterTest method testProtobufWithDependenciesImport.
@Test
public void testProtobufWithDependenciesImport() {
ProtobufImporter importer = null;
try {
importer = new ProtobufImporter("target/test-classes/io/github/microcks/util/grpc/goodbye-v1.proto", null);
} catch (IOException ioe) {
fail("Exception should not be thrown");
}
// Check that basic service properties are there.
List<Service> services = null;
try {
services = importer.getServiceDefinitions();
} catch (MockRepositoryImportException e) {
fail("Service definition import should not fail");
}
assertEquals(1, services.size());
Service service = services.get(0);
assertEquals("GoodbyeService", service.getName());
assertEquals(ServiceType.GRPC, service.getType());
assertEquals("v1", service.getVersion());
assertEquals("io.github.microcks.grpc.goodbye.v1", service.getXmlNS());
// Check that resources have been parsed, correctly renamed, etc...
List<Resource> resources = null;
try {
resources = importer.getResourceDefinitions(service);
} catch (MockRepositoryImportException mrie) {
fail("Resource definition import should not fail");
}
assertEquals(2, resources.size());
for (Resource resource : resources) {
assertNotNull(resource.getContent());
if (ResourceType.PROTOBUF_SCHEMA.equals(resource.getType())) {
assertEquals("GoodbyeService-v1.proto", resource.getName());
} else if (ResourceType.PROTOBUF_DESCRIPTOR.equals(resource.getType())) {
assertEquals("GoodbyeService-v1.pbb", resource.getName());
try {
// Check Protobuf Descriptor.
byte[] decodedBinaryPB = Base64.getDecoder().decode(resource.getContent().getBytes("UTF-8"));
DescriptorProtos.FileDescriptorSet fds = DescriptorProtos.FileDescriptorSet.parseFrom(decodedBinaryPB);
assertEquals(2, fds.getFileCount());
assertEquals("shared/uuid.proto", fds.getFile(0).getName());
assertEquals("goodbye-v1.proto", fds.getFile(1).getName());
} catch (Exception e) {
fail("Protobuf file descriptor is not correct");
}
} else {
fail("Resource has not the expected type");
}
}
}
use of io.github.microcks.domain.Resource in project microcks by microcks.
the class ProtobufImporterTest method testProtobufWithRemoteDependenciesImport.
@Test
public void testProtobufWithRemoteDependenciesImport() {
ProtobufImporter importer = null;
try {
importer = new ProtobufImporter("target/test-classes/io/github/microcks/util/grpc/remote/goodbye-v1.proto", new ReferenceResolver("https://raw.githubusercontent.com/microcks/microcks/1.5.x/webapp/src/test/resources/io/github/microcks/util/grpc/base.proto", null, true));
} catch (IOException ioe) {
fail("Exception should not be thrown");
}
// Check that basic service properties are there.
List<Service> services = null;
try {
services = importer.getServiceDefinitions();
} catch (MockRepositoryImportException e) {
fail("Service definition import should not fail");
}
assertEquals(1, services.size());
Service service = services.get(0);
assertEquals("GoodbyeService", service.getName());
assertEquals(ServiceType.GRPC, service.getType());
assertEquals("v1", service.getVersion());
assertEquals("io.github.microcks.grpc.goodbye.v1", service.getXmlNS());
// Check that resources have been parsed, correctly renamed, etc...
List<Resource> resources = null;
try {
resources = importer.getResourceDefinitions(service);
} catch (MockRepositoryImportException mrie) {
fail("Resource definition import should not fail");
}
assertEquals(3, resources.size());
for (Resource resource : resources) {
assertNotNull(resource.getContent());
if (ResourceType.PROTOBUF_SCHEMA.equals(resource.getType())) {
assertTrue("GoodbyeService-v1.proto".equals(resource.getName()) || "GoodbyeService-v1-shared~1uuid.proto".equals(resource.getName()));
} else if (ResourceType.PROTOBUF_DESCRIPTOR.equals(resource.getType())) {
assertEquals("GoodbyeService-v1.pbb", resource.getName());
System.err.println("base64: " + resource.getContent());
try {
// Check Protobuf Descriptor.
byte[] decodedBinaryPB = Base64.getDecoder().decode(resource.getContent().getBytes("UTF-8"));
DescriptorProtos.FileDescriptorSet fds = DescriptorProtos.FileDescriptorSet.parseFrom(decodedBinaryPB);
assertEquals(2, fds.getFileCount());
assertEquals("shared/uuid.proto", fds.getFile(0).getName());
assertEquals("goodbye-v1.proto", fds.getFile(1).getName());
} catch (Exception e) {
fail("Protobuf file descriptor is not correct");
}
} else {
fail("Resource has not the expected type");
}
}
}
use of io.github.microcks.domain.Resource in project microcks by microcks.
the class ProtobufImporterTest method testSimpleProtobufImport.
@Test
public void testSimpleProtobufImport() {
ProtobufImporter importer = null;
try {
importer = new ProtobufImporter("target/test-classes/io/github/microcks/util/grpc/hello-v1.proto", null);
} catch (IOException ioe) {
fail("Exception should not be thrown");
}
// Check that basic service properties are there.
List<Service> services = null;
try {
services = importer.getServiceDefinitions();
} catch (MockRepositoryImportException e) {
fail("Service definition import should not fail");
}
assertEquals(1, services.size());
Service service = services.get(0);
assertEquals("HelloService", service.getName());
assertEquals(ServiceType.GRPC, service.getType());
assertEquals("v1", service.getVersion());
assertEquals("io.github.microcks.grpc.hello.v1", service.getXmlNS());
// Check that resources have been parsed, correctly renamed, etc...
List<Resource> resources = null;
try {
resources = importer.getResourceDefinitions(service);
} catch (MockRepositoryImportException mrie) {
fail("Resource definition import should not fail");
}
assertEquals(2, resources.size());
for (Resource resource : resources) {
assertNotNull(resource.getContent());
if (ResourceType.PROTOBUF_SCHEMA.equals(resource.getType())) {
assertEquals("HelloService-v1.proto", resource.getName());
} else if (ResourceType.PROTOBUF_DESCRIPTOR.equals(resource.getType())) {
assertEquals("HelloService-v1.pbb", resource.getName());
} else {
fail("Resource has not the expected type");
}
}
// Check that operations and input/output have been found.
assertEquals(1, service.getOperations().size());
Operation operation = service.getOperations().get(0);
assertEquals("greeting", operation.getName());
assertEquals(".io.github.microcks.grpc.hello.v1.HelloRequest", operation.getInputName());
assertEquals(".io.github.microcks.grpc.hello.v1.HelloResponse", operation.getOutputName());
}
use of io.github.microcks.domain.Resource in project microcks by microcks.
the class ServiceService method importServiceDefinition.
/**
* Import definitions of services and bounded resources and messages into Microcks
* repository. This uses a MockRepositoryImporter under hood.
* @param repositoryFile The File for mock repository.
* @param referenceResolver The Resolver to be used during import (may be null).
* @param artifactInfo The essential information on Artifact to import.
* @return The list of imported Services
* @throws MockRepositoryImportException if something goes wrong (URL not reachable nor readable, etc...)
*/
public List<Service> importServiceDefinition(File repositoryFile, ReferenceResolver referenceResolver, ArtifactInfo artifactInfo) throws MockRepositoryImportException {
// Retrieve the correct importer based on file path.
MockRepositoryImporter importer = null;
try {
importer = MockRepositoryImporterFactory.getMockRepositoryImporter(repositoryFile, referenceResolver);
} catch (IOException ioe) {
log.error("Exception while accessing file " + repositoryFile.getPath(), ioe);
throw new MockRepositoryImportException(ioe.getMessage(), ioe);
}
Service reference = null;
boolean serviceUpdate = false;
List<Service> services = importer.getServiceDefinitions();
for (Service service : services) {
Service existingService = serviceRepository.findByNameAndVersion(service.getName(), service.getVersion());
log.debug("Service [{}, {}] exists ? {}", service.getName(), service.getVersion(), existingService != null);
// If it's the main artifact: retrieve previous id and props if update, save anyway.
if (artifactInfo.isMainArtifact()) {
if (existingService != null) {
// Retrieve its previous identifier and metadatas
// (backup metadata that may have been imported with extensions).
Metadata backup = service.getMetadata();
service.setId(existingService.getId());
service.setMetadata(existingService.getMetadata());
// If there was metadata found through extensions, overwrite historical ones.
if (backup != null) {
existingService.getMetadata().setLabels(backup.getLabels());
existingService.getMetadata().setAnnotations(backup.getAnnotations());
}
// Keep its overriden operation properties.
copyOverridenOperations(existingService, service);
serviceUpdate = true;
}
if (service.getMetadata() == null) {
service.setMetadata(new Metadata());
}
// For services of type EVENT, we should put default values on frequency and bindings.
if (service.getType().equals(ServiceType.EVENT)) {
manageEventServiceDefaults(service);
}
service.getMetadata().objectUpdated();
service.setSourceArtifact(artifactInfo.getArtifactName());
service = serviceRepository.save(service);
// We're dealing with main artifact so reference is saved or updated one.
reference = service;
} else {
// It's a secondary artifact just for messages or metadata. We'll have problems if not having an existing service...
if (existingService == null) {
log.warn("Trying to import {} as a secondary artifact but there's no existing [{}, {}] Service. Just skipping.", artifactInfo.getArtifactName(), service.getName(), service.getVersion());
break;
}
// update the existing service with them.
if (service.getMetadata() != null) {
existingService.getMetadata().setLabels(service.getMetadata().getLabels());
existingService.getMetadata().setAnnotations(service.getMetadata().getAnnotations());
}
for (Operation operation : service.getOperations()) {
Operation existingOp = existingService.getOperations().stream().filter(op -> op.getName().equals(operation.getName())).findFirst().orElse(null);
if (existingOp != null) {
if (operation.getDefaultDelay() != null) {
existingOp.setDefaultDelay(operation.getDefaultDelay());
}
if (operation.getDispatcher() != null) {
existingOp.setDispatcher(operation.getDispatcher());
}
if (operation.getDispatcherRules() != null) {
existingOp.setDispatcherRules(operation.getDispatcherRules());
}
}
}
// We're dealing with secondary artifact so reference is the pre-existing one.
// Moreover, we should replace current imported service (unbound/unsaved)
// by reference in the results list.
reference = existingService;
services.remove(service);
services.add(reference);
}
// Remove resources previously attached to service.
List<Resource> existingResources = resourceRepository.findByServiceIdAndSourceArtifact(reference.getId(), artifactInfo.getArtifactName());
if (existingResources != null && existingResources.size() > 0) {
resourceRepository.deleteAll(existingResources);
}
// Save new resources.
List<Resource> resources = importer.getResourceDefinitions(service);
for (Resource resource : resources) {
resource.setServiceId(reference.getId());
resource.setSourceArtifact(artifactInfo.getArtifactName());
}
resourceRepository.saveAll(resources);
for (Operation operation : reference.getOperations()) {
String operationId = IdBuilder.buildOperationId(reference, operation);
// Remove messages previously attached to service.
requestRepository.deleteAll(requestRepository.findByOperationIdAndSourceArtifact(operationId, artifactInfo.getArtifactName()));
responseRepository.deleteAll(responseRepository.findByOperationIdAndSourceArtifact(operationId, artifactInfo.getArtifactName()));
eventMessageRepository.deleteAll(eventMessageRepository.findByOperationIdAndSourceArtifact(operationId, artifactInfo.getArtifactName()));
List<Exchange> exchanges = importer.getMessageDefinitions(service, operation);
for (Exchange exchange : exchanges) {
if (exchange instanceof RequestResponsePair) {
RequestResponsePair pair = (RequestResponsePair) exchange;
// Associate request and response with operation and artifact.
pair.getRequest().setOperationId(operationId);
pair.getResponse().setOperationId(operationId);
pair.getRequest().setSourceArtifact(artifactInfo.getArtifactName());
pair.getResponse().setSourceArtifact(artifactInfo.getArtifactName());
// Save response and associate request with response before saving it.
responseRepository.save(pair.getResponse());
pair.getRequest().setResponseId(pair.getResponse().getId());
requestRepository.save(pair.getRequest());
} else if (exchange instanceof UnidirectionalEvent) {
UnidirectionalEvent event = (UnidirectionalEvent) exchange;
// Associate event message with operation and artifact before saving it..
event.getEventMessage().setOperationId(operationId);
event.getEventMessage().setSourceArtifact(artifactInfo.getArtifactName());
eventMessageRepository.save(event.getEventMessage());
}
}
}
// When extracting message information, we may have modified Operation because discovered new resource paths
// depending on variable URI parts. As a consequence, we got to update Service in repository.
serviceRepository.save(reference);
// Publish a Service update event before returning.
publishServiceChangeEvent(reference, serviceUpdate ? ChangeType.UPDATED : ChangeType.CREATED);
}
log.info("Having imported {} services definitions into repository", services.size());
return services;
}
Aggregations