Search in sources :

Example 16 with Service

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

the class PostmanCollectionImporter method getServiceDefinitions.

@Override
public List<Service> getServiceDefinitions() throws MockRepositoryImportException {
    List<Service> result = new ArrayList<>();
    // Build a new service.
    Service service = new Service();
    // Collection V2 as an info node.
    if (collection.has("info")) {
        isV2Collection = true;
        fillServiceDefinition(service);
    } else {
        throw new MockRepositoryImportException("Only Postman v2 Collection are supported.");
    }
    // Then build its operations.
    try {
        service.setOperations(extractOperations());
    } catch (Throwable t) {
        log.error("Runtime exception while extracting Operations for " + service.getName());
        throw new MockRepositoryImportException("Runtime exception for " + service.getName() + ": " + t.getMessage());
    }
    result.add(service);
    return result;
}
Also used : Service(io.github.microcks.domain.Service) MockRepositoryImportException(io.github.microcks.util.MockRepositoryImportException)

Example 17 with Service

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

the class ProtobufImporter method getServiceDefinitions.

@Override
public List<Service> getServiceDefinitions() throws MockRepositoryImportException {
    List<Service> results = new ArrayList<>();
    for (DescriptorProtos.FileDescriptorProto fdp : fds.getFileList()) {
        // Retrieve version from package name.
        // org.acme package => org.acme version
        // org.acme.v1 package => v1 version
        String packageName = fdp.getPackage();
        String[] parts = packageName.split("\\.");
        String version = (parts.length > 2 ? parts[parts.length - 1] : packageName);
        for (DescriptorProtos.ServiceDescriptorProto sdp : fdp.getServiceList()) {
            // Build a new service.
            Service service = new Service();
            service.setName(sdp.getName());
            service.setVersion(version);
            service.setType(ServiceType.GRPC);
            service.setXmlNS(packageName);
            // Then build its operations.
            service.setOperations(extractOperations(sdp));
            results.add(service);
        }
    }
    return results;
}
Also used : ArrayList(java.util.ArrayList) Service(io.github.microcks.domain.Service) DescriptorProtos(com.google.protobuf.DescriptorProtos)

Example 18 with Service

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

the class MetadataImporter method getServiceDefinitions.

@Override
public List<Service> getServiceDefinitions() throws MockRepositoryImportException {
    List<Service> result = new ArrayList<>();
    // Build a new service.
    Service service = new Service();
    JsonNode metadataNode = spec.get("metadata");
    if (metadataNode == null) {
        log.error("Missing mandatory metadata in {}", spec.asText());
        throw new MockRepositoryImportException("Mandatory metadata property is missing in APIMetadata");
    }
    service.setName(metadataNode.path("name").asText());
    service.setVersion(metadataNode.path("version").asText());
    Metadata metadata = new Metadata();
    MetadataExtractor.completeMetadata(metadata, metadataNode);
    service.setMetadata(metadata);
    // Then build its operations.
    service.setOperations(extractOperations());
    result.add(service);
    return result;
}
Also used : ArrayList(java.util.ArrayList) Metadata(io.github.microcks.domain.Metadata) Service(io.github.microcks.domain.Service) JsonNode(com.fasterxml.jackson.databind.JsonNode) MockRepositoryImportException(io.github.microcks.util.MockRepositoryImportException)

Example 19 with Service

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

the class GraphQLController method execute.

