use of io.github.microcks.domain.Service in project microcks by microcks.
the class UploadArtifactController method importArtifact.
@RequestMapping(value = "/artifact/upload", method = RequestMethod.POST)
public ResponseEntity<?> importArtifact(@RequestParam(value = "file") MultipartFile file, @RequestParam(value = "mainArtifact", defaultValue = "true") boolean mainArtifact) {
if (!file.isEmpty()) {
log.debug("Content type of " + file.getOriginalFilename() + " is " + file.getContentType());
List<Service> services = null;
try {
// Save upload to local file before import.
String localFile = System.getProperty("java.io.tmpdir") + "/microcks-" + System.currentTimeMillis() + ".artifact";
ReadableByteChannel rbc = null;
FileOutputStream fos = null;
try {
rbc = Channels.newChannel(file.getInputStream());
// Transfer file to local.
fos = new FileOutputStream(localFile);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
} finally {
if (fos != null)
fos.close();
if (rbc != null)
rbc.close();
}
// Now try importing services.
services = serviceService.importServiceDefinition(new File(localFile), null, new ArtifactInfo(file.getOriginalFilename(), mainArtifact));
} catch (IOException ioe) {
log.error("Exception while writing uploaded item " + file.getOriginalFilename(), ioe);
return new ResponseEntity<Object>("Exception while writing uploaded item", HttpStatus.INTERNAL_SERVER_ERROR);
} catch (MockRepositoryImportException mrie) {
return new ResponseEntity<Object>(mrie.getMessage(), HttpStatus.BAD_REQUEST);
}
if (services != null && services.size() > 0) {
return new ResponseEntity<Object>(services.get(0).getName() + ":" + services.get(0).getVersion(), HttpStatus.CREATED);
}
}
return new ResponseEntity<Object>(HttpStatus.NO_CONTENT);
}
use of io.github.microcks.domain.Service in project microcks by microcks.
the class GraphQLImporterTest method testSimpleGraphQLImport.
@Test
public void testSimpleGraphQLImport() {
GraphQLImporter importer = null;
try {
importer = new GraphQLImporter("target/test-classes/io/github/microcks/util/graphql/films.graphql");
} 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("Movie Graph API", service.getName());
assertEquals(ServiceType.GRAPHQL, service.getType());
assertEquals("1.0", service.getVersion());
// 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(1, resources.size());
Resource resource = resources.get(0);
assertEquals(ResourceType.GRAPHQL_SCHEMA, resource.getType());
assertEquals("Movie Graph API-1.0.graphql", resource.getName());
// Check that operations and input/output have been found.
assertEquals(4, service.getOperations().size());
for (Operation operation : service.getOperations()) {
if ("allFilms".equals(operation.getName())) {
assertEquals("QUERY", operation.getMethod());
assertEquals("FilmsConnection", operation.getOutputName());
assertNull(operation.getDispatcher());
} else if ("film".equals(operation.getName())) {
assertEquals("QUERY", operation.getMethod());
assertEquals("Film", operation.getOutputName());
assertEquals("String", operation.getInputName());
assertEquals(DispatchStyles.QUERY_ARGS, operation.getDispatcher());
assertEquals("id", operation.getDispatcherRules());
} else if ("addStar".equals(operation.getName())) {
assertEquals("MUTATION", operation.getMethod());
assertEquals("Film", operation.getOutputName());
assertEquals("String", operation.getInputName());
assertEquals(DispatchStyles.QUERY_ARGS, operation.getDispatcher());
assertEquals("filmId", operation.getDispatcherRules());
} else if ("addReview".equals(operation.getName())) {
assertEquals("MUTATION", operation.getMethod());
assertEquals("Film", operation.getOutputName());
assertEquals("String, Review", operation.getInputName());
assertNull(operation.getDispatcher());
} else {
fail("Unknown operation");
}
}
}
use of io.github.microcks.domain.Service in project microcks by microcks.
the class AsyncMinionApp method onStart.
/**
* Application startup method.
*/
void onStart(@Observes StartupEvent ev) {
// We need to retrieve Keycloak server from Microcks config.
KeycloakConfig config = microcksAPIConnector.getKeycloakConfig();
logger.infof("Microcks Keycloak server url {%s} and realm {%s}", config.getAuthServerUrl(), config.getRealm());
String keycloakEndpoint = config.getAuthServerUrl() + "/realms/" + config.getRealm() + "/protocol/openid-connect/token";
if (!keycloakAuthURL.isEmpty() && keycloakAuthURL.get().length() > 0) {
logger.infof("Use locally defined Keycloak Auth URL: %s", keycloakAuthURL);
keycloakEndpoint = keycloakAuthURL.get() + "/realms/" + config.getRealm() + "/protocol/openid-connect/token";
}
try {
// First retrieve an authentication token before fetching async messages to publish.
String oauthToken;
if (config.isEnabled()) {
// We've got a full Keycloak config, attempt an authent.
oauthToken = keycloakConnector.connectAndGetOAuthToken(keycloakEndpoint);
logger.info("Authentication to Keycloak server succeed!");
} else {
// No realm config, probably a dev mode - use a fake token.
oauthToken = "<anonymous-admin-token>";
logger.info("Keycloak protection is not enabled, using a fake token");
}
int page = 0;
boolean fetchServices = true;
while (fetchServices) {
List<Service> services = microcksAPIConnector.listServices("Bearer " + oauthToken, page, SERVICES_FETCH_SIZE);
for (Service service : services) {
logger.debug("Found service " + service.getName() + " - " + service.getVersion());
if (service.getType().equals(ServiceType.EVENT)) {
// Find the operations matching this minion constraints..
List<Operation> operations = service.getOperations().stream().filter(o -> Arrays.asList(restrictedFrequencies).contains(o.getDefaultDelay())).filter(o -> o.getBindings().keySet().stream().anyMatch(Arrays.asList(supportedBindings)::contains)).collect(Collectors.toList());
if (operations.size() > 0) {
logger.info("Found " + operations.size() + " candidate operations in " + service.getName() + " - " + service.getVersion());
ServiceView serviceView = microcksAPIConnector.getService("Bearer " + oauthToken, service.getId(), true);
for (Operation operation : operations) {
AsyncMockDefinition mockDefinition = new AsyncMockDefinition(serviceView.getService(), operation, serviceView.getMessagesMap().get(operation.getName()).stream().filter(e -> e instanceof UnidirectionalEvent).map(e -> ((UnidirectionalEvent) e).getEventMessage()).collect(Collectors.toList()));
mockRepository.storeMockDefinition(mockDefinition);
schemaRegistry.updateRegistryForService(mockDefinition.getOwnerService());
}
}
}
}
if (services.size() < SERVICES_FETCH_SIZE) {
fetchServices = false;
}
page++;
}
logger.info("Starting scheduling of all producer jobs...");
producerScheduler.scheduleAllProducerJobs();
} catch (ConnectorException ce) {
logger.error("Cannot authenticate to Keycloak server and thus enable to call Microcks API" + "to get Async APIs to mocks...", ce);
throw new RuntimeException("Unable to start the Minion due to connection exception");
} catch (IOException ioe) {
logger.error("IOException while communicating with Keycloak or Microcks API", ioe);
throw new RuntimeException("Unable to start the Minion due to IO exception");
}
}
use of io.github.microcks.domain.Service in project microcks by microcks.
the class ServiceChangeEventPublisher method onApplicationEvent.
@Override
@Async
public void onApplicationEvent(ServiceChangeEvent event) {
log.debug("Received a ServiceChangeEvent on " + event.getServiceId());
ServiceView serviceView = null;
if (event.getChangeType() != ChangeType.DELETED) {
Service service = serviceRepository.findById(event.getServiceId()).orElse(null);
if (service != null) {
// Put messages into a map where key is operation name.
Map<String, List<? extends Exchange>> messagesMap = new HashMap<>();
for (Operation operation : service.getOperations()) {
if (service.getType() == ServiceType.EVENT) {
// If an event, we should explicitly retrieve event messages.
List<UnidirectionalEvent> events = messageService.getEventByOperation(IdBuilder.buildOperationId(service, operation));
messagesMap.put(operation.getName(), events);
} else {
// Otherwise we have traditional request / response pairs.
List<RequestResponsePair> pairs = messageService.getRequestResponseByOperation(IdBuilder.buildOperationId(service, operation));
messagesMap.put(operation.getName(), pairs);
}
}
serviceView = new ServiceView(service, messagesMap);
}
}
// Build and send a ServiceViewChangeEvent that wraps ServiceView.
ServiceViewChangeEvent serviceViewChangeEvent = new ServiceViewChangeEvent(event.getServiceId(), serviceView, event.getChangeType(), System.currentTimeMillis());
kafkaTemplate.send("microcks-services-updates", event.getServiceId(), serviceViewChangeEvent);
log.debug("Processing of ServiceChangeEvent done !");
}
use of io.github.microcks.domain.Service in project microcks by microcks.
the class PostmanCollectionImporter method getMessageDefinitionsV2.
private List<Exchange> getMessageDefinitionsV2(Service service, Operation operation) {
Map<Request, Response> result = new HashMap<Request, Response>();
Iterator<JsonNode> items = collection.path("item").elements();
while (items.hasNext()) {
JsonNode item = items.next();
result.putAll(getMessageDefinitionsV2("", item, operation));
}
// Adapt map to list of Exchanges.
return result.entrySet().stream().map(entry -> new RequestResponsePair(entry.getKey(), entry.getValue())).collect(Collectors.toList());
}
Aggregations