JAX-RS 2.0 and OData

45
JAX-RS 2.0 AND ODATA Anil Allewar ( [email protected] )

description

The presentation provides overview of JAX-RS 2.0 and the cool new things that come with it. It also provides an introduction to OData which is a protocol proposed by Microsoft for data interchange.

Transcript of JAX-RS 2.0 and OData

Page 1: JAX-RS 2.0 and OData

JAX-RS 2.0 AND ODATAAnil Allewar ( [email protected] )

Page 2: JAX-RS 2.0 and OData

About Me

Graduated (finally) as BE in Computers - 2002

Worked with Infosys, Opus Software Solutions and Synerzip

Core expertise in Java Enterprise and Middle-Ware stack

EAI, EII, Rule Engines, ESB, Spring, ORM, Data Virtualization

Currently working as Solutions Architect with Synerzip

Page 3: JAX-RS 2.0 and OData

Agenda

REST methodology introduction JAX-RS 2.0

History Use cases Features

Odata History Use cases Features

Page 4: JAX-RS 2.0 and OData

SOA

Service Oriented Architecture is an architecture paradigm where the software components are provided as services accessed through a network accessible endpoint

There is no object broker required as there is no remote object reference held by the clientRegistry

ContractProtocolDefines Format & Operations

Registers

Page 5: JAX-RS 2.0 and OData

What is REST?

REST stands for REpresentational State Transfer. The largest example of system conforming to REST

architecture is the World Wide Web. In the REST architectural style, data and functionality

are considered resources and are accessed using Uniform Resource Identifiers (URIs), typically links on the Web.

This architecture style is called REST since the state of the client changes with each URI (link in layman’s term) accessed. The URI provides the representation that is returned by the resource.

Resources are manipulated using a fixed set of four CRUD (create, read, update, delete) operations: PUT, GET, POST and DELETE

Current version of JAX-RS in production is JAX-RS 1.1 and JAX-RS 2.0 is currently being drafted.

Page 6: JAX-RS 2.0 and OData

JAX-RS

JAX-RS is Java API for RESTful Web Services

REST principals Assign URL to everything Link things together for state

transition(called HyperMedia as the engine of application state)

Use common methods Multiple representations of state Stateless communication

Introduced in JEE 5

Page 7: JAX-RS 2.0 and OData

Pros/Cons: JAX-WS Vs JAX-RS

JAX-WSJAX-WS JAX-RSJAX-RS

• Formal contract that describes the

web service (in the form of WSDL) is

available• Technologies defined by the

WorldWide Web Consortium (W3C):

HTTP (forTransport protocol), SOAP and

WSDL• Implemented either using an

EJB 3endpoint or using servlet

endpoint.• Can provide transactions,

security,Reliability and asynchronous

messages

• Formal contract that describes the

web service (in the form of WSDL) is

available• Technologies defined by the

WorldWide Web Consortium (W3C):

HTTP (forTransport protocol), SOAP and

WSDL• Implemented either using an

EJB 3endpoint or using servlet

endpoint.• Can provide transactions,

security,Reliability and asynchronous

messages

• Does not require creation of

client/server proxies• Requires only HTTP forapplication protocol - data interchange using XML, HTML,JSON,URL encoded forms etc• Implemented as a servletendpoint only • Possible to discover

resourceswithout centralized repository

• Does not require creation of

client/server proxies• Requires only HTTP forapplication protocol - data interchange using XML, HTML,JSON,URL encoded forms etc• Implemented as a servletendpoint only • Possible to discover

resourceswithout centralized repository• Requires client/server

proxies to make the SOAP based web

service call

• Requires client/server proxies to

make the SOAP based web service call

• Service provider and client need

to have understanding of thecontext and content provided

byservice (Not now as WSDL 2.0 /WADL / XML schema can beused to describe REST web

service) butthey don’t have standard

client support

• Service provider and client need

to have understanding of thecontext and content provided

byservice (Not now as WSDL 2.0 /WADL / XML schema can beused to describe REST web

service) butthey don’t have standard

client support

Page 8: JAX-RS 2.0 and OData

JAX-RS annotations

Annotation Description

@Path The @Path annotation defines the relative path where the web service is hosted. You could also embed variables in path like “/employee/{id}. A @Path value isn’t required to have leading or trailing slashes (/).The path can be applied to a root resource or to a sub-resource.

@GET, @POST@DELETE, @PUT

These annotations are request method designators and correspond to HTTP request method that will be serviced by this class method