@RequestMapping(value = "/{service}/{version}/**", method = { RequestMethod.GET, RequestMethod.POST })
public ResponseEntity<?> execute(@PathVariable("service") String serviceName, @PathVariable("version") String version, @RequestParam(value = "delay", required = false) Long delay, @RequestBody(required = false) String body, HttpServletRequest request) {
    log.info("Servicing GraphQL mock response for service [{}, {}]", serviceName, version);
    log.debug("Request body: {}", body);
    long startTime = System.currentTimeMillis();
    // If serviceName was encoded with '+' instead of '%20', remove them.
    if (serviceName.contains("+")) {
        serviceName = serviceName.replace('+', ' ');
    }
    Service service = serviceRepository.findByNameAndVersion(serviceName, version);
    GraphQLHttpRequest graphqlHttpReq;
    Document graphqlRequest;
    try {
        graphqlHttpReq = GraphQLHttpRequest.from(body, request);
        graphqlRequest = requestParser.parseDocument(graphqlHttpReq.getQuery());
    } catch (Exception e) {
        log.error("Error parsing GraphQL request: {}", e);
        return new ResponseEntity<Object>("Error parsing GraphQL request: " + e.getMessage(), HttpStatus.BAD_REQUEST);
    }
    Definition graphqlDef = graphqlRequest.getDefinitions().get(0);
    OperationDefinition graphqlOperation = (OperationDefinition) graphqlDef;
    log.debug("Got this graphqlOperation: {}", graphqlOperation);
    // Operation type is direct but name depends on syntax...
    String operationName = graphqlHttpReq.getOperationName();
    String operationType = graphqlOperation.getOperation().toString();
    // Check is it's an introspection query to handle first.
    if ("QUERY".equals(operationType) && INTROSPECTION_SELECTION.equals(((Field) graphqlOperation.getSelectionSet().getSelections().get(0)).getName())) {
        log.info("Handling GraphQL schema introspection query...");
        Resource graphqlSchema = resourceRepository.findByServiceIdAndType(service.getId(), ResourceType.GRAPHQL_SCHEMA).get(0);
        TypeDefinitionRegistry typeDefinitionRegistry = schemaParser.parse(graphqlSchema.getContent());
        GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, RuntimeWiring.MOCKED_WIRING);
        GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build();
        ExecutionResult executionResult = graphQL.execute(graphqlHttpReq.getQuery());
        String responseContent = null;
        try {
            responseContent = mapper.writeValueAsString(executionResult);
        } catch (JsonProcessingException jpe) {
            log.error("Unknown Json processing exception", jpe);
            return new ResponseEntity<>(jpe.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity<Object>(responseContent, HttpStatus.OK);
    }
    // Then deal with one or many regular GraphQL selection queries.
    List<GraphQLQueryResponse> graphqlResponses = new ArrayList<>();
    final Long[] maxDelay = { (delay == null ? 0L : delay) };
    for (Selection selection : graphqlOperation.getSelectionSet().getSelections()) {
        GraphQLQueryResponse graphqlResponse = null;
        try {
            graphqlResponse = processGraphQLQuery(service, operationType, (Field) selection, graphqlRequest.getDefinitionsOfType(FragmentDefinition.class), body, graphqlHttpReq, request);
            graphqlResponses.add(graphqlResponse);
            if (graphqlResponse.getOperationDelay() != null && graphqlResponse.getOperationDelay() > maxDelay[0]) {
                maxDelay[0] = graphqlResponse.getOperationDelay();
            }
        } catch (GraphQLQueryProcessingException e) {
            log.error("Caught a GraphQL processing exception", e);
            return new ResponseEntity<Object>(e.getMessage(), e.getStatus());
        }
    }
    /* Optimized parallel version but need to better handle exception.
      graphqlResponses = graphqlOperation.getSelectionSet().getSelections().stream().parallel().map(selection -> {
         try {
            GraphQLQueryResponse graphqlResponse = processGraphQLQuery(service, operationType, (Field) selection,
                  graphqlRequest.getDefinitionsOfType(FragmentDefinition.class), body, graphqlHttpReq, request);
            if (graphqlResponse.getOperationDelay() != null && graphqlResponse.getOperationDelay() > maxDelay[0]) {
               maxDelay[0] = graphqlResponse.getOperationDelay();
            }
            return graphqlResponse;
         } catch (GraphQLQueryProcessingException e) {
            log.error("Caught a GraphQL processing exception", e);
            return null;
         }
      }).collect(Collectors.toList());
      */
    // Deal with response headers.
    HttpHeaders responseHeaders = new HttpHeaders();
    for (GraphQLQueryResponse response : graphqlResponses) {
        if (response.getResponse().getHeaders() != null) {
            for (Header header : response.getResponse().getHeaders()) {
                if (!HttpHeaders.TRANSFER_ENCODING.equalsIgnoreCase(header.getName())) {
                    responseHeaders.put(header.getName(), new ArrayList<>(header.getValues()));
                }
            }
        }
    }
    if (!responseHeaders.containsKey("Content-Type") && !responseHeaders.containsKey("content-type")) {
        responseHeaders.put("Content-Type", List.of("application/json"));
    }
    // Waiting for delay if any.
    MockControllerCommons.waitForDelay(startTime, maxDelay[0]);
    // Publish an invocation event before returning if enabled.
    if (enableInvocationStats) {
        MockControllerCommons.publishMockInvocation(applicationContext, this, service, graphqlResponses.get(0).getResponse(), startTime);
    }
    String responseContent = null;
    JsonNode responseNode = graphqlResponses.get(0).getJsonResponse();
    // If multi-queries and aliases were used, recompose an aggregated result.
    if (graphqlResponses.size() > 1) {
        ObjectNode aggregated = mapper.createObjectNode();
        ObjectNode dataNode = aggregated.putObject("data");
        for (GraphQLQueryResponse response : graphqlResponses) {
            dataNode.set(response.getAlias(), response.getJsonResponse().path("data").path(response.getOperationName()).deepCopy());
        }
        responseNode = aggregated;
    }
    try {
        responseContent = mapper.writeValueAsString(responseNode);
    } catch (JsonProcessingException e) {
        log.error("Unknown Json processing exception", e);
        return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
    return new ResponseEntity<Object>(responseContent, responseHeaders, HttpStatus.OK);
}
Also used : HttpHeaders(org.springframework.http.HttpHeaders) TypeDefinitionRegistry(graphql.schema.idl.TypeDefinitionRegistry) ArrayList(java.util.ArrayList) JsonNode(com.fasterxml.jackson.databind.JsonNode) GraphQLHttpRequest(io.github.microcks.util.graphql.GraphQLHttpRequest) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) GraphQL(graphql.GraphQL) Resource(io.github.microcks.domain.Resource) Service(io.github.microcks.domain.Service) ExecutionResult(graphql.ExecutionResult) GraphQLSchema(graphql.schema.GraphQLSchema) JsonMappingException(io.github.microcks.util.dispatcher.JsonMappingException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) ResponseEntity(org.springframework.http.ResponseEntity) Header(io.github.microcks.domain.Header) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 20 with Service

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

the class GraphQLImporter method getServiceDefinitions.

@Override
public List<Service> getServiceDefinitions() throws MockRepositoryImportException {
    List<Service> results = new ArrayList<>();
    Service service = new Service();
    service.setType(ServiceType.GRAPHQL);
    // 1st thing: look for comments to get service and version identifiers.
    for (Comment comment : graphqlSchema.getComments()) {
        String content = comment.getContent().trim();
        if (content.startsWith(MICROCKS_ID_STARTER)) {
            String identifiers = content.substring(MICROCKS_ID_STARTER.length());
            if (identifiers.indexOf(":") != -1) {
                String[] serviceAndVersion = identifiers.split(":");
                service.setName(serviceAndVersion[0].trim());
                service.setVersion(serviceAndVersion[1].trim());
                break;
            }
            log.error("microcksId comment is malformed. Expecting \'microcksId: <API_name>:<API_version>\'");
            throw new MockRepositoryImportException("microcksId comment is malformed. Expecting \'microcksId: <API_name>:<API_version>\'");
        }
    }
    if (service.getName() == null || service.getVersion() == null) {
        log.error("No microcksId: comment found into GraphQL schema to get API name and version");
        throw new MockRepositoryImportException("No microcksId: comment found into GraphQL schema to get API name and version");
    }
    // We found a service, build its operations.
    service.setOperations(extractOperations());
    results.add(service);
    return results;
}
Also used : Comment(graphql.language.Comment) ArrayList(java.util.ArrayList) Service(io.github.microcks.domain.Service) MockRepositoryImportException(io.github.microcks.util.MockRepositoryImportException)

Aggregations

Service (io.github.microcks.domain.Service)42 MockRepositoryImportException (io.github.microcks.util.MockRepositoryImportException)18 Operation (io.github.microcks.domain.Operation)15 Test (org.junit.Test)15 Resource (io.github.microcks.domain.Resource)12 IOException (java.io.IOException)10 ResponseEntity (org.springframework.http.ResponseEntity)7 Response (io.github.microcks.domain.Response)6 File (java.io.File)6 ArrayList (java.util.ArrayList)6 RequestMapping (org.springframework.web.bind.annotation.RequestMapping)6 Exchange (io.github.microcks.domain.Exchange)4 Request (io.github.microcks.domain.Request)4 RequestResponsePair (io.github.microcks.domain.RequestResponsePair)4 UnidirectionalEvent (io.github.microcks.domain.UnidirectionalEvent)4 List (java.util.List)4 HttpHeaders (org.springframework.http.HttpHeaders)4 JsonNode (com.fasterxml.jackson.databind.JsonNode)3 Header (io.github.microcks.domain.Header)3 Metadata (io.github.microcks.domain.Metadata)3