Thursday 25 July 2019

OLingo: OData: Delete an entity


To delete an entity, we must implement ‘deleteEntity’ method of EntityProcessor interface.

Procedure is very simple.
a.   Get the id from the request uri
b.   Delete the product with given id.

 @Override
 public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo)
   throws ODataApplicationException, ODataLibraryException {
  List<UriResource> resourcePaths = uriInfo.getUriResourceParts();

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

  List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
  EntityUtil.deleteEntityData(edmEntitySet, keyPredicates);

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

Since this is continuation to my previous post, I am adding only updated classes.


DemoEntityProcessor.java
package com.app.service;

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

import org.apache.olingo.commons.api.data.ContextURL;
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.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.deserializer.DeserializerResult;
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
import org.apache.olingo.server.api.processor.EntityProcessor;
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.SerializerResult;
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 com.app.util.EntityUtil;

public class DemoEntityProcessor implements EntityProcessor {
 private OData odata;
 private ServiceMetadata serviceMetadata;

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

 @Override
 public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
   throws ODataApplicationException, ODataLibraryException {
  // 1. retrieve the Entity Type
  List<UriResource> resourcePaths = uriInfo.getUriResourceParts();

  // Note: only in our example we can assume that the first segment is the
  // EntitySet
  UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
  EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();

  // 2. retrieve the data from backend
  List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
  Entity entity = EntityUtil.readEntityData(edmEntitySet, keyPredicates);

  // 3. serialize
  EdmEntityType entityType = edmEntitySet.getEntityType();

  ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();
  // expand and select currently not supported
  EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build();

  ODataSerializer serializer = odata.createSerializer(responseFormat);
  SerializerResult serializerResult = serializer.entity(serviceMetadata, entityType, entity, options);
  InputStream entityStream = serializerResult.getContent();

  // 4. configure the response object
  response.setContent(entityStream);
  response.setStatusCode(HttpStatusCode.OK.getStatusCode());
  response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
 }

 @Override
 public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
   ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
  EdmEntitySet edmEntitySet = EntityUtil.getEntitySetFromURI(uriInfo);

  EdmEntityType edmEntityType = edmEntitySet.getEntityType();

  InputStream requestInputStream = request.getBody();
  ODataDeserializer deserializer = this.odata.createDeserializer(requestFormat);
  DeserializerResult result = deserializer.entity(requestInputStream, edmEntityType);
  Entity requestEntity = result.getEntity();

  Entity createdEntity = EntityUtil.createEntityData(edmEntitySet, requestEntity);

  ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();

  EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build();

  ODataSerializer serializer = this.odata.createSerializer(responseFormat);
  SerializerResult serializedResponse = serializer.entity(serviceMetadata, edmEntityType, createdEntity, options);

  response.setContent(serializedResponse.getContent());
  response.setStatusCode(HttpStatusCode.CREATED.getStatusCode());
  response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
 }

 @Override
 public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
   ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {

  List<UriResource> resourcePaths = uriInfo.getUriResourceParts();

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

  InputStream requestInputStream = request.getBody();
  ODataDeserializer deserializer = this.odata.createDeserializer(requestFormat);
  DeserializerResult result = deserializer.entity(requestInputStream, edmEntityType);
  Entity requestEntity = result.getEntity();

  List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();

  HttpMethod httpMethod = request.getMethod();
  EntityUtil.updateEntityData(edmEntitySet, keyPredicates, requestEntity, httpMethod);

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

 }

 @Override
 public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo)
   throws ODataApplicationException, ODataLibraryException {
  List<UriResource> resourcePaths = uriInfo.getUriResourceParts();

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

  List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
  EntityUtil.deleteEntityData(edmEntitySet, keyPredicates);

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

}


EntityUtil.java
package com.app.util;

import java.util.List;

import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.server.api.ODataApplicationException;
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 com.app.service.DemoEdmProvider;

/**
 * Responsible to perform CRUD operations on entities.
 * 
 * @author Krishna
 *
 */
public class EntityUtil {

 public static EntityCollection getData(EdmEntitySet edmEntitySet) {
  if (DemoEdmProvider.ES_PRODUCTS_NAME.equals(edmEntitySet.getName())) {
   return ProductUtil.getProductsData();
  }

  return null;
 }

 public static Entity readEntityData(EdmEntitySet edmEntitySet, List<UriParameter> keyParams)
   throws ODataApplicationException {

  EdmEntityType edmEntityType = edmEntitySet.getEntityType();

  // actually, this is only required if we have more than one Entity Type
  if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) {
   return ProductUtil.getProduct(edmEntityType, keyParams);
  }

