Author: mibo
Date: Tue Apr 28 11:20:40 2015
New Revision: 1676481

URL: http://svn.apache.org/r1676481
Log:
Add read tutorial

Added:
    olingo/site/trunk/content/doc/odata4/tutorials/read/tutorial_read.md

Added: olingo/site/trunk/content/doc/odata4/tutorials/read/tutorial_read.md
URL: 
http://svn.apache.org/viewvc/olingo/site/trunk/content/doc/odata4/tutorials/read/tutorial_read.md?rev=1676481&view=auto
==============================================================================
--- olingo/site/trunk/content/doc/odata4/tutorials/read/tutorial_read.md (added)
+++ olingo/site/trunk/content/doc/odata4/tutorials/read/tutorial_read.md Tue 
Apr 28 11:20:40 2015
@@ -0,0 +1,989 @@
+Title:
+Notice:    Licensed to the Apache Software Foundation (ASF) under one
+           or more contributor license agreements.  See the NOTICE file
+           distributed with this work for additional information
+           regarding copyright ownership.  The ASF licenses this file
+           to you under the Apache License, Version 2.0 (the
+           "License"); you may not use this file except in compliance
+           with the License.  You may obtain a copy of the License at
+           .
+             http://www.apache.org/licenses/LICENSE-2.0
+           .
+           Unless required by applicable law or agreed to in writing,
+           software distributed under the License is distributed on an
+           "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+           KIND, either express or implied.  See the License for the
+           specific language governing permissions and limitations
+           under the License.
+
+# How to build an OData Service with Olingo V4
+
+This tutorial guides you through the steps required to write an OData Service 
based on the Olingo OData 4.0 Library for Java.
+
+We will create a Web Application and deploy it on a local Tomcat server.
+Afterwards, the OData service can be invoked from a browser and it will 
provide the data according to the OData V4 specification.
+This tutorial is kept as minimalistic as possible, in order to fully 
concentrate on the implementation of the service.
+For example, only READ scenario is covered in this tutorial, whereas creation, 
modification and deletion will be covered in the subsequent tutorial.
+
+**Scenario**
+
+The OData service that we’re going to create will implement the following 
model:
+
+![datamodel](model1.png "The OData model")
+
+The service will display a list of products and a few properties that describe 
each product.
+This data model will be enhanced in the subsequent tutorials in order to 
display Categories and to support navigation from a product to its Category.
+
+
+**Goal**
+
+
+We will be dealing with 3 java classes and the web.xml descriptor file.
+Furthermore, for building with maven, we’ll edit the pom.xml file.
+
+This is how our working directory in Eclipse will look like:
+
+
+![projectLayout](EclipseProjectTree.png "The project layout")
+
+
+At the end of this tutorial, you’ll have written an OData service and 
you’ll be able to invoke the following URL in a browser:
+
+http://localhost:8080/DemoService/DemoService.svc/Products
+
+And the browser will display the following little collection of data:
+![productCollection](productCollectionPayload.png "The product collection")
+
+
+```json
+{"@odata.context":"$metadata#Products","value":[{"ID":1,"Name":"Notebook Basic 
15","Description":"Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 
40GB"},{"ID":2,"Name":"1UMTS PDA","Description":"Ultrafast 3G UMTS/HSDPA Pocket 
PC, supports GSM network"},{"ID":3,"Name":"Ergo Screen","Description":"17 
Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960"}]}
+```
+
+
+**Table of Contents**
+
+1. Prerequisites
+2. Preparation
+3. Create Project
+  * Create Project
+  * Edit pom file
+  * Check build path
+  * Build the project
+4. Implementation - Read scenario to request the EntitySet “Products”
+  1. Declare the metadata
+  2. Provide the data
+  3. Web application implementation
+5. Run the service
+  * Run with Eclipse
+  * The Service URLs
+6. Summary
+
+___
+
+# 1. Prerequisites
+
+In order to follow this tutorial, you should have
+
+* Basic knowledge about OData and OData V4
+* Knowledge about Java as programming language
+* Optional: knowledge about developing web applications
+* Optional: knowledge about building with Maven
+
+___
+
+# 2. Preparation
+
+Before starting off with the creation of our OData service, we need to prepare 
for the following needs:
+1. An IDE for writing the Java code
+2. A builder to build the .war file, which will be deployed on server
+3. A web server to run our web application / OData service
+
+
+I recommend using Eclipse for all 3 needs, as it is the easiest approach.
+This means, you should install the pre-packed Eclipse distribution called 
“Eclipse IDE for Java EE developers” and which can be found here: 
http://www.eclipse.org/downloads/
+
+![eclipseDownload](eclipseDownload.png "The Eclipse EE download")
+
+This Eclipse package contains an embedded server and also an integrated Maven 
builder.
+
+
+
+---
+
+# 3. Create Project
+
+The recommended procedure to create a project is to use Maven, because it 
offers an archetype for generating the project skeleton.
+Furthermore, using Maven is convenient for managing the build dependencies.
+The description within this section is based on an Eclipse installation that 
contains the Maven integration.
+
+
+
+**Create Project using the maven archetype “webapp”**
+
+Within Eclipse, open the Maven Project wizard via
+*File -> New -> other -> Maven -> Maven Project*
+
+On the second wizard page, choose  the archetype: maven-archetype-webapp
+
+![mavenArchetype](mavenArchetype.png "The Maven Archetype")
+
+On the next page, enter the following information:
+- Project Name: DemoService
+- Groupd Id: my.group.id
+- Artifact Id: DemoService
+- Version: 0.0.1
+- Package: myservice.mynamespace.service
+
+> Note:
+> If you’re using this wizard for the first time, it might take some time, 
as maven needs to download the archetype itself to your local maven-repo.
+
+After finishing the wizard, the next step is to edit the pom.xml file.
+
+
+**Edit pom file**
+
+In our project, we’ll be using several libraries, e.g. the Olingo libraries.
+In the pom.xml file, we specify the dependencies and Maven will take care to 
download them to our local maven repository.
+Furthermore, the pom.xml file tells Maven which output we want to have as 
result of our build. In our case, this is a war file.
+
+In our example, the pom.xml file looks as follows:
+
+```xml
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+       <modelVersion>4.0.0</modelVersion>
+       <groupId>my.group.id</groupId>
+       <artifactId>DemoService</artifactId>
+       <packaging>war</packaging>
+       <version>0.0.1</version>
+
+       <name>DemoService Maven Webapp</name>
+
+       <properties>
+               <javax.version>2.5</javax.version>
+               <odata.version>4.0.0-beta-02</odata.version>
+               <slf4j.version>1.7.7</slf4j.version>
+       </properties>
+
+       <dependencies>
+               <dependency>
+                       <groupId>javax.servlet</groupId>
+                       <artifactId>servlet-api</artifactId>
+                       <version>${javax.version}</version>
+                       <scope>provided</scope>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.apache.olingo</groupId>
+                       <artifactId>odata-server-api</artifactId>
+                       <version>${odata.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.olingo</groupId>
+                       <artifactId>odata-server-core</artifactId>
+                       <version>${odata.version}</version>
+                       <scope>runtime</scope>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.apache.olingo</groupId>
+                       <artifactId>odata-commons-api</artifactId>
+                       <version>${odata.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.olingo</groupId>
+                       <artifactId>odata-commons-core</artifactId>
+                       <version>${odata.version}</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.slf4j</groupId>
+                       <artifactId>slf4j-simple</artifactId>
+                       <version>${slf4j.version}</version>
+                       <scope>runtime</scope>
+               </dependency>
+       </dependencies>
+</project>
+```
+
+**Check Java build path**
+
+In order to check the Build path settings, open the context menu on the 
project and choose
+*Build Path -> Configure Build Path…*
+
+![ConfigureBuildPathAction](ConfigureBuildPathAction.png "Open the Configure 
BuildPath action")
+
+Select the *Source* tab.
+You might see that the source folder *src/main/java* is configured, but marked 
with an error marker.
+
+![ConfigureBuildPathErr](ConfigureBuildPathErr.png "Configure BuildPath has 
errors")
+
+The reason is that it is missing on file system.
+So the solution is to create the required folder in Eclipse.
+
+![createFolder](createFolder.png "Create new java folder")
+
+Afterwards, open the Build Path dialog again.
+The second error might be about missing test source folder.
+Since we don’t need it for our tutorial, we remove it from the build path.
+
+![ConfigureBuildPathOK](ConfigureBuildPathOK.png "Configure Build Path is OK 
now")
+
+
+**Build the project**
+
+Although the project doesn’t contain any source files yet, let’s perform 
our first Maven build, in order to check if there are any problems.
+
+From context menu on project node, chose *Run As -> maven build*
+If you’ve never executed the build before, Maven asks you to specify at 
least one goal.
+Enter the usual goals “clean install” and press “Run”
+
+![mavenBuild](mavenBuild.png "The Maven build dialog")
+
+The log output is provided in the Eclipse Console view.
+You should check it for the output “Build Success”
+
+> Note:
+> It might be the case that maven provides an error marker right from the 
beginning.
+> In such case it helps to update your Project:
+> From context menu on project node, choose Maven -> update Project -> <your 
project>
+
+___
+
+# 4. Implementation
+
+The implementation of an OData service based on Olingo server library can be 
grouped in the following steps:  
+
+  * Declaring the metadata of the service
+  * Handle service requests  
+
+Furthermore, since our example service has to run on a web server, we have to 
create some code which allows to call our service in a web application:  
+
+  * Web application implementation
+
+The following section will guide you through every step in detail.
+
+
+## 4.1. Declare the metadata
+
+### 4.1.1. Background
+
+According to the OData specification, an OData service has to declare its 
structure in the so-called *metadata document*.
+This document defines the contract, such that the user of the service knows 
which requests can be executed, the structure of the result and how the service 
can be navigated.
+
+The metadata document can be invoked via the following URI:
+
+```html
+ <serviceroot>/$metadata
+```
+
+Furthermore, OData specifies the usage of the so-called service document
+Here, the user can see which Entity Collections are offered by an OData 
service.
+
+The service document can be invoked via the following URI:
+
+```html
+ <serviceroot>/
+```
+
+The information that is given by these 2 URIs, has to be implemented in the 
service code.
+Olingo provides API for it and we’ll use it in the implementation of our 
*EdmProvider.*
+
+
+### 4.1.2. Create class
+
+Create package *myservice.mynamespace.service*  
+Create class *DemoEdmProvider* and specify the superclass 
*org.apache.olingo.server.api.edm.provider.EdmProvider*
+
+Note: **edm** is the abbreviation for **Entity Data Model**.  
+Accordingly, we understand that the *EdmProvider* is supposed to provide 
static descriptive information.
+
+The Entity Model of the service can be defined in the EDM Provider. The EDM 
model basically defines the available EntityTypes and the relation between the 
entities. An EntityType consists of primitive, complex or navigation 
properties. The model can be invoked with the metadata document request.
+
+As we can see, the Olingo server API provides one package that contains 
interfaces for the description of the metadata:
+
+![edmPackage](edmPackage.png "The edm package")
+
+Some of these interfaces are going to be used in the following sections.
+Note:
+You can find the Javadoc here: 
http://olingo.apache.org/javadoc/odata4/index.html
+
+
+### 4.1.3. Implement the required methods
+
+
+The base class *EdmProvider* provides methods for declaring the metadata of 
all OData elements.
+
+For example:
+* The entries that are displayed in the service document are provided by the 
method
+*getEntityContainerInfo()*
+* The structure of EntityTypes is declared in the method *getEntityType()*
+
+In our simple example, we implement the minimum amount of methods, required to 
run a meaningful OData service.  
+These are:
+
+* **_getEntityType()_**  
+       Here we declare the EntityType “Product” and a few of its properties
+* **_getEntitySet()_**  
+       Here we state that the list of products can be called via the EntitySet 
“Products”
+* **_getEntityContainer()_**  
+       Here we provide a Container element that is necessary to host the 
EntitySet.
+* **_getSchemas()_**  
+       The Schema is the root element to carry the elements.
+* **_getEntityContainerInfo()_**
+       Information about the EntityContainer to be displayed in the Service 
Document
+
+In Eclipse, in order to select the methods to override, right click into the 
Java editor and from the context menu choose *Source -> Override/Implement 
Methods…*
+Select the mentioned methods and press OK.
+
+![overrideMethods](overrideMethods.png "The dialog for overriding superclass 
methods in Eclipse")
+
+Let’s have a closer look at the methods in detail.
+
+First, we need to declare some constants, to be used in below code
+
+```java
+// Service Namespace
+public static final String NAMESPACE = "com.example.model";
+
+// EDM Container
+public static final String CONTAINER_NAME = "Container";
+public static final FullQualifiedName CONTAINER = new 
FullQualifiedName(NAMESPACE, CONTAINER_NAME);
+
+// Entity Types Names
+public static final String ET_PRODUCT_NAME = "Product";
+public static final FullQualifiedName ET_PRODUCT_FQN = new 
FullQualifiedName(NAMESPACE, ET_PRODUCT_NAME);
+
+// Entity Set Names
+public static final String ES_PRODUCTS_NAME = "Products";
+```
+
+
+**_getEntityType()_**
+
+In our example service, we want to provide a list of products to users who 
call the OData service.
+The user of our service, for example an app-developer, will ask himself: how 
does such a "product" entry look like? How is it structured? Which information 
about a product is provided? For example, the name of it? And which data types 
can be expected from these properties?  
+Such information is provided by the _EdmProvider_.
+
+In our example service, for modelling the _EntityType_, we have to provide the 
following metadata:
+
+The name of the EntityType: “Product”  
+The properties: name and type and additional info, e.g. “ID” of type 
“edm.int32”  
+Which of the properties is the “key” property: a reference to the “ID” 
property.  
+
+
+```java
+@Override
+public EntityType getEntityType(FullQualifiedName entityTypeName) throws 
ODataException {
+
+       // this method is called for one of the EntityTypes that are configured 
in the Schema
+       if(entityTypeName.equals(ET_PRODUCT_FQN)){
+
+               //create EntityType properties
+               Property id = new 
Property().setName("ID").setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
+               Property name = new 
Property().setName("Name").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
+               Property  description = new 
Property().setName("Description").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
+
+               // create PropertyRef for Key element
+               PropertyRef propertyRef = new PropertyRef();
+               propertyRef.setPropertyName("ID");
+
+               // configure EntityType
+               EntityType entityType = new EntityType();
+               entityType.setName(ET_PRODUCT_NAME);
+               entityType.setProperties(Arrays.asList(id, name , description));
+               entityType.setKey(Arrays.asList(propertyRef));
+
+               return entityType;
+       }
+
+       return null;
+}
+```
+
+
+**_getEntitySet()_**
+
+The procedure for declaring the _EntitySets_ is similar.
+An _EntitySet_ is a crucial resource, when an OData service is used to request 
data.
+In our example, we’ll invoke the following URL, which we expect to provide 
us a list of products:
+```html
+http://localhost:8080/DemoService/DemoServlet.svc/Products
+```
+When declaring an _EntitySet_, we need to define the type of entries which are 
contained in the list. Such type is an _EntityType_.
+In our example, we set our previously created _EntityType_, which is referred 
by a _FullQualifiedName_.
+
+```java
+@Override
+public EntitySet getEntitySet(FullQualifiedName entityContainer, String 
entitySetName) throws ODataException {
+
+       if(entityContainer.equals(CONTAINER)){
+               if(entitySetName.equals(ES_PRODUCTS_NAME)){
+                       EntitySet entitySet = new EntitySet();
+                       entitySet.setName(ES_PRODUCTS_NAME);
+                       entitySet.setType(ET_PRODUCT_FQN);
+
+                       return entitySet;
+               }
+       }
+
+       return null;
+}
+```
+
+
+**_getEntityContainer()_**
+
+In order to provide data, our OData service needs an _EntityContainer_ that 
carries the _EntitySets_.
+In our example, we have only one _EntitySet_, so we create one 
_EntityContainer_ and set our _EntitySet_.
+
+```java
+@Override
+public EntityContainer getEntityContainer() throws ODataException {
+
+       // create EntitySets
+       List<EntitySet> entitySets = new ArrayList<EntitySet>();
+       entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME));
+
+       // create EntityContainer
+       EntityContainer entityContainer = new EntityContainer();
+       entityContainer.setName(CONTAINER_NAME);
+       entityContainer.setEntitySets(entitySets);
+
+       return entityContainer;
+}
+```
+
+
+**_getSchemas()_**
+
+Up to this point, we have declared the type of our data (_EntityType_) and our 
list (_EntitySet_), and we’ve put it into a container (_EntityContainer_).  
+Now we’re required to put all these elements into a _Schema_.  
+While the model of an OData service can have several schemas, in most cases 
there will probably be only one schema.  
+So, in our example, we create a list of schemas, where we add one new _Schema_ 
object.  
+The schema is configured with a _Namespace_, which serves to uniquely identify 
all elements.  
+Then our elements are added to the Schema.
+
+```java
+@Override
+public List<Schema> getSchemas() throws ODataException {
+
+       // create Schema
+       Schema schema = new Schema();
+       schema.setNamespace(NAMESPACE);
+
+       // add EntityTypes
+       List<EntityType> entityTypes = new ArrayList<EntityType>();
+       entityTypes.add(getEntityType(ET_PRODUCT_FQN));
+       schema.setEntityTypes(entityTypes);
+
+       // add EntityContainer
+       schema.setEntityContainer(getEntityContainer());
+
+       // finally
+       List<Schema> schemas = new ArrayList<Schema>();
+       schemas.add(schema);
+
+       return schemas;
+}
+```
+
+
+**_getEntityContainerInfo()_**
+
+```java
+@Override
+public EntityContainerInfo getEntityContainerInfo(FullQualifiedName 
entityContainerName) throws ODataException {
+
+// This method is invoked when displaying the service document at e.g. 
http://localhost:8080/DemoService/DemoService.svc
+       if(entityContainerName == null || 
entityContainerName.equals(CONTAINER)){
+               EntityContainerInfo entityContainerInfo = new 
EntityContainerInfo();
+               entityContainerInfo.setContainerName(CONTAINER);
+               return entityContainerInfo;
+       }
+
+       return null;
+}
+```
+
+**Summary:**  
+We have created a class that declares the metadata of our OData service.
+We have declared the main elements of an OData service: _EntityType_, 
_EntitySet_, _EntityContainer_ and _Schema_.
+
+At runtime of an OData service, such metadata can be viewed by invoking the 
Metadata Document.
+
+In our example:
+```
+http://localhost:8080/DemoService/DemoService.svc/$metadata
+```
+
+```xml
+<?xml version='1.0' encoding='UTF-8'?>
+<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx";>
+  <edmx:DataServices>
+    <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"; 
Namespace="com.example.model">
+      <EntityType Name="Product">
+        <Key>
+          <PropertyRef Name="ID"/>
+        </Key>
+        <Property Name="ID" Type="Edm.Int32"/>
+        <Property Name="Name" Type="Edm.String"/>
+        <Property Name="Description" Type="Edm.String"/>
+      </EntityType>
+      <EntityContainer Name="Container">
+        <EntitySet Name="Products" EntityType="com.example.model.Product"/>
+      </EntityContainer>
+    </Schema>
+  </edmx:DataServices>
+</edmx:Edmx>
+```
+
+The Service Document can be invoked to view the Entity Sets, like in our 
example at
+```
+http://localhost:8080/DemoService/DemoService.svc/
+```
+
+```json
+{
+  "@odata.context" : 
"http://localhost:8080/DemoService/DemoService.svc/$metadata";,
+  "value" : [
+  {
+    "name" : "Products",
+    "url" : "Products"
+  } ]
+}
+```
+
+> Note:  
+> After implementing the _EdmProvider_, we can, as an intermediate step, 
build/deploy the service and invoke the 2 static pages:   service document and 
metadata document.  
+> If desired, you can proceed with implementing the required steps for web 
application as described in
+4.3. And run the application as described in chapter 5
+
+
+## 4.2. Provide the data
+
+After implementing the _EdmProvider_, the next step is the main task of an 
OData service: provide data.  
+In our example, we imagine that our OData service is invoked by a user who 
wants to see which products are offered by a web shop.  
+He invokes a URL and gets a list of products.  
+Providing the list of products is the task that we are going to implement in 
this chapter.
+
+The work that we have to do in this chapter can be divided into 4 tasks:
+1. Check the URI  
+    We need to identify the requested resource and have to consider Query 
Options (if available)
+2. Provide the data  
+    Based on the URI info, we have to obtain the data from our data store (can 
be e.g. a Database)
+3. Serialize the data  
+    The data has to be transformed into the required format
+4. Configure the response  
+    Since we’re implementing a “processor”, the last step is to provide 
the response object
+
+These 4 steps will be considered in the implementation of the 
_readEntityCollection()_  method.
+
+
+### 4.2.1. Background
+
+In terms of _Olingo_, while processing a service request, a Processor instance 
is invoked that is supposed to understand the (user HTTP-) request and deliver 
the desired data.  
+_Olingo_ provides API for processing different kind of service requests:  
+Such a service request can ask for a list of entities, or for one entity, or 
one property.
+
+Example:  
+In our example, we’ve stated in our metadata document that we’ll provide a 
list of “products” whenever the _EntitySet_ with name “Products” is 
invoked.  
+This means that the user of our OData service will append the _EntitySet_ name 
to the root URL of the service and then invoke the full URL.  
+This is http://localhost:8080/ExampleService1/ExampleServlet1.svc/Products
+So, whenever this URL is fired, Olingo will invoke the 
_EntityCollectionProcessor_ implementation of our OData service.
+And our _EntityCollectionProcessor_ implementation is expected to provide a 
list of products.
+
+As we’ve already mentioned, the metadata document is the contract for 
providing data.
+This means that when it comes to provide the actual data, we have to do it 
according to the specified metadata.  
+For example, the property names have to match, also the types of the 
properties, and, if specified, the length of the strings, etc
+
+
+### 4.2.2. Create class
+
+Within our package _myservice.mynamespace.service_, we create a Java class 
_DemoEntityCollectionProcessor_  that implements the interface 
_org.apache.olingo.server.api.processor.EntityCollectionProcessor_.
+
+![createJavaClass](createJavaClass.png "The Eclipse dialog for creating a Java 
class")
+
+
+### 4.2.3. Implement the required methods
+
+After creation of the Java class, we can see that there are 2 methods to be 
implemented:
+* _init()_  
+       This method is invoked by the _Olingo_ Framework, allowing us to store 
the context object
+* _readEntityCollection()_  
+    Here we have to fetch the required data and pass it back to the _Olingo_ 
FWK
+
+
+Let’s have a closer look
+
+
+**_init()_**
+
+This method is common to all processor interfaces.  
+The _Olingo_ framework initializes the processor with an instance of the 
_OData_ object.
+According to the Javadoc, this object is the “Root object for serving 
factory tasks…”
+We’ll need it later, so we store it as member variable.
+
+```java
+       public void init(OData odata, ServiceMetadata serviceMetadata) {
+               this.odata = odata;
+       }
+```
+
+Don’t forget to declare the member variable
+
+```java
+       private OData odata;
+```
+
+**_readEntityCollection()_**
+
+The _EntityCollectionProcessor_ exposes only one method:  
+_readEntityCollection()_  
+Here we have to understand that this _readEntityCollection_-method is invoked, 
when the OData service is called with an HTTP GET operation for an entity 
collection.
+
+The _readEntityCollection_ method is used to “read” the data in the 
backend (this can be e.g. a database) and to deliver it to the user who calls 
the OData service.
+
+The method signature:
+
+The “request” parameter contains raw HTTP information. It is typically 
used for creation scenario, where a request body is sent along with the request.
+
+With the second parameter, the “response” object is passed to our method 
in order to carry the response data. So here we have to set the response body, 
along with status code and content-type header.
+
+The third parameter, the “uriInfo”, contains information about the 
relevant part of the URL. This means, the segments starting after the service 
name.  
+Example:
+If the user calls the following URL:  
+http://localhost:8080/DemoService/DemoService.svc/Products  
+The _readEntityCollection_ method is invoked and the _uriInfo_ object contains 
one segment: “Products”  
+If the user calls the following URL:  
+http://localhost:8080/DemoService/DemoService.svc/Products?$filter=ID eq 1  
+Then the _readEntityCollection_ method is invoked and the _uriInfo_ contains 
the information about the entity set and furthermore the system query option 
$filter and its value.
+
+The last parameter, the “responseFormat”, contains information about the 
content type that is requested by the user.  
+This means that the user has the choice to receive the data either in XML or 
in JSON.  
+Example:  
+If the user calls the following URL:  
+http://localhost:8080/DemoService/DemoService.svc/Products?$format=application/json;odata.metadata=minimal
  
+then the content type is:  
+application/json;odata.metadata=minimal  
+which means that the payload is formatted in JSON (like it is shown in the 
introduction section of this tutorial)
+
+> Note:
+> The content type can as well be specified via the following request header  
+> Accept: application/json;odata.metadata=minimal  
+> In this case as well, our readEntityCollection() method will be called with 
the parameter responseFormat containing the content type > information.
+
+> Note:
+> If the user doesn’t specify any content type, then the default is JSON.
+
+Why is this parameter needed?  
+Because the _readEntityCollection_ method is supposed to deliver the data in 
the format that is requested by the user. We’ll use this parameter when 
creating a serializer based on it.
+
+
+The steps for implementating the method _readEntityCollection_ are:
+
+1. Which data is requested?  
+Usually, an OData service provides different _EntitySets_, so first it is 
required to identify which _EntitySet_ has been requested. This information can 
be retrieved from the _uriInfo_ object
+
+2. Fetch the data  
+As a developer of the OData service, you have to know how and where the data 
is stored. In many cases, this would be a database. At this point, you would 
connect to your database and fetch the requested data with an appropriate SQL 
statement. The data that is fetched from the data storage has to be put into an 
_EntitySet_ object.
+Note that this object has to be of type _EntitySet_, not _EdmEntitySet_  
+The package _org.apache.olingo.commons.api.data_ provides interfaces that 
describe the actual data, not the metadata.
+
+![datapackage](datapackage.png "The package containing the interfaces for 
handling runtime data")
+
+3. Transform the data  
+_Olingo_ expects from us to provide the data as low-level _InputStream_ 
object. However, _Olingo_ supports us in doing so, by providing us with a 
proper "serializer".
+So what we have to do is create the serializer based on the requested content 
type, configure it and call it.
+
+4. Configure the response  
+The response object has been passed to us in the method signature. We use it 
to set the serialized data (the _InputStream_ object).  
+Furthermore, we have to set the HTTP status code, which means that we have the 
opportunity to do proper error handling.  
+And finally we have to set the content type.
+
+```java
+public void readEntityCollection(ODataRequest request, ODataResponse response, 
UriInfo uriInfo, ContentType responseFormat)
+                     throws ODataApplicationException, SerializerException {
+
+       // 1st retrieve the requested EntitySet from the uriInfo 
(representation of the parsed URI)
+       List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+       // in our example, the first segment is the EntitySet:
+       UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) 
resourcePaths.get(0);
+       EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
+
+       // 2nd: fetch the data from backend for this requested EntitySetName 
and delivere as EntitySet
+       EntitySet entitySet = getData(edmEntitySet);
+
+       // 3rd: create a serializer based on the requested format (json)
+       ODataFormat format = ODataFormat.fromContentType(responseFormat);
+       ODataSerializer serializer = odata.createSerializer(format);
+
+       // and serialize the content: transform from the EntitySet object to 
InputStream
+       EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+       ContextURL contextUrl = 
ContextURL.with().entitySet(edmEntitySet).build();
+
+    EntityCollectionSerializerOptions opts =
+                    
EntityCollectionSerializerOptions.with().contextURL(contextUrl).build();
+       InputStream serializedContent = 
serializer.entityCollection(edmEntityType, entitySet, opts);
+
+       // 4th: configure the response object: set the body, headers and status 
code
+       response.setContent(serializedContent);
+       response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+       response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+}
+```
+
+**_getData()_**
+
+Up to now, we haven’t elaborated on fetching the actual data.
+In our tutorial, to keep the code as simple as possible, we use a little 
helper method that delivers some hardcoded entries.  
+Since we’re supposed to deliver the data inside an _EntitySet_ instance, we 
create the instance, ask it for the (initially empty) list of entities and add 
some new entities to it.  
+We create the entities and their properties according to what we declared in 
our _ExampleEdmProvider_ class. So we have to take care to provide the correct 
names to the new property objects.
+
+```java
+private EntitySet getData(EdmEntitySet edmEntitySet){
+
+       EntitySet entitySet = new EntitySetImpl();
+       List<Entity> entityList = entitySet.getEntities();
+
+       // add some sample product entities
+       entityList.add(new EntityImpl()
+               .addProperty(new PropertyImpl(null, "ID", ValueType.PRIMITIVE, 
1))
+               .addProperty(new PropertyImpl(null, "Name", 
ValueType.PRIMITIVE, "Notebook Basic 15"))
+               .addProperty(new PropertyImpl(null, "Description", 
ValueType.PRIMITIVE, "Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 
40GB")));
+       entityList.add(new EntityImpl()
+               .addProperty(new PropertyImpl(null, "ID", ValueType.PRIMITIVE, 
2))
+               .addProperty(new PropertyImpl(null, "Name", 
ValueType.PRIMITIVE, "1UMTS PDA"))
+               .addProperty(new PropertyImpl(null, "Description", 
ValueType.PRIMITIVE, "Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM 
network")));
+
+       entityList.add(new EntityImpl()
+               .addProperty(new PropertyImpl(null, "ID", ValueType.PRIMITIVE, 
3))
+               .addProperty(new PropertyImpl(null, "Name", 
ValueType.PRIMITIVE, "Ergo Screen"))
+               .addProperty(new PropertyImpl(null, "Description", 
ValueType.PRIMITIVE, "17 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 
x 960")));
+
+       return entitySet;
+}
+```
+
+
+
+## 4.3. Web Application
+
+After declaring the metadata and providing the data, our OData service 
implementation is done.  
+The last step is to enable our OData service to be called on a web server.  
+Therefore, we’re wrapping our service by a web application.
+
+The web application is defined in the web.xml file, where a servlet is 
registered.
+The servlet is a standard _HttpServlet_ which dispatches the user requests to 
the _Olingo_ framework.
+
+Let’s quickly do the remaining steps:
+
+
+
+### 4.3.1. Create and implement the Servlet
+
+Create a new package _myservice.mynamespace.web_.
+Create Java class with name _DemoServlet_ that inherits from _HttpServlet_.
+
+![createJavaServletClass](createJavaServletClass.png "Creating the servlet 
class")
+
+Override the _service()_ method.  
+Basically, what we’re doing here is to create an _ODataHttpHandler_, which 
is a class that is provided by _Olingo_.
+It receives the user request and if the URL conforms to the OData 
specification, the request is delegated to the processor implementation of the 
OData service.
+This means that the handler has to be configured with all processor 
implementations that have been created along with the OData service (in our 
example, only one processor).
+Furthermore, the _ODataHttpHandler_ needs to carry the knowledge about the 
_EdmProvider_.
+
+As such, here’s the location where our 2 implemented classes come together, 
the metadata declaration and the data provisioning.
+
+```java
+// This class represents a standard HttpServlet implementation.
+// It is used as main entry point for the web application that carries the 
OData service.
+// The implementation of this HttpServlet simply delegates the user requests 
to the ODataHttpHandler
+public class DemoServlet extends HttpServlet {
+
+       private static final long serialVersionUID = 1L;
+       private static final Logger LOG = 
LoggerFactory.getLogger(DemoServlet.class);
+
+       @Override
+       protected void service(final HttpServletRequest req, final 
HttpServletResponse resp) throws ServletException, IOException {
+
+               try {
+                       // create odata handler and configure it with 
EdmProvider and Processor
+                       OData odata = OData.newInstance();
+                       ServiceMetadata edm = odata.createServiceMetadata(new 
ExampleEdmProvider(), new ArrayList<EdmxReference>());
+                       ODataHttpHandler handler = odata.createHandler(edm);
+                       handler.register(new DemoEntityCollectionProcessor());
+
+                       // let the handler do the work
+                       handler.process(req, resp);
+
+               } catch (RuntimeException e) {
+                       LOG.error("Server Error ocurred in DemoServlet", e);
+                       throw new ServletException(e);
+               }
+       }
+}
+
+```
+
+### 4.3.2. Edit the web.xml
+
+The very last step of our tutorial is to register the Servlet in the _web.xml_ 
file.  
+Furthermore, we need to specify the _url-pattern_ for the servlet, such that 
our OData service can be invoked.
+
+Open the _src/main/webapp/WEB-INF/web.xml_ file and paste the following 
content into it:
+
+
+```xml
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+    xmlns="http://java.sun.com/xml/ns/javaee";
+    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd";
+    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd";
+    id="WebApp_ID" version="2.5">
+
+<servlet>
+  <servlet-name>DemoServlet</servlet-name>
+  <servlet-class> myservice.mynamespace.web.DemoServlet</servlet-class>
+  <load-on-startup>1</load-on-startup>
+</servlet>
+
+<servlet-mapping>
+  <servlet-name>DemoServlet</servlet-name>
+  <url-pattern>/DemoService.svc/*</url-pattern>
+</servlet-mapping>
+</web-app>
+
+```
+
+That’s it. Now we can build and run the web application.
+
+---
+
+
+# 5. Run the service
+
+
+Running the service means build the war file and deploy it on a server.  
+In our tutorial, we’re using the Eclipse web integration tools, which make 
life easier.
+
+
+### Run with Eclipse
+
+Select your project and from the context menu choose _Run As -> Run on Server_ 
 
+If you don’t have any server configured in Eclipse, you have to “manually 
define a new server” in the subsequent dialog.  
+If you have installed a Tomcat server on your local file system, you can use 
it here.  
+If not, you can use the _Basic -> J2EE Preview_ option, which is should be 
enough for our tutorial.  
+
+![runOnServer](runOnServer.png "The Eclipse dialog for deploying web apps to a 
server")
+
+> Note:
+> You might have to first execute maven build and also press F5 to refresh the 
content of the Eclipse project
+
+After pressing "run", Eclipse starts the internal server and deploys the web 
application on it.
+Then the Eclipse internal Browser View is opened and the index.jsp file that 
has been generated into our Example project is opened.  
+We ignore it. Instead, we open our OData service in our favorite browser.
+
+> Note:
+> If you face problems related to the server, it helps to restart your Eclipse 
IDE.
+
+### The service-URLs
+
+Try the following URLs:
+
+**Service Document**
+
+```
+http://localhost:8080/DemoService/DemoService.svc/
+```
+The expected result is the service document which displays our 
_EntityContainerInfo_:
+
+```json
+{
+  "@odata.context" : 
"http://localhost:8080/DemoService/DemoService.svc/$metadata";,
+  "value" : [
+  {
+    "name" : "Products",
+    "url" : "Products"
+  } ]
+}
+```
+
+**Metadata Document**
+
+```
+http://localhost:8080/ExampleService1/ExampleService1.svc/$metadata
+```
+The expected result is the metadata document that displays our _Schema_, 
_EntityType_, _EntityContainer_ and _EntitySet_.
+
+```xml
+<?xml version='1.0' encoding='UTF-8'?>
+<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx";>
+  <edmx:DataServices>
+    <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"; 
Namespace="com.example.model">
+      <EntityType Name="Product">
+        <Key>
+          <PropertyRef Name="ID"/>
+        </Key>
+        <Property Name="ID" Type="Edm.Int32"/>
+        <Property Name="Name" Type="Edm.String"/>
+        <Property Name="Description" Type="Edm.String"/>
+      </EntityType>
+      <EntityContainer Name="Container">
+        <EntitySet Name="Products" EntityType="com.example.model.Product"/>
+      </EntityContainer>
+    </Schema>
+  </edmx:DataServices>
+</edmx:Edmx>
+```
+
+**Query / EntitySet**
+
+```
+http://localhost:8080/DemoService/DemoService.svc/Products
+```
+The expected result is the hardcoded list of product entries, which we have 
coded in our processor implementation:
+
+```json
+{
+  "@odata.context":"$metadata#Products","
+  value":[
+    {
+      "ID":1,
+      "Name":"Notebook Basic 15",
+      "Description":"Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 
40GB"
+    },
+    {
+      "ID":2,
+      "Name":"1UMTS PDA",
+      "Description":"Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network"
+    },
+    {
+      "ID":3,
+      "Name":"Ergo Screen",
+      "Description":"17 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 
x 960"
+  }]
+}
+```
+
+
+---
+
+
+# 6. Summary
+
+Finally, we’ve created our first OData service based on the V4 version of 
the OData specification and using the V4 server library provided by _Olingo_.  
+Our first OData service is very simple; it only allows invoking one entity 
collection, apart from the service document and the metadata document.
+
+**Outlook**
+
+Further topics to be covered by follow-up tutorials:  
+* READ scenario: reading single entity, reading property  
+* WRITE scenario: executing PUT, POST and DELETE requests  
+* Navigation: navigating from one entity to a corresponding second entity
+* Data types
+
+
+**Further reading**
+
+OData specification: http://odata.org/  
+Olingo Javadoc: http://olingo.apache.org/javadoc/odata4/index.html


Reply via email to