@PathParam The @PathParam annotation is a type of parameter that you can extract from the URI path and use in the class/method

@QueryParam The @QueryParam annotation is a type of parameter that you can extract from the request URI query parameters and use in the class/method

@Consumes The @Consumes annotation is used to specify the MIME types of representations sent by the client that a resource can consume.

@Produces The @Produces annotation is used to specify the MIME types of representations sent by the resource to the client e.g. “application/xml”

Page 9: JAX-RS 2.0 and OData

Basic REST Web Service@Path("rest")public class RootResource {

/* * The @Context makes the HTTP context related objects available to the * resource class */@Contextprivate transient SecurityContext secContext;

@Contextprivate transient HttpServletRequest request;

@Injectprivate Provider<BaseProducer> producer;

@Path("employee")public EmployeeResource getEmployeeResource() {

this.request.setAttribute("test", "Memory");EmployeeResource returnResource = new EmployeeResource();returnResource.setContext(this.secContext);producer.get();return returnResource;

}@GET@Produces({ "application/xml; qs=0.9", MediaType.APPLICATION_JSON })public String sayXMLHello() {

return "<?xml version=\"1.0\"?>" + "<hello> Hello Jersey" + "</hello>";}

}

Resources

Dependency

Injection

HTTP Method Binding

Page 10: JAX-RS 2.0 and OData

Web Deployment Descriptor

<web-app id="WebApp_ID" version="2.4"xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-

app_2_4.xsd"><display-name>JAXRS_REST_WebServices</display-name>

<servlet><servlet-name>Jersey REST Service</servlet-name><servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class><init-param>

<param-name>javax.ws.rs.Application</param-name><param-value>com.anil.jaxb.resource.config.ApplicationConfigSetter</

param-value></init-param><load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping><servlet-name>Jersey REST Service</servlet-name><url-pattern>/</url-pattern>

</servlet-mapping>

</web-app>

There are various ways in which we can have Jersey discover the resources to be deloyed.

For simple deployments, no web.xml is needed at all. Instead, an @ApplicationPath annotation can be used to annotate the user defined application class and specify the the base resource URI of all application resources.

Page 11: JAX-RS 2.0 and OData

Basic Jersey Client

/** * This method is used to test get/delete request for an employee to the * REST API API * * @throws IOException */@Testpublic void testDeleteEmployeeRequest() throws IOException {

WebTarget webResource = this.client.target(getBaseURI()).path("rest/employee/3");

// Register the authentication to be used for logging in the web// applicationwebResource.configuration().register(

new HttpBasicAuthFilter("tomcat", "tomcat"));

String getResponse = webResource.request(MediaType.APPLICATION_XML).get(String.class);

String deleteResponse = webResource.request(MediaType.APPLICATION_XML).delete(String.class);

System.out.println("The response received from get is: " + getResponse);System.out.println("The response received from delete is: "

+ deleteResponse);}

Page 12: JAX-RS 2.0 and OData

Web Service Security

Since REST web services are essentially HTTP resources, they can be protected using the Java EE web authentication and authorization mechanism using elements in web.xml file.

<!-- The web resources with root /rest are protected --><security-constraint>