  return null;
 }

 public static EdmEntitySet getEntitySetFromURI(UriInfo uriInfo) {
  List<UriResource> resourcePaths = uriInfo.getUriResourceParts();

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

  return edmEntitySet;
 }

 public static Entity createEntityData(EdmEntitySet edmEntitySet, Entity entityToCreate) {

  EdmEntityType edmEntityType = edmEntitySet.getEntityType();

  // actually, this is only required if we have more than one Entity Type
  if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) {
   return ProductUtil.createProduct(edmEntityType, entityToCreate);
  }

  return null;
 }

 public static void updateEntityData(EdmEntitySet edmEntitySet, List<UriParameter> keyPredicates,
   Entity requestEntity, HttpMethod httpMethod) throws ODataApplicationException {

  EdmEntityType edmEntityType = edmEntitySet.getEntityType();

  if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) {
   ProductUtil.updateProduct(edmEntityType, keyPredicates, requestEntity, httpMethod);
  }
 }

 public static void deleteEntityData(EdmEntitySet edmEntitySet, List<UriParameter> keyPredicates) {
  EdmEntityType edmEntityType = edmEntitySet.getEntityType();

  // actually, this is only required if we have more than one Entity Type
  if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) {
   ProductUtil.deleteProduct(keyPredicates);
  }
 }

}


ProductUtil.java
package com.app.util;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.data.ValueType;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.ex.ODataRuntimeException;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.UriParameter;

import com.app.model.Product;

public class ProductUtil {
 private static List<Product> products = new ArrayList<>();
 public static int idCounter = 3;

 static {
  Product prod1 = new Product(1, "Washing Machine by AVC", "Good for morth east countries", 876544);
  Product prod2 = new Product(2, "XYZ Camera", "Catch pics while travelling", 965987);

  products.add(prod1);
  products.add(prod2);
 }

 public static int getId() {
  return idCounter++;
 }

