use of io.github.microcks.domain.Operation 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());
}
use of io.github.microcks.domain.Operation in project microcks by microcks.
the class PostmanCollectionImporter method extractOperationV2.
private void extractOperationV2(String folderName, JsonNode itemNode, Map<String, Operation> collectedOperations) {
log.debug("Extracting operation in folder " + folderName);
String itemNodeName = itemNode.path("name").asText();
// Item may be a folder or an operation description.
if (!itemNode.has("request")) {
// Item is simply a folder that may contain some other folders recursively.
Iterator<JsonNode> items = itemNode.path("item").elements();
while (items.hasNext()) {
JsonNode item = items.next();
extractOperationV2(folderName + "/" + itemNodeName, item, collectedOperations);
}
} else {
// Item is here an operation description.
String operationName = buildOperationName(itemNode, folderName);
Operation operation = collectedOperations.get(operationName);
String url = itemNode.path("request").path("url").asText("");
if ("".equals(url)) {
url = itemNode.path("request").path("url").path("raw").asText("");
}
// Ex: http://localhost:8080/prefix1/prefix2/order/123456 or http://petstore.swagger.io/v2/pet/1. Trim it.
if (url.indexOf(folderName + "/") != -1) {
url = removeProtocolAndHostPort(url);
}
if (operation == null) {
// Build a new operation.
operation = new Operation();
operation.setName(operationName);
// Complete with REST specific fields.
operation.setMethod(itemNode.path("request").path("method").asText());
// Deal with dispatcher stuffs.
if (urlHasParameters(url) && urlHasParts(url)) {
operation.setDispatcherRules(DispatchCriteriaHelper.extractPartsFromURIPattern(url) + " ?? " + DispatchCriteriaHelper.extractParamsFromURI(url));
operation.setDispatcher(DispatchStyles.URI_ELEMENTS);
} else if (urlHasParameters(url)) {
operation.setDispatcherRules(DispatchCriteriaHelper.extractParamsFromURI(url));
operation.setDispatcher(DispatchStyles.URI_PARAMS);
operation.addResourcePath(extractResourcePath(url, null));
} else if (urlHasParts(url)) {
operation.setDispatcherRules(DispatchCriteriaHelper.extractPartsFromURIPattern(url));
operation.setDispatcher(DispatchStyles.URI_PARTS);
} else {
operation.addResourcePath(extractResourcePath(url, null));
}
}
// Do not deal with resource path now as it will be done when extracting messages.
collectedOperations.put(operationName, operation);
}
}
use of io.github.microcks.domain.Operation in project microcks by microcks.
the class TestRunnerService method launchTestsInternal.
/**
* Launch tests using asynchronous/completable future pattern.
* @param testResult TestResults to aggregate results within
* @param service Service to test
* @param runnerType Type of runner for launching the tests
* @return A Future wrapping test results
*/
@Async
public CompletableFuture<TestResult> launchTestsInternal(TestResult testResult, Service service, TestRunnerType runnerType) {
// Found next build number for this test.
List<TestResult> older = testResultRepository.findByServiceId(service.getId(), PageRequest.of(0, 2, Sort.Direction.DESC, "testNumber"));
if (older != null && !older.isEmpty() && older.get(0).getTestNumber() != null) {
testResult.setTestNumber(older.get(0).getTestNumber() + 1L);
} else {
testResult.setTestNumber(1L);
}
Secret secret = null;
if (testResult.getSecretRef() != null) {
secret = secretRepository.findById(testResult.getSecretRef().getSecretId()).orElse(null);
log.debug("Using a secret to test endpoint? '{}'", secret != null ? secret.getName() : "none");
}
// Initialize runner once as it is shared for each test.
AbstractTestRunner<HttpMethod> testRunner = retrieveRunner(runnerType, secret, testResult.getTimeout(), service.getId());
if (testRunner == null) {
// Set failure and stopped flags and save before exiting.
testResult.setSuccess(false);
testResult.setInProgress(false);
testResult.setElapsedTime(0);
testResultRepository.save(testResult);
return CompletableFuture.completedFuture(testResult);
}
for (TestCaseResult testCaseResult : testResult.getTestCaseResults()) {
// Retrieve operation corresponding to testCase.
Operation operation = service.getOperations().stream().filter(o -> o.getName().equals(testCaseResult.getOperationName())).findFirst().get();
String testCaseId = IdBuilder.buildTestCaseId(testResult, operation);
// Prepare collection of requests to launch.
List<Request> requests = requestRepository.findByOperationId(IdBuilder.buildOperationId(service, operation));
requests = cloneRequestsForTestCase(requests, testCaseId);
List<TestReturn> results = new ArrayList<>();
try {
HttpMethod method = testRunner.buildMethod(operation.getMethod());
results = testRunner.runTest(service, operation, testResult, requests, testResult.getTestedEndpoint(), method);
} catch (URISyntaxException use) {
log.error("URISyntaxException on endpoint {}, aborting current tests", testResult.getTestedEndpoint(), use);
// Set flags and add to results before exiting loop.
testCaseResult.setSuccess(false);
testCaseResult.setElapsedTime(0);
testResultRepository.save(testResult);
break;
} catch (Throwable t) {
log.error("Throwable while testing operation {}", operation.getName(), t);
}
// sample request for that operation -> mark it as failed.
if (results == null) {
testCaseResult.setSuccess(false);
testCaseResult.setElapsedTime(0);
testResultRepository.save(testResult);
} else if (!results.isEmpty()) {
updateTestCaseResultWithReturns(testCaseResult, results, testCaseId);
testResultRepository.save(testResult);
}
}
// Update success, progress indicators and total time before saving and returning.
updateTestResult(testResult);
return CompletableFuture.completedFuture(testResult);
}
use of io.github.microcks.domain.Operation in project microcks by microcks.
the class AsyncAPIImporter method extractOperations.
/**
* Extract the list of operations from Specification.
*/
private List<Operation> extractOperations() throws MockRepositoryImportException {
List<Operation> results = new ArrayList<>();
// Iterate on specification "channels" nodes.
Iterator<Entry<String, JsonNode>> channels = spec.path("channels").fields();
while (channels.hasNext()) {
Entry<String, JsonNode> channel = channels.next();
String channelName = channel.getKey();
// Iterate on specification path, "verbs" nodes.
Iterator<Entry<String, JsonNode>> verbs = channel.getValue().fields();
while (verbs.hasNext()) {
Entry<String, JsonNode> verb = verbs.next();
String verbName = verb.getKey();
// Only deal with real verbs for now.
if (VALID_VERBS.contains(verbName)) {
String operationName = verbName.toUpperCase() + " " + channelName.trim();
Operation operation = new Operation();
operation.setName(operationName);
operation.setMethod(verbName.toUpperCase());
// Complete operation properties if any.
if (verb.getValue().has(MetadataExtensions.MICROCKS_OPERATION_EXTENSION)) {
MetadataExtractor.completeOperationProperties(operation, verb.getValue().path(MetadataExtensions.MICROCKS_OPERATION_EXTENSION));
}
// Deal with dispatcher stuffs.
if (operation.getDispatcher() == null && channelHasParts(channelName)) {
operation.setDispatcher(DispatchStyles.URI_PARTS);
operation.setDispatcherRules(DispatchCriteriaHelper.extractPartsFromURIPattern(channelName));
} else {
operation.addResourcePath(channelName);
}
// We have to look also for bindings. First at the upper channel level.
if (channel.getValue().has("bindings")) {
Iterator<String> bindingNames = channel.getValue().path("bindings").fieldNames();
while (bindingNames.hasNext()) {
String bindingName = bindingNames.next();
JsonNode binding = channel.getValue().path("bindings").path(bindingName);
switch(bindingName) {
case "ws":
Binding b = retrieveOrInitOperationBinding(operation, BindingType.WS);
if (binding.has("method")) {
b.setMethod(binding.path("method").asText());
}
break;
case "amqp":
b = retrieveOrInitOperationBinding(operation, BindingType.AMQP);
if (binding.has("is")) {
String is = binding.path("is").asText();
if ("queue".equals(is)) {
b.setDestinationType("queue");
JsonNode queue = binding.get("queue");
b.setDestinationName(queue.get("name").asText());
} else if ("routingKey".equals(is)) {
JsonNode exchange = binding.get("exchange");
b.setDestinationType(exchange.get("type").asText());
}
}
break;
}
}
}
// Then look for bindings at the operation level.
if (verb.getValue().has("bindings")) {
Iterator<String> bindingNames = verb.getValue().path("bindings").fieldNames();
while (bindingNames.hasNext()) {
String bindingName = bindingNames.next();
JsonNode binding = verb.getValue().path("bindings").path(bindingName);
switch(bindingName) {
case "kafka":
break;
case "mqtt":
Binding b = retrieveOrInitOperationBinding(operation, BindingType.MQTT);
if (binding.has("qos")) {
b.setQoS(binding.path("qos").asText());
}
if (binding.has("retain")) {
b.setPersistent(binding.path("retain").asBoolean());
}
break;
case "amqp1":
b = retrieveOrInitOperationBinding(operation, BindingType.AMQP1);
if (binding.has("destinationName")) {
b.setDestinationName(binding.path("destinationName").asText());
}
if (binding.has("destinationType")) {
b.setDestinationType(binding.path("destinationType").asText());
}
break;
}
}
}
// Then look for bindings at the message level.
JsonNode messageBody = verb.getValue().path("message");
messageBody = followRefIfAny(messageBody);
if (messageBody.has("bindings")) {
Iterator<String> bindingNames = messageBody.path("bindings").fieldNames();
while (bindingNames.hasNext()) {
String bindingName = bindingNames.next();
JsonNode binding = messageBody.path("bindings").path(bindingName);
switch(bindingName) {
case "kafka":
Binding b = retrieveOrInitOperationBinding(operation, BindingType.KAFKA);
if (binding.has("key")) {
b.setKeyType(binding.path("key").path("type").asText());
}
break;
case "mqtt":
case "amqp1":
break;
}
}
}
results.add(operation);
}
}
}
return results;
}
use of io.github.microcks.domain.Operation in project microcks by microcks.
the class GraphQLImporter method extractOperations.
/**
* Extract the operations from GraphQL schema document.
*/
private List<Operation> extractOperations() {
List<Operation> results = new ArrayList<>();
for (Definition definition : graphqlSchema.getDefinitions()) {
if (definition instanceof ObjectTypeDefinition) {
ObjectTypeDefinition typeDefinition = (ObjectTypeDefinition) definition;
if (VALID_OPERATION_TYPES.contains(typeDefinition.getName().toLowerCase())) {
List<Operation> operations = extractOperations(typeDefinition);
results.addAll(operations);
}
}
}
return results;
}
Aggregations