0
votes

I'm developing a REST service Odata V4.0 compliant. For that purpose, I'm using Apache Olingo v4.2.0 and I need to implement some relationship operations.

In order to implement that feature, I implement ReferenceProcessor interface:

package es.mesview.odataapi.service.processors;

import es.mesview.odataapi.data.AbstractManagerDataModel;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.*;
import org.apache.olingo.server.api.deserializer.DeserializerResult;
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
import org.apache.olingo.server.api.processor.ReferenceProcessor;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;

import java.io.InputStream;
import java.util.List;

/**
 * Created by hector on 11/07/2016.
 */
public class MesViewReferenceProcessor implements ReferenceProcessor {
    private OData odata;
    private ServiceMetadata serviceMetadata;
    private AbstractManagerDataModel abstractManagerDataModel;

    public MesViewReferenceProcessor(AbstractManagerDataModel abstractManagerDataModel) {
        this.abstractManagerDataModel = abstractManagerDataModel;
    }

    @Override
    public void readReference(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
        System.out.println("Read reference: Not implemented yet.");
    }

    @Override
    public void createReference(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat) throws ODataApplicationException, ODataLibraryException {
        System.out.println("Create reference: Not implemented yet.");
    }

    @Override
    public void updateReference(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat) throws ODataApplicationException, ODataLibraryException {
        // 1. Retrieve info from URI
        // 1.1. retrieve the info about the requested entity set
        List<UriResource> resourcePaths = uriInfo.getUriResourceParts();

        UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
        EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
        EdmEntityType edmEntityType = uriResourceEntitySet.getEntityType();

        // Retrieve the payload
        ODataDeserializer deserializer = this.odata.createDeserializer(requestFormat);


        // Get reference entity
        DeserializerResult reference = deserializer.entityReferences(request.getBody());
        // reference.getEntity return null
        Entity referencedEntity = reference.getEntity();

        List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
        HttpMethod httpMethod = request.getMethod();

        // Update reference
        abstractManagerDataModel.updateReferenceData(edmEntitySet, keyPredicates, referencedEntity, httpMethod, request.getRawBaseUri());

        response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
    }

    @Override
    public void deleteReference(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException {
        System.out.println("Delete reference: Not implemented yet.");
    }

    @Override
    public void init(OData odata, ServiceMetadata serviceMetadata) {
        this.odata = odata;
        this.serviceMetadata = serviceMetadata;
    }
}

But when I try to get the referenced entity, it returns null (Entity referencedEntity = reference.getEntity();).

How can I get the referenced entity, or at least, entity id?

To execute updateReference, I send the request:

PUT /odataapi/odata-api.svc/areas(5)/plant/$ref HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 73ee1876-1685-336f-7cbe-108e5bc9c4b5

{
    "@odata.context":"http://localhost:8080/odataapi/odata-api.svc/$metadata#$ref",
    "@odata.id":"Plants(2)"
}
2

2 Answers

3
votes

You need to use the method "getEntityReferences" which will give you a list of all references in the payload. The method "getEntity" will only deliver an entity if you deserialize an entity object e.g. in your "updateEntity" method.

Here is the example from the Olingo test scenario: https://github.com/apache/olingo-odata4/blob/2e24ffd1d3c343fdec45f8dbf0398783a0a86f3f/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java#L352

0
votes

Your request lacks @odata.context which is a must have for a reference request. Here's the link for the OData documentation.