Search in sources :

Example 16 with Resource

use of io.github.microcks.domain.Resource in project microcks by microcks.

the class AsyncAPIImporter method getResourceDefinitions.

@Override
public List<Resource> getResourceDefinitions(Service service) {
    List<Resource> results = new ArrayList<>();
    // Build a suitable name.
    String name = service.getName() + "-" + service.getVersion();
    if (isYaml) {
        name += ".yaml";
    } else {
        name += ".json";
    }
    // Build a brand new resource just with spec content.
    Resource resource = new Resource();
    resource.setName(name);
    resource.setType(ResourceType.ASYNC_API_SPEC);
    resource.setContent(specContent);
    results.add(resource);
    // references for external schemas only if we have a resolver available.
    if (referenceResolver != null) {
        for (Operation operation : service.getOperations()) {
            String[] operationElements = operation.getName().split(" ");
            String messageNamePtr = "/channels/" + operationElements[1].replaceAll("/", "~1");
            messageNamePtr += "/" + operationElements[0].toLowerCase() + "/message";
            JsonNode messageNode = spec.at(messageNamePtr);
            if (messageNode != null) {
                // If it's a $ref, then navigate to it.
                messageNode = followRefIfAny(messageNode);
                // Extract payload schema here.
                if (messageNode.has("payload")) {
                    JsonNode payloadNode = messageNode.path("payload");
                    // Check we have a reference that is not a local one.
                    if (payloadNode.has("$ref") && !payloadNode.path("$ref").asText().startsWith("#")) {
                        String ref = payloadNode.path("$ref").asText();
                        // to indicate exact Resource)
                        if (ref.contains("#")) {
                            ref = ref.substring(0, ref.indexOf("#"));
                        }
                        try {
                            // Extract content using resolver.
                            String content = referenceResolver.getHttpReferenceContent(ref, "UTF-8");
                            // Build a new resource from content. Use the escaped operation path.
                            Resource schemaResource = new Resource();
                            schemaResource.setName(IdBuilder.buildResourceFullName(service, operation));
                            schemaResource.setPath(ref);
                            schemaResource.setContent(content);
                            // We have to look at schema format to know the type.
                            // Default value is set at first.
                            String schemaFormat = "application/vnd.aai.asyncapi";
                            if (messageNode.has("schemaFormat")) {
                                schemaFormat = messageNode.path("schemaFormat").asText();
                            }
                            if (schemaFormat.startsWith("application/vnd.aai.asyncapi")) {
                                schemaResource.setType(ResourceType.ASYNC_API_SCHEMA);
                            } else if (schemaFormat.startsWith("application/vnd.oai.openapi")) {
                                schemaResource.setType(ResourceType.OPEN_API_SCHEMA);
                            } else if (schemaFormat.startsWith("application/schema+json") || schemaFormat.startsWith("application/schema+yaml")) {
                                schemaResource.setType(ResourceType.JSON_SCHEMA);
                            } else if (schemaFormat.startsWith("application/vnd.apache.avro")) {
                                schemaResource.setType(ResourceType.AVRO_SCHEMA);
                            }
                            results.add(schemaResource);
                        } catch (IOException ioe) {
                            log.error("IOException while trying to resolve reference " + ref, ioe);
                            log.info("Ignoring the reference {} cause it could not be resolved", ref);
                        }
                    }
                }
            }
        }
        // Finally try to clean up resolved references and associated resources (files)
        referenceResolver.cleanResolvedReferences();
    }
    return results;
}
Also used : Resource(io.github.microcks.domain.Resource) ArrayList(java.util.ArrayList) JsonNode(com.fasterxml.jackson.databind.JsonNode) Operation(io.github.microcks.domain.Operation) IOException(java.io.IOException)

Example 17 with Resource

use of io.github.microcks.domain.Resource in project microcks by microcks.

the class AsyncAPITestRunner method runTest.

@Override
public List<TestReturn> runTest(Service service, Operation operation, TestResult testResult, List<Request> requests, String endpointUrl, HttpMethod method) throws URISyntaxException, IOException {
    if (log.isDebugEnabled()) {
        log.debug("Launching test run on " + endpointUrl + " for ms");
    }
    // Retrieve the resource corresponding to OpenAPI specification if any.
    Resource asyncAPISpecResource = null;
    List<Resource> resources = resourceRepository.findByServiceId(service.getId());
    for (Resource resource : resources) {
        if (ResourceType.ASYNC_API_SPEC.equals(resource.getType())) {
            asyncAPISpecResource = resource;
            break;
        }
    }
    // Microcks-async-minion interface object building.
    ObjectNode jsonArg = mapper.createObjectNode();
    jsonArg.put("runnerType", TestRunnerType.ASYNC_API_SCHEMA.toString());
    jsonArg.put("testResultId", testResult.getId());
    jsonArg.put("serviceId", service.getId());
    jsonArg.put("operationName", operation.getName());
    jsonArg.put("endpointUrl", endpointUrl);
    jsonArg.put("timeoutMS", testResult.getTimeout());
    jsonArg.put("asyncAPISpec", asyncAPISpecResource.getContent());
    if (testResult.getSecretRef() != null) {
        Secret secret = secretRepository.findById(testResult.getSecretRef().getSecretId()).orElse(null);
        if (secret != null) {
            log.debug("Adding the secret '{}' to test specification request", secret.getName());
            jsonArg.set("secret", mapper.valueToTree(secret));
        }
    }
    URI asyncMinionURI = new URI(asyncMinionUrl + "/api/tests");
    ClientHttpRequest httpRequest = clientHttpRequestFactory.createRequest(asyncMinionURI, HttpMethod.POST);
    httpRequest.getBody().write(mapper.writeValueAsBytes(jsonArg));
    httpRequest.getHeaders().add("Content-Type", "application/json");
    // Actually execute request.
    ClientHttpResponse httpResponse = null;
    try {
        httpResponse = httpRequest.execute();
    } catch (IOException ioe) {
        log.error("IOException while executing request ", ioe);
    } finally {
        if (httpResponse != null) {
            httpResponse.close();
        }
    }
    return new ArrayList<>();
}
Also used : Secret(io.github.microcks.domain.Secret) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) Resource(io.github.microcks.domain.Resource) ArrayList(java.util.ArrayList) IOException(java.io.IOException) ClientHttpRequest(org.springframework.http.client.ClientHttpRequest) URI(java.net.URI) ClientHttpResponse(org.springframework.http.client.ClientHttpResponse)

