Search in sources :

Example 6 with InvalidEntityBodyException

use of com.yahoo.elide.core.exceptions.InvalidEntityBodyException in project elide by yahoo.

the class PersistentResource method toResource.

/**
 * Convert a persistent resource to a resource.
 *
 * @param relationships The relationships
 * @param attributes    The attributes
 * @return The Resource
 */
public Resource toResource(final Map<String, Relationship> relationships, final Map<String, Object> attributes) {
    final Resource resource = new Resource(typeName, (obj == null) ? uuid.orElseThrow(() -> new InvalidEntityBodyException("No id found on object")) : dictionary.getId(obj));
    resource.setRelationships(relationships);
    resource.setAttributes(attributes);
    if (requestScope.getElideSettings().isEnableJsonLinks()) {
        resource.setLinks(requestScope.getElideSettings().getJsonApiLinks().getResourceLevelLinks(this));
    }
    return resource;
}
Also used : InvalidEntityBodyException(com.yahoo.elide.core.exceptions.InvalidEntityBodyException) Resource(com.yahoo.elide.jsonapi.models.Resource)

Example 7 with InvalidEntityBodyException

use of com.yahoo.elide.core.exceptions.InvalidEntityBodyException in project elide by yahoo.

the class CollectionTerminalState method createObject.

private PersistentResource createObject(RequestScope requestScope) throws ForbiddenAccessException, InvalidObjectIdentifierException {
    JsonApiDocument doc = requestScope.getJsonApiDocument();
    JsonApiMapper mapper = requestScope.getMapper();
    if (doc.getData() == null) {
        throw new InvalidEntityBodyException("Invalid JSON-API document: " + doc);
    }
    Data<Resource> data = doc.getData();
    Collection<Resource> resources = data.get();
    Resource resource = (resources.size() == 1) ? IterableUtils.first(resources) : null;
    if (resource == null) {
        try {
            throw new InvalidEntityBodyException(mapper.writeJsonApiDocument(doc));
        } catch (JsonProcessingException e) {
            throw new InternalServerErrorException(e);
        }
    }
    String id = resource.getId();
    Type<?> newObjectClass = requestScope.getDictionary().getEntityClass(resource.getType(), requestScope.getApiVersion());
    if (newObjectClass == null) {
        throw new UnknownEntityException("Entity " + resource.getType() + " not found");
    }
    if (!entityClass.isAssignableFrom(newObjectClass)) {
        throw new InvalidValueException("Cannot assign value of type: " + resource.getType() + " to type: " + entityClass);
    }
    PersistentResource pResource = PersistentResource.createObject(parent.orElse(null), relationName.orElse(null), newObjectClass, requestScope, Optional.ofNullable(id));
    Map<String, Object> attributes = resource.getAttributes();
    if (attributes != null) {
        for (Map.Entry<String, Object> entry : attributes.entrySet()) {
            String fieldName = entry.getKey();
            Object val = entry.getValue();
            pResource.updateAttribute(fieldName, val);
        }
    }
    Map<String, Relationship> relationships = resource.getRelationships();
    if (relationships != null) {
        for (Map.Entry<String, Relationship> entry : relationships.entrySet()) {
            String fieldName = entry.getKey();
            Relationship relationship = entry.getValue();
            Set<PersistentResource> resourceSet = (relationship == null) ? null : relationship.toPersistentResources(requestScope);
            pResource.updateRelation(fieldName, resourceSet);
        }
    }
    return pResource;
}
Also used : PersistentResource(com.yahoo.elide.core.PersistentResource) JsonApiDocument(com.yahoo.elide.jsonapi.models.JsonApiDocument) UnknownEntityException(com.yahoo.elide.core.exceptions.UnknownEntityException) Resource(com.yahoo.elide.jsonapi.models.Resource) PersistentResource(com.yahoo.elide.core.PersistentResource) ToString(lombok.ToString) InvalidValueException(com.yahoo.elide.core.exceptions.InvalidValueException) InvalidEntityBodyException(com.yahoo.elide.core.exceptions.InvalidEntityBodyException) Relationship(com.yahoo.elide.jsonapi.models.Relationship) InternalServerErrorException(com.yahoo.elide.core.exceptions.InternalServerErrorException) JsonApiMapper(com.yahoo.elide.jsonapi.JsonApiMapper) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) HashMap(java.util.HashMap) Map(java.util.Map) MultivaluedMap(javax.ws.rs.core.MultivaluedMap)

Example 8 with InvalidEntityBodyException

use of com.yahoo.elide.core.exceptions.InvalidEntityBodyException in project elide by yahoo.

the class JsonApiPatch method handleReplaceOp.

/**
 * Replace data via patch extension.
 */
