Search in sources :

Example 6 with Operation

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());
}
Also used : Response(io.github.microcks.domain.Response) java.util(java.util) JsonGenerator(com.fasterxml.jackson.core.JsonGenerator) LoggerFactory(org.slf4j.LoggerFactory) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) DispatchCriteriaHelper(io.github.microcks.util.DispatchCriteriaHelper) TypeFactory(com.fasterxml.jackson.databind.type.TypeFactory) Exchange(io.github.microcks.domain.Exchange) MockRepositoryImporter(io.github.microcks.util.MockRepositoryImporter) JsonNode(com.fasterxml.jackson.databind.JsonNode) Resource(io.github.microcks.domain.Resource) Parameter(io.github.microcks.domain.Parameter) Response(io.github.microcks.domain.Response) DispatchStyles(io.github.microcks.util.DispatchStyles) MockRepositoryImportException(io.github.microcks.util.MockRepositoryImportException) Request(io.github.microcks.domain.Request) URIBuilder(io.github.microcks.util.URIBuilder) Logger(org.slf4j.Logger) PatternSyntaxException(java.util.regex.PatternSyntaxException) Files(java.nio.file.Files) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) Service(io.github.microcks.domain.Service) Header(io.github.microcks.domain.Header) Operation(io.github.microcks.domain.Operation) ServiceType(io.github.microcks.domain.ServiceType) Paths(java.nio.file.Paths) JsonWriteFeature(com.fasterxml.jackson.core.json.JsonWriteFeature) RequestResponsePair(io.github.microcks.domain.RequestResponsePair) RequestResponsePair(io.github.microcks.domain.RequestResponsePair) Request(io.github.microcks.domain.Request) JsonNode(com.fasterxml.jackson.databind.JsonNode)

Example 7 with Operation

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);
    }
}
Also used : JsonNode(com.fasterxml.jackson.databind.JsonNode) Operation(io.github.microcks.domain.Operation)

Example 8 with 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);
}
Also used : TestCaseResult(io.github.microcks.domain.TestCaseResult) TestReturn(io.github.microcks.domain.TestReturn) PageRequest(org.springframework.data.domain.PageRequest) Request(io.github.microcks.domain.Request) ArrayList(java.util.ArrayList) TestResult(io.github.microcks.domain.TestResult) Operation(io.github.microcks.domain.Operation) URISyntaxException(java.net.URISyntaxException) Secret(io.github.microcks.domain.Secret) HttpMethod(org.springframework.http.HttpMethod) Async(org.springframework.scheduling.annotation.Async)

Example 9 with Operation

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;
}
Also used : Binding(io.github.microcks.domain.Binding) Entry(java.util.Map.Entry) ArrayList(java.util.ArrayList) JsonNode(com.fasterxml.jackson.databind.JsonNode) Operation(io.github.microcks.domain.Operation)

Example 10 with Operation

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;
}
Also used : ObjectTypeDefinition(graphql.language.ObjectTypeDefinition) ArrayList(java.util.ArrayList) InputValueDefinition(graphql.language.InputValueDefinition) Definition(graphql.language.Definition) ObjectTypeDefinition(graphql.language.ObjectTypeDefinition) FieldDefinition(graphql.language.FieldDefinition) Operation(io.github.microcks.domain.Operation)

Aggregations

Operation (io.github.microcks.domain.Operation)26 Service (io.github.microcks.domain.Service)14 JsonNode (com.fasterxml.jackson.databind.JsonNode)7 IOException (java.io.IOException)7 ArrayList (java.util.ArrayList)7 MockRepositoryImportException (io.github.microcks.util.MockRepositoryImportException)6 Resource (io.github.microcks.domain.Resource)5 UnidirectionalEvent (io.github.microcks.domain.UnidirectionalEvent)5 Exchange (io.github.microcks.domain.Exchange)4 RequestResponsePair (io.github.microcks.domain.RequestResponsePair)4 Response (io.github.microcks.domain.Response)4 ServiceType (io.github.microcks.domain.ServiceType)4 Test (org.junit.Test)4 Header (io.github.microcks.domain.Header)3 ServiceView (io.github.microcks.domain.ServiceView)3 List (java.util.List)3 Collectors (java.util.stream.Collectors)3 FieldDefinition (graphql.language.FieldDefinition)2 InputValueDefinition (graphql.language.InputValueDefinition)2 Metadata (io.github.microcks.domain.Metadata)2