Example 18 with Resource

use of io.github.microcks.domain.Resource 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;
}
Also used : Resource(io.github.microcks.domain.Resource) ArrayList(java.util.ArrayList) IOException(java.io.IOException) MockRepositoryImportException(io.github.microcks.util.MockRepositoryImportException) MockRepositoryImportException(io.github.microcks.util.MockRepositoryImportException) IOException(java.io.IOException) FileAlreadyExistsException(java.nio.file.FileAlreadyExistsException)

Example 19 with Resource

use of io.github.microcks.domain.Resource in project microcks by microcks.

the class GraphQLTestRunner method extractTestReturnCode.

@Override
protected int extractTestReturnCode(Service service, Operation operation, Request request, ClientHttpResponse httpResponse, String responseContent) {
    int code = TestReturn.SUCCESS_CODE;
    int responseCode = 0;
    try {
        responseCode = httpResponse.getRawStatusCode();
        log.debug("Response status code : " + responseCode);
    } catch (IOException ioe) {
        log.debug("IOException while getting raw status code in response", ioe);
        return TestReturn.FAILURE_CODE;
    }
    // Check that we're in the 20x family.
    if (!String.valueOf(responseCode).startsWith("20")) {
        log.debug("Response code if not in 20x range, assuming it's a failure");
        return TestReturn.FAILURE_CODE;
    }
    // Extract response content-type in any case.
    String contentType = null;
    if (httpResponse.getHeaders().getContentType() != null) {
        log.debug("Response media-type is {}", httpResponse.getHeaders().getContentType().toString());
        contentType = httpResponse.getHeaders().getContentType().toString();
        // Sanitize charset information from media-type.
        if (contentType.contains("charset=") && contentType.indexOf(";") > 0) {
            contentType = contentType.substring(0, contentType.indexOf(";"));
        }
    }
    // Also do not try to schema validate something that is not application/json for now...
    if (responseCode != 204 && APPLICATION_JSON_TYPE.equals(contentType)) {
        // Retrieve the resource corresponding to OpenAPI specification if any.
        Resource graphqlSchemaResource = null;
        List<Resource> resources = resourceRepository.findByServiceIdAndType(service.getId(), ResourceType.GRAPHQL_SCHEMA);
        if (!resources.isEmpty()) {
            graphqlSchemaResource = resources.get(0);
        }
        if (graphqlSchemaResource == null) {
            log.debug("Found no GraphQL specification resource for service {0}, so failing validating", service.getId());
            return TestReturn.FAILURE_CODE;
        }
        JsonNode responseSchema = null;
        try {
            responseSchema = GraphQLSchemaValidator.buildResponseJsonSchema(graphqlSchemaResource.getContent(), lastQueryContent);
            log.debug("responseSchema: " + responseSchema);
            lastValidationErrors = GraphQLSchemaValidator.validateJson(responseSchema, mapper.readTree(responseContent));
        } catch (IOException ioe) {
            log.debug("Response body cannot be accessed or transformed as Json, returning failure");
            return TestReturn.FAILURE_CODE;
        }
        if (!lastValidationErrors.isEmpty()) {
            log.debug("GraphQL schema validation errors found " + lastValidationErrors.size() + ", marking test as failed.");
            return TestReturn.FAILURE_CODE;
        }
        log.debug("GraphQL schema validation of response is successful !");
    }
    return code;
}
Also used : Resource(io.github.microcks.domain.Resource) JsonNode(com.fasterxml.jackson.databind.JsonNode) IOException(java.io.IOException)

Aggregations

Resource (io.github.microcks.domain.Resource)19 Service (io.github.microcks.domain.Service)11 IOException (java.io.IOException)11 MockRepositoryImportException (io.github.microcks.util.MockRepositoryImportException)8 Test (org.junit.Test)7 ArrayList (java.util.ArrayList)6 Operation (io.github.microcks.domain.Operation)5 JsonNode (com.fasterxml.jackson.databind.JsonNode)4 Response (io.github.microcks.domain.Response)4 Request (io.github.microcks.domain.Request)3 HttpHeaders (org.springframework.http.HttpHeaders)3 ResponseEntity (org.springframework.http.ResponseEntity)3 RequestMapping (org.springframework.web.bind.annotation.RequestMapping)3 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)2 File (java.io.File)2 ClassPathResource (org.springframework.core.io.ClassPathResource)2 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 Descriptors (com.google.protobuf.Descriptors)1 DynamicMessage (com.google.protobuf.DynamicMessage)1 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)1