private Supplier<Pair<Integer, JsonNode>> handleReplaceOp(String path, JsonNode patchVal, PatchRequestScope requestScope, PatchAction action) {
    try {
        JsonApiDocument value = requestScope.getMapper().readJsonApiPatchExtValue(patchVal);
        if (!path.contains("relationships")) {
            // Reserved
            Data<Resource> data = value.getData();
            Collection<Resource> resources = data.get();
            // Defer relationship updating until the end
            getSingleResource(resources).setRelationships(null);
            // Reparse since we mangle it first
            action.doc = requestScope.getMapper().readJsonApiPatchExtValue(patchVal);
            action.path = path;
            action.isPostProcessing = true;
        }
        // Defer relationship updating until the end
        PatchVisitor visitor = new PatchVisitor(new PatchRequestScope(path, value, requestScope));
        return visitor.visit(JsonApiParser.parse(path));
    } catch (IOException e) {
        throw new InvalidEntityBodyException("Could not parse patch extension value: " + patchVal);
    }
}
Also used : InvalidEntityBodyException(com.yahoo.elide.core.exceptions.InvalidEntityBodyException) JsonApiDocument(com.yahoo.elide.jsonapi.models.JsonApiDocument) Resource(com.yahoo.elide.jsonapi.models.Resource) PatchVisitor(com.yahoo.elide.jsonapi.parser.PatchVisitor) IOException(java.io.IOException)

Example 9 with InvalidEntityBodyException

use of com.yahoo.elide.core.exceptions.InvalidEntityBodyException in project elide by yahoo.

the class JsonApiPatch method handleAddOp.

/**
 * Add a document via patch extension.
 */
private Supplier<Pair<Integer, JsonNode>> handleAddOp(String path, JsonNode patchValue, PatchRequestScope requestScope, PatchAction action) {
    try {
        JsonApiDocument value = requestScope.getMapper().readJsonApiPatchExtValue(patchValue);
        Data<Resource> data = value.getData();
        if (data == null || data.get() == null) {
            throw new InvalidEntityBodyException("Expected an entity body but received none.");
        }
        Collection<Resource> resources = data.get();
        if (!path.contains("relationships")) {
            // Reserved key for relationships
            String id = getSingleResource(resources).getId();
            if (StringUtils.isEmpty(id)) {
                throw new InvalidEntityBodyException("Patch extension requires all objects to have an assigned " + "ID (temporary or permanent) when assigning relationships.");
            }
            String fullPath = path + "/" + id;
            // Defer relationship updating until the end
            getSingleResource(resources).setRelationships(null);
            // Reparse since we mangle it first
            action.doc = requestScope.getMapper().readJsonApiPatchExtValue(patchValue);
            action.path = fullPath;
            action.isPostProcessing = true;
        }
        PostVisitor visitor = new PostVisitor(new PatchRequestScope(path, value, requestScope));
        return visitor.visit(JsonApiParser.parse(path));
    } catch (HttpStatusException e) {
        action.cause = e;
        throw e;
    } catch (IOException e) {
        throw new InvalidEntityBodyException("Could not parse patch extension value: " + patchValue);
    }
}
Also used : InvalidEntityBodyException(com.yahoo.elide.core.exceptions.InvalidEntityBodyException) JsonApiDocument(com.yahoo.elide.jsonapi.models.JsonApiDocument) Resource(com.yahoo.elide.jsonapi.models.Resource) HttpStatusException(com.yahoo.elide.core.exceptions.HttpStatusException) IOException(java.io.IOException) PostVisitor(com.yahoo.elide.jsonapi.parser.PostVisitor)

Example 10 with InvalidEntityBodyException

use of com.yahoo.elide.core.exceptions.InvalidEntityBodyException in project elide by yahoo.

the class QueryRunner method executeGraphQLRequest.

