use of io.github.microcks.util.MockRepositoryImportException 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;
}
use of io.github.microcks.util.MockRepositoryImportException 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 underhood.
* @param repositoryUrl The String representing mock repository url.
* @param repositorySecret The authentication secret associated with the repository url. Can be set to null if none.
* @param disableSSLValidation Whether SSL certificates validation should be turned off.
* @param mainArtifact Whether this repository should be considered as main artifact for Services to import.
* @return The list of imported Services
* @throws MockRepositoryImportException if something goes wrong (URL not reachable nor readable, etc...)
*/
public List<Service> importServiceDefinition(String repositoryUrl, Secret repositorySecret, boolean disableSSLValidation, boolean mainArtifact) throws MockRepositoryImportException {
log.info("Importing service definitions from " + repositoryUrl);
File localFile = null;
Map<String, List<String>> fileProperties = null;
if (repositoryUrl.startsWith("http")) {
try {
HTTPDownloader.FileAndHeaders fileAndHeaders = HTTPDownloader.handleHTTPDownloadToFileAndHeaders(repositoryUrl, repositorySecret, disableSSLValidation);
localFile = fileAndHeaders.getLocalFile();
fileProperties = fileAndHeaders.getResponseHeaders();
} catch (IOException ioe) {
log.error("Exception while downloading " + repositoryUrl, ioe);
throw new MockRepositoryImportException(repositoryUrl + " cannot be downloaded", ioe);
}
} else {
// Simply build localFile from repository url.
localFile = new File(repositoryUrl);
}
RelativeReferenceURLBuilder referenceURLBuilder = RelativeReferenceURLBuilderFactory.getRelativeReferenceURLBuilder(fileProperties);
String artifactName = referenceURLBuilder.getFileName(repositoryUrl, fileProperties);
// Initialize a reference resolver to the folder of this repositoryUrl.
ReferenceResolver referenceResolver = new ReferenceResolver(repositoryUrl, repositorySecret, disableSSLValidation, referenceURLBuilder);
return importServiceDefinition(localFile, referenceResolver, new ArtifactInfo(artifactName, mainArtifact));
}
use of io.github.microcks.util.MockRepositoryImportException in project microcks by microcks.
the class ProtobufImporter method getResourceDefinitions.
@Override
public List<Resource> getResourceDefinitions(Service service) throws MockRepositoryImportException {
List<Resource> results = new ArrayList<>();
// Build 2 resources: one with plain text, another with base64 encoded binary descriptor.
Resource textResource = new Resource();
textResource.setName(service.getName() + "-" + service.getVersion() + ".proto");
textResource.setType(ResourceType.PROTOBUF_SCHEMA);
textResource.setContent(specContent);
results.add(textResource);
try {
byte[] binaryPB = Files.readAllBytes(Path.of(protoDirectory, protoFileName + BINARY_DESCRIPTOR_EXT));
String base64PB = new String(Base64.getEncoder().encode(binaryPB), "UTF-8");
Resource descResource = new Resource();
descResource.setName(service.getName() + "-" + service.getVersion() + BINARY_DESCRIPTOR_EXT);
descResource.setType(ResourceType.PROTOBUF_DESCRIPTOR);
descResource.setContent(base64PB);
results.add(descResource);
} catch (Exception e) {
log.error("Exception while encoding Protobuf binary descriptor into base64", e);
throw new MockRepositoryImportException("Exception while encoding Protobuf binary descriptor into base64");
}
// Now build resources for dependencies if any.
if (referenceResolver != null) {
referenceResolver.getResolvedReferences().forEach((p, f) -> {
Resource protoResource = new Resource();
protoResource.setName(service.getName() + "-" + service.getVersion() + "-" + p.replaceAll("/", "~1"));
protoResource.setType(ResourceType.PROTOBUF_SCHEMA);
protoResource.setPath(p);
try {
protoResource.setContent(Files.readString(f.toPath(), Charset.forName("UTF-8")));
} catch (IOException ioe) {
log.error("", ioe);
}
results.add(protoResource);
});
referenceResolver.cleanResolvedReferences();
}
return results;
}
Aggregations