 private static Entity getProductEntity(final Product product) {
  Entity entity = new Entity().addProperty(new Property(null, "ID", ValueType.PRIMITIVE, product.getId()))
    .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, product.getName()))
    .addProperty(new Property(null, "Description", ValueType.PRIMITIVE, product.getDescription()))
    .addProperty(new Property(null, "Price", ValueType.PRIMITIVE, product.getPrice()));
  entity.setId(createId("Products", product.getId()));
  return entity;
 }

 public static EntityCollection getProductsData() {
  EntityCollection dataToSend = new EntityCollection();
  List<Entity> productList = dataToSend.getEntities();

  for (Product prod : products) {
   productList.add(getProductEntity(prod));
  }

  return dataToSend;
 }

 private static URI createId(final String entitySetName, final Object id) {
  try {
   return new URI(entitySetName + "(" + String.valueOf(id) + ")");
  } catch (URISyntaxException e) {
   throw new ODataRuntimeException("Unable to create id for entity: " + entitySetName, e);
  }
 }

 public static Entity getProduct(EdmEntityType edmEntityType, List<UriParameter> keyParams)
   throws ODataApplicationException {
  EntityCollection entitySet = getProductsData();

  Entity requestedEntity = findEntity(edmEntityType, entitySet, keyParams);

  if (requestedEntity == null) {
   throw new ODataApplicationException("Entity for requested key doesn't exist",
     HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
  }

  return requestedEntity;
 }

 public static Entity findEntity(EdmEntityType edmEntityType, EntityCollection entitySet,
   List<UriParameter> keyParams) throws ODataApplicationException {

  List<Entity> entityList = entitySet.getEntities();

  for (Entity entity : entityList) {
   boolean foundEntity = entityMatchesAllKeys(edmEntityType, entity, keyParams);
   if (foundEntity) {
    return entity;
   }
  }

  return null;
 }

 private static String getValueOfTheProperty(EdmEntityType edmEntityType, Entity entity, String propertyName)
   throws ODataApplicationException {
  EdmProperty edmKeyProperty = (EdmProperty) edmEntityType.getProperty(propertyName);

  /*
   * Get some basic information to convert the property value of this
   * entity to string
   */
  Boolean isNullable = edmKeyProperty.isNullable();
  Integer maxLength = edmKeyProperty.getMaxLength();
  Integer precision = edmKeyProperty.getPrecision();
  Boolean isUnicode = edmKeyProperty.isUnicode();
  Integer scale = edmKeyProperty.getScale();

  EdmType edmType = edmKeyProperty.getType();
  Object valueObject = entity.getProperty(propertyName).getValue();

  try {
   EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) edmType;
   return edmPrimitiveType.valueToString(valueObject, isNullable, maxLength, precision, scale, isUnicode);
  } catch (EdmPrimitiveTypeException e) {
   throw new ODataApplicationException("Failed to retrieve String value",
     HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ENGLISH, e);
  }
 }

 public static boolean entityMatchesAllKeys(EdmEntityType edmEntityType, Entity entity, List<UriParameter> keyParams)
   throws ODataApplicationException {

  /* We need to make sure that all the predicates are matched */
  for (final UriParameter key : keyParams) {
   String keyName = key.getName();
   String keyText = key.getText();

   String valueAsString = getValueOfTheProperty(edmEntityType, entity, keyName);

   if (valueAsString == null || !valueAsString.equals(keyText)) {
    return false;
   }
  }

  return true;
 }

 public static Entity createProduct(EdmEntityType edmEntityType, Entity entity) {

  int newId = ProductUtil.getId();

  Property idProperty = entity.getProperty("ID");

  if (idProperty != null) {
   idProperty.setValue(ValueType.PRIMITIVE, Integer.valueOf(newId));
  } else {
   entity.getProperties().add(new Property(null, "ID", ValueType.PRIMITIVE, newId));
  }

  String name = (String) entity.getProperty("Name").getValue();
  String description = (String) entity.getProperty("Description").getValue();
  double price = (Double) entity.getProperty("Price").getValue();

  entity.setId(createId("Products", newId));

  Product prod = new Product(newId, name, description, price);

  products.add(prod);

  return entity;

 }

 public static void updateProduct(EdmEntityType edmEntityType, Entity entity) {

  Property idProperty = entity.getProperty("ID");
  int id = (Integer) idProperty.getValue();

  for (Product prod : products) {

   if (prod.getId() != id) {
    continue;
   }
   String name = null, description = null;
   double price = 0;

   Property property = entity.getProperty("Name");

   if (property != null) {
    name = (String) property.getValue();
   }

   property = entity.getProperty("Description");

   if (property != null) {
    description = (String) property.getValue();
   }

   property = entity.getProperty("Price");

   if (property != null) {
    price = (Double) property.getValue();
   }

   prod.setName(name);
   prod.setDescription(description);
   prod.setPrice(price);
   break;
  }
 }

 public static void updateProduct(EdmEntityType edmEntityType, List<UriParameter> keyPredicates,
   Entity requestEntity, HttpMethod httpMethod) throws ODataApplicationException {
  Entity productEntity = getProduct(edmEntityType, keyPredicates);
  if (productEntity == null) {
   throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(),
     Locale.ENGLISH);
  }

  List<Property> existingProperties = productEntity.getProperties();
  for (Property existingProp : existingProperties) {
   String propName = existingProp.getName();

   if (isKey(edmEntityType, propName)) {
    continue;
   }

   Property updateProperty = requestEntity.getProperty(propName);

   if (updateProperty == null) {
    if (httpMethod.equals(HttpMethod.PATCH)) {
     continue;
    } else if (httpMethod.equals(HttpMethod.PUT)) {
     existingProp.setValue(existingProp.getValueType(), null);
     continue;
    }
   }

   existingProp.setValue(existingProp.getValueType(), updateProperty.getValue());
  }

  updateProduct(edmEntityType, productEntity);

 }

 private static boolean isKey(EdmEntityType edmEntityType, String propertyName) {
  List<EdmKeyPropertyRef> keyPropertyRefs = edmEntityType.getKeyPropertyRefs();
  for (EdmKeyPropertyRef propRef : keyPropertyRefs) {
   String keyPropertyName = propRef.getName();
   if (keyPropertyName.equals(propertyName)) {
    return true;
   }
  }
  return false;
 }

 public static void deleteProduct(List<UriParameter> keyPredicates) {

  for (final UriParameter key : keyPredicates) {
   String keyName = key.getName();

   if (!"ID".equals(keyName)) {
    continue;
   }
   String keyText = key.getText();

   int id = Integer.valueOf(keyText);
   deleteProductById(id);
   break;
  }
 }

 private static void deleteProductById(int id) {
  for (Product prod : products) {
   if (prod.getId() != id)
    continue;

   products.remove(prod);
   break;
  }
 }
}

Run the application on server.

Hit below url, by setting accept header to application/json
http://localhost:8080/olingoWriteData/DemoService.svc/Products


You will receive below response.
{
    "@odata.context": "$metadata#Products",
    "value": [
        {
            "ID": 1,
            "Name": "Washing Machine by AVC",
            "Description": "Good for morth east countries",
            "Price": 876544
        },
        {
            "ID": 2,
            "Name": "XYZ Camera",
            "Description": "Catch pics while travelling",
            "Price": 965987
        }
    ]
}

Hit below request to delete product with id 1.

Method: DELETE
URL: http://localhost:8080/olingoWriteData/DemoService.svc/Products(1)

Confirm the same by hitting the below url.

http://localhost:8080/olingoWriteData/DemoService.svc/Products
{
    "@odata.context": "$metadata#Products",
    "value": [
        {
            "ID": 2,
            "Name": "XYZ Camera",
            "Description": "Catch pics while travelling",
            "Price": 965987
        }
    ]
}


As you see the response, product 1 is deleted.


Previous                                                    Next                                                    Home

3 comments:

  1. how to change property Name to Student in json

    ReplyDelete
  2. can you association link database

    ReplyDelete