<web-resource-collection><web-resource-name>REST</web-resource-name><url-pattern>/rest/employee/*</url-pattern>

</web-resource-collection><auth-constraint>

<!-- Use the tomcat-users.xml for authentication --><role-name>tomcat</role-name>

</auth-constraint></security-constraint>

<!-- Define the Login Configuration for this Application --><login-config>

<auth-method>BASIC</auth-method><realm-name>UserDatabaseRealm</realm-name>

</login-config>

<!-- Security roles referenced by this web application --><security-role>

<description>The unlimited role allowed to login to the application.</description>

<role-name>tomcat</role-name></security-role>

Page 13: JAX-RS 2.0 and OData

Sub-resource Locators

We can delegate the handling of request to sub resources by using methods annotated with @Path BUT not annotated with resource method designators such as @GET or @POST.

Note that the runtime will not manage the life-cycle or perform any field injection onto instances returned from sub-resource locator methods.

However, sub-resources support method injection.@Path("rest")public class RootResource {

.............@Path("employee")public EmployeeResource getEmployeeResource() {

this.request.setAttribute("test", "Memory");EmployeeResource returnResource = new EmployeeResource();returnResource.setContext(this.secContext);return returnResource;

}}

Page 14: JAX-RS 2.0 and OData

Exceptions, URIBuilder, JAXB Based JSON support

JAX-RS provides exceptions to be thrown which match to HTTP error codes; examples include javax.ws.rs.NotFoundException, javax.ws.rs.ServerErrorException

The JAX-RS runtime provides URIBuilder class which takes care of specifics like encoding etc which you would need to otherwise do manually for java.net.URI class.

JAXB/JSON support is provided by using custom Message readers and writers.

@Produces(MediaType.APPLICATION_XML)

public Response insertEmployee(final Employee employee,

@Context UriInfo uriInfo) {...........}

Custom Serialization for JAXB

Page 15: JAX-RS 2.0 and OData

Injecting Types

We can define fields/method params etc to be injected with object of the described type by the JAX-RS runtime.

Injection can be performed on fields, constructor parameters, resource/sub-resource/sub-resource locator method parameters and bean setter methods.

For JAX-RS 1.1, @Context annotation was used to indicate injectables to JAX-RS runtime.

JAX-RS 2.0 has integrated with JSR-330 (CDI) and Jersey supports CDI using HK2. You can use @Context or @Inject though @Context is still preferred.

The proposal for this area is not finalized yet in JAX-RS 2.0 specifications

Page 16: JAX-RS 2.0 and OData

JAX-RS 2.0 features

Client API Filters & handlers

Asynchronous

Processing

Validation (JSR-349)

Hypermedia

CDI (JSR-330)

Server Side

Connection

Negotiation

Page 17: JAX-RS 2.0 and OData

Client API

The JAX-RS 1.1 specifications was focussed on server side and there was no client API.

Need for a standard to also share server side API(readers/writer) and encapsulate boiler plate codeClient

FactoryClient

Target

Request Builder

Invocation

Response

Configuration

Page 18: JAX-RS 2.0 and OData

Client API

Create a new client (This is heavy!!)this.client = ClientFactory.newClient();

Use builder pattern to invoke server resources – supports adding query params, target entities etc.

Close the client after use.

WebTarget webResource = this.client.target(getBaseURI()).path("rest/employee");// Register the authentication to be used for logging in the web// applicationwebResource.configuration().register(new HttpBasicAuthFilter("tomcat", "tomcat"));

Response response = webResource.request(MediaType.APPLICATION_XML).put(Entity.entity(employeeToAdd, MediaType.APPLICATION_XML),Response.class);

Page 19: JAX-RS 2.0 and OData

Client API

Support for generic invocation using command pattern for batch processing

Invocation invGoodRequest = this.client.target(getBaseURI()).path("rest/employee").request(MediaType.APPLICATION_XML).buildPut(Entity.entity(inputXMLBuilder.toString(),

MediaType.APPLICATION_XML));

invGoodRequest.configuration().register(new HttpBasicAuthFilter("tomcat", "tomcat"));

Collection<Invocation> invCollection = Arrays.asList(invGoodRequest,invBadRequest);

// Execute the invocation as a batch processfor (Invocation currentInvocation : invCollection) {

// By default invoke() returns a response but we also have an// overloaded method that takes the target class as parameterResponse response = currentInvocation.invoke();

}

Page 20: JAX-RS 2.0 and OData

Filters and Handlers

Message request pre-processing and response post-processing via well-defined extension points on the client and server side.

Use cases – logging, stream marshalling(Gzip etc), security Filters

Each filter can decide to continue or break the chain Filters in the filter chain are ordered according to their binding

priority The binding priority is an annotation that specifies an integer

based priority You can match what filters are applied to what resources –

default is global Do not directly invoke the next filter in the chain – hence is

called Non wrapping filter chain Filters implementing this interface must be annotated with

@Provider to be discovered by the JAX-RS runtime

Page 21: JAX-RS 2.0 and OData

Filters and Handlers@Provider@Logging@BindingPriority(1)public class LoggingFilter implements ContainerRequestFilter,

ContainerResponseFilter {private static Logger logger = LoggerFactory.getLogger(LoggingFilter.class);

/* * @see * javax.ws.rs.container.ContainerResponseFilter#filter(javax.ws.rs.container * .ContainerRequestContext, javax.ws.rs.container.ContainerResponseContext) */@Overridepublic void filter(ContainerRequestContext reqContext,

ContainerResponseContext responseContext) throws IOException {logger.info("POST request filter for server and the response entity class

is: "+ responseContext.getEntity().getClass().getCanonicalName());

}/** @see * javax.ws.rs.container.ContainerRequestFilter#filter(javax.ws.rs.container * .ContainerRequestContext) */@Overridepublic void filter(ContainerRequestContext reqContext) throws IOException {

logger.info("PRE request filter for server: "+ reqContext.getRequest().toString());

}}