private ElideResponse executeGraphQLRequest(String baseUrlEndPoint, ObjectMapper mapper, User principal, String graphQLDocument, GraphQLQuery query, UUID requestId, Map<String, List<String>> requestHeaders) {
    boolean isVerbose = false;
    String queryText = query.getQuery();
    boolean isMutation = isMutation(queryText);
    try (DataStoreTransaction tx = isMutation ? elide.getDataStore().beginTransaction() : elide.getDataStore().beginReadTransaction()) {
        elide.getTransactionRegistry().addRunningTransaction(requestId, tx);
        if (query.getQuery() == null || query.getQuery().isEmpty()) {
            return ElideResponse.builder().responseCode(HttpStatus.SC_BAD_REQUEST).body("A `query` key is required.").build();
        }
        // get variables from request for constructing entityProjections
        Map<String, Object> variables = query.getVariables();
        // TODO - get API version.
        GraphQLProjectionInfo projectionInfo = new GraphQLEntityProjectionMaker(elide.getElideSettings(), variables, apiVersion).make(queryText);
        GraphQLRequestScope requestScope = new GraphQLRequestScope(baseUrlEndPoint, tx, principal, apiVersion, elide.getElideSettings(), projectionInfo, requestId, requestHeaders);
        isVerbose = requestScope.getPermissionExecutor().isVerbose();
        // Logging all queries. It is recommended to put any private information that shouldn't be logged into
        // the "variables" section of your query. Variable values are not logged.
        log.info("Processing GraphQL query:\n{}", queryText);
        ExecutionInput.Builder executionInput = new ExecutionInput.Builder().localContext(requestScope).query(queryText);
        if (query.getOperationName() != null) {
            executionInput.operationName(query.getOperationName());
        }
        executionInput.variables(variables);
        ExecutionResult result = api.execute(executionInput);
        tx.preCommit(requestScope);
        requestScope.getPermissionExecutor().executeCommitChecks();
        if (isMutation) {
            if (!result.getErrors().isEmpty()) {
                HashMap<String, Object> abortedResponseObject = new HashMap<>();
                abortedResponseObject.put("errors", result.getErrors());
                abortedResponseObject.put("data", null);
                // Do not commit. Throw OK response to process tx.close correctly.
                throw new WebApplicationException(Response.ok(mapper.writeValueAsString(abortedResponseObject)).build());
            }
            requestScope.saveOrCreateObjects();
        }
        tx.flush(requestScope);
        requestScope.runQueuedPreCommitTriggers();
        elide.getAuditLogger().commit();
        tx.commit(requestScope);
        requestScope.runQueuedPostCommitTriggers();
        if (log.isTraceEnabled()) {
            requestScope.getPermissionExecutor().logCheckStats();
        }
        return ElideResponse.builder().responseCode(HttpStatus.SC_OK).body(mapper.writeValueAsString(result)).build();
    } catch (JsonProcessingException e) {
        log.debug("Invalid json body provided to GraphQL", e);
        return buildErrorResponse(mapper, new InvalidEntityBodyException(graphQLDocument), isVerbose);
    } catch (IOException e) {
        log.error("Uncaught IO Exception by Elide in GraphQL", e);
        return buildErrorResponse(mapper, new TransactionException(e), isVerbose);
    } catch (RuntimeException e) {
        return handleRuntimeException(elide, e, isVerbose);
    } finally {
        elide.getTransactionRegistry().removeRunningTransaction(requestId);
        elide.getAuditLogger().clear();
    }
}
Also used : WebApplicationException(javax.ws.rs.WebApplicationException) HashMap(java.util.HashMap) GraphQLProjectionInfo(com.yahoo.elide.graphql.parser.GraphQLProjectionInfo) ExecutionResult(graphql.ExecutionResult) IOException(java.io.IOException) InvalidEntityBodyException(com.yahoo.elide.core.exceptions.InvalidEntityBodyException) TransactionException(com.yahoo.elide.core.exceptions.TransactionException) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) GraphQLEntityProjectionMaker(com.yahoo.elide.graphql.parser.GraphQLEntityProjectionMaker) ExecutionInput(graphql.ExecutionInput) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException)

Aggregations

InvalidEntityBodyException (com.yahoo.elide.core.exceptions.InvalidEntityBodyException)14 Resource (com.yahoo.elide.jsonapi.models.Resource)6 IOException (java.io.IOException)6 JsonApiDocument (com.yahoo.elide.jsonapi.models.JsonApiDocument)5 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)3 PersistentResource (com.yahoo.elide.core.PersistentResource)3 HashMap (java.util.HashMap)3 DataStoreTransaction (com.yahoo.elide.core.datastore.DataStoreTransaction)2 HttpStatusException (com.yahoo.elide.core.exceptions.HttpStatusException)2 InvalidValueException (com.yahoo.elide.core.exceptions.InvalidValueException)2 TransactionException (com.yahoo.elide.core.exceptions.TransactionException)2 GraphQLEntityProjectionMaker (com.yahoo.elide.graphql.parser.GraphQLEntityProjectionMaker)2 GraphQLProjectionInfo (com.yahoo.elide.graphql.parser.GraphQLProjectionInfo)2 ExecutionInput (graphql.ExecutionInput)2 ExecutionResult (graphql.ExecutionResult)2 Map (java.util.Map)2 WebApplicationException (javax.ws.rs.WebApplicationException)2 Version (com.fasterxml.jackson.core.Version)1 JsonNode (com.fasterxml.jackson.databind.JsonNode)1 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1