Page 22: JAX-RS 2.0 and OData

Filters and Handlers

@Target({ ElementType.TYPE, ElementType.METHOD })@Retention(value = RetentionPolicy.RUNTIME)@NameBindingpublic @interface Logging {

}

@GET@Produces({ "application/xml; qs=0.9", MediaType.APPLICATION_JSON })@Loggingpublic String sayXMLHello() {

return "<?xml version=\"1.0\"?>" + "<hello> Hello Jersey" + "</hello>";

}

Page 23: JAX-RS 2.0 and OData

Filters and Handlers

Handlers are wrapping i.e. It directly invokes the next handler in the handler chain

Typically used for message data marshalling and un-marshalling

By default handlers are global but mechanism is provided for static(@NameBinding) as well as dynamic binding(DynamicBinding interface) of a filter or handler to a particular resource or resource method

Typically used to say compress streams API still work in progress

Page 24: JAX-RS 2.0 and OData

Asynchronous Messaging

Server API support Execute long running server processes Frees up container threads to service other

requests By default remain suspended till the server

event completes Resume operation once the server event is

generated Client API support

Asynchronous request invocation API

Page 25: JAX-RS 2.0 and OData

Asynchronous Messaging - Serverpublic static final String NOTIFICATION_RESPONSE = "Hello async world!";private static final Logger LOGGER = LoggerFactory.getLogger(HelloResource.class.getName());private static final int SLEEP_TIME_IN_MILLIS = 1000;private static final ExecutorService TASK_EXECUTOR = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("long-running-resource-executor-%d").build());private static int count = 0;

/** * Asyc method server support * * @param asyncResponse */@Path("async")@GETpublic void longGet(@Suspended final AsyncResponse asyncResponse) {

TASK_EXECUTOR.submit(new Runnable() {

@Overridepublic void run() {

try {Thread.sleep(SLEEP_TIME_IN_MILLIS);LOGGER.debug("Received request for async processing: "

+ HelloResource.count++);} catch (InterruptedException ex) {

LOGGER.error("Response processing interrupted", ex);}asyncResponse.resume(NOTIFICATION_RESPONSE);

}});

}

Page 26: JAX-RS 2.0 and OData

Asynchronous Messaging - Client@Testpublic void testAsyncClientRequests() throws InterruptedException {

Client client = ClientFactory.newClient();WebTarget webResource = client.target(getBaseURI()).path("hello/async");final int REQUESTS = 10;final CountDownLatch latch = new CountDownLatch(REQUESTS);for (int i = 0; i < REQUESTS; i++) {

webResource.request(MediaType.TEXT_PLAIN).async().get(new InvocationCallback<Response>() {

@Overridepublic void completed(Response response) {

try {final String result = response

.readEntity(String.class);Assert.assertEquals("Hello Jersey", result);

} finally {latch.countDown();

}}@Overridepublic void failed(ClientException exception) {

System.out.println("Exception while invocation: "+ exception.getMessage());

latch.countDown();}

});}

}

Page 27: JAX-RS 2.0 and OData

Validation

Services need to validate data before processing Bean Validation is a Java specification which:

provides a unified way of declaring and defining constraints on an object model.

defines a runtime engine to validate objects Already have JSR 349: Bean Validation 1.1 which

needs to be integrated to JAX-RS Support for constraint annotations in

Methods (response entities) Fields & properties Parameters (in request entity) Resource classes

Page 28: JAX-RS 2.0 and OData

Validation

@POST@Consumes(MediaType.APPLICATION_FORM_URLENCODED)@Produces(MediaType.APPLICATION_XML)public String searchEmployee(@NotNull @FormParam("name") String name,

@OrderNumber @FormParam(“orderNumber") String orderNumber,@FormParam(“department") String department) {

@Constraint(validatedBy = OrderNumberValidator.class) @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) @Retention(RUNTIME) public @interface OrderNumber {

String message() default "{custom message}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {};

}

public class OrderNumberValidator implements ConstraintValidator<OrderNumber, String> {/** Configure the constraint validator based on the elements specified at the

time it was defined. */ public void initialize(OrderNumber constraint) { ... } /** Validate a specified value. returns false if the specified value does not conform to the definition */ public boolean isValid(String value, ConstraintValidatorContext context) {

//validate value }

}

Default

Custom

Page 29: JAX-RS 2.0 and OData

HyperMedia

Use HATEOAS (Hypermedia As The Engine Of App State) REST principle

Structural links are used to avoid sending a complete representation of a resource and enable lazy loading. The clients can follow these type of links to retrieve the "pieces" they need.

Transitional link is used to update the state of a resource and is typically identified by a "rel" attribute.

Structural links are normally in the entity; transitional links could be in link headers or the entity.

Support transitional links only

Page 30: JAX-RS 2.0 and OData

Improved Connection Negotiation This would allow a server to specify a

preferred MIME type if the client does not care about it.

An unspecified value takes the default value of 1

The rule says "application/json" will be served as the preferred type if there is no Accept header from the client.

@GET@Produces({ "application/xml; qs=0.9", MediaType.APPLICATION_JSON })@Loggingpublic String sayXMLHello() {return "<?xml version=\"1.0\"?>" + "<hello> Hello Jersey" + "</hello>";}

Page 31: JAX-RS 2.0 and OData

WADL/WSDL 2.0

The Web Application Description Language (WADL) is a machine-readable XML description of HTTP-based web applications (typically REST web services).

REST doesn’t really require description; follow links

Additionally because the WADL generates machine readable code, it would break when the interface changes – tight coupling

WSDL 2.0 adds supports for REST services Sample WADL available at

http://odata4j-sample.appspot.com/datastore.svc/application.wadl

Page 32: JAX-RS 2.0 and OData

Odata - Introduction

Open Data Protocol (OData) is a Web protocol for querying and updating data

Based on Web technologies such as HTTP, Atom Publishing Protocol (AtomPub) and JSON

The OData Protocol is different from other REST-based web service approaches in that it provides a uniform way to describe both the data and the data model

The current version of Odata specifications is version 3; however the java implementation for OData (called OData4j) supports version 2

OData4j will move to version 3 after release 1.0; currently at 0.7

Page 33: JAX-RS 2.0 and OData

ATOM

Atom is an XML-based document format that describes lists of related information known as "feeds“

Feeds are composed of a number of items, known as "entries", each with an extensible set of attached metadata

The "atom:entry" element represents an individual entry, acting as a container for metadata and data associated with the entry.

It can be child of an atom:feed element OR it can be the top level element

Page 34: JAX-RS 2.0 and OData

ATOM Example

<?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom">

<title>Example Feed</title> <link href="http://example.org/"/> <updated>2003-12-13T18:30:02Z</updated> <author>

<name>John Doe</name> </author> <id>urn:uuid:60a76c80-d399-11d9-b93C-

0003939e0af6</id> <entry> <title>Atom-Powered Robots Run Amok</title> <link

href="http://example.org/2003/12/13/atom03"/> <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-

80da344efa6a</id> <updated>2003-12-13T18:30:02Z</updated>

<summary>Some text.</summary> </entry>

</feed>

XML Namespace

ATOM feedMetadat

a

Entry

Page 35: JAX-RS 2.0 and OData

Odata Structure

Feed Metadata (title, id, updated etc) Collection of entries

Entry Properties (primitives & complex) Links (related entries and related feeds)

Service document that lists all the top level feeds – usually serviced by the service root URI endpoint

OData services can also expose Service Operations, which are simple, service-specific functions that accept input parameters and return entries or complex/primitive values.

The data is usually serviced by a producer who can expose data from relational databases, web services etc

The producer takes care of transformation between EDM and the underlying data access layer

Page 36: JAX-RS 2.0 and OData

EDM

Entity Data Model (EDM) - is the underlying abstract data model used by OData services to formalize the description of the resources it exposes

All data services may also expose a Service Metadata Document that describes the data model (i.e. structure and organization of all the resources) exposed as HTTP endpoints by the service.

Metadata is available at the endpoint using convention $metadata

The central concepts in the EDM are entities and associations.

EDM is defined using an XML language called conceptual schema definition language (CSDL)

Page 37: JAX-RS 2.0 and OData

EDM

EntityTypes – data model definitions(for example customer, product etc)

Entities – instances of Entity types with a key and structured type consisting of list of properties

Complex Types - structured types also consisting of a list of properties but with no key

Entity Key – primary key either single or composite Associations - define the relationship between two

or more Entity Types Navigation Properties - special properties on Entity

Types which are bound to a specific association and can be used to refer to associations of an entity

Page 38: JAX-RS 2.0 and OData

OData Producers

Create a factory that OData4j can use to initialize the producer

OData4j currently supports JPAProducer & InMemoryProducer. It also plans to support JDBCProducer in the near future.

You can write your own producer and it has to implement the org.odata4j.producer.ODataProducer interface.

Page 39: JAX-RS 2.0 and OData

Registering Producer

public class ODataJPAProducerFactory implements ODataProducerFactory {

private String persistenceUnitName = "odataJPAService";private Strig namespace = "odataJPA";private int maxResults = 50;

@Overridepublic ODataProducer create(Properties arg0) {

EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnitName);

JPAProducer producer = new JPAProducer(emf, namespace, maxResults);return producer;}

}<servlet>

<servlet-name>OData</servlet-name><servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-

class><init-param>

<param-name>javax.ws.rs.Application</param-name><param-value>org.odata4j.jersey.producer.resources.ODataApplication</

param-value></init-param><init-param>

<param-name>odata4j.producerfactory</param-name><param-value>com.synerzip.odata.producer.ODataJPAProducerFactory</

param-value></init-param><load-on-startup>1</load-on-startup>

</servlet>

Inject Producer

Register Producer

Page 40: JAX-RS 2.0 and OData

URI Convention

URI Used for Example

$links Get all associations between entries

http://localhost:8080/odata_example/odatajpa.svc/SupplierParts(1L)/$links/part

$orderby

Order data based on desc or asc (default) options

http://localhost:8080/odata_example/odatajpa.svc/SupplierParts?$orderby=quantity desc

$top Return first N items of the set

http://localhost:8080/odata_example/odatajpa.svc/SupplierParts?$orderby=quantity desc&$top=4

$skip Skip the first N records of the entity set and get next

http://localhost:8080/odata_example/odatajpa.svc/SupplierParts?$skip=2&$top=2

$filter Select only subset of entities that match the predicates provided – rich set of operators and functions

http://localhost:8080/odata_example/odatajpa.svc/SupplierParts?$filter=(quantity gt 200 and quantity lt 300) or shipperId eq 10

Page 41: JAX-RS 2.0 and OData

URI Convention

URI Used for Example

$expand

Eagerly load associations inline

http://localhost:8080/odata_example/odatajpa.svc/Supplier?$expand=supplierParts

$format

Specify what media type to be used for response(Atom/Xml/Json)

http://localhost:8080/odata_example/odatajpa.svc/Supplier?$expand=supplierParts&$format=Json

$select Return only subset of properties

http://localhost:8080/odata_example/odatajpa.svc/Supplier?$select=supplierCity, supplierId

$inlinecount

Response should include the count on entities after applying $filter. Valid values are allpages/none

http://localhost:8080/odata_example/odatajpa.svc/Supplier?$inlinecount=allpages<m:count>16</m:count>

Page 42: JAX-RS 2.0 and OData

CUD Operations using Consumer// create the new productOEntity newSupplier = consumer.createEntity("Supplier")

.properties(OProperties.string("supplierId", "S200"))

.properties(OProperties.string("supplierName", "Smith A"))

.properties(OProperties.string("supplierCity", "Boston"))

.properties(OProperties.string("supplierState", "MA"))

.properties(OProperties.decimal("supplierStatus", 20L))

.execute();

// update the newly created productconsumer.updateEntity(newSupplier)

.properties(OProperties.string("supplierName", "Carl A"))

.execute();

report("newSupplier name after update: "+ consumer.getEntity("Supplier", "S200").execute().getProperty("supplierName").getValue());

// update the newly create product using mergeconsumer.mergeEntity("Supplier", "S101")

.properties(OProperties.string("supplierName", "Zack A"))

.execute();

report("newPart rating after merge: "+ consumer.getEntity("Supplier", "S101").execute().getProperty("supplierName").getValue());

// clean up, delete the new productconsumer.deleteEntity("Supplier", "S200").execute();

Page 43: JAX-RS 2.0 and OData

Batch Operations

Odata supports executing multiple operations sent in a single HTTP request through the use of Batching

The batch requests can be sent as POST with the path containing $batch

OData Batch Request is represented as a Multipart MIME v1.0 message

The OData4j implementation is inefficient in the sense that it executes the individual batch items in a separate transaction

Page 44: JAX-RS 2.0 and OData

Questions?