Create a new extension
We will create a new extension similar to the one already covered in
Trail+~New+Extension, to expose our webservice. However we won't define any new Items in the data model.
- Open the Ant view in Eclipse and invoke the platform's task extgen.
- Enter the name "cuppywstrail" for the extension WHICH MUST BE ONE WORD IN LOWER CASE
- Enter the package prefix "de.hybris.platform.cuppywstrail" also WHICH MUST BE ALL IN LOWER CASE
- Select yempty for the extension template
- The Ant script will now create a skeleton extension for you in
<YOURPATH>/bin/custom/cuppywstrail but this is not yet imported
into Eclipse
- Import the generated extension into your Eclipse environment
- Right-click in package explorer and select Import
- Select General|Existing Projects into Workspace and browse to the new extension <YOURPATH>/bin/custom/cuppywstrail
- Remember to ensure that the "Copy projects into workspace" check box is not checked before clicking on the Finish button
- You should now see the extension in your Eclipse Package Explorer
- You can ignore any build errors currently being reported as the configuration is not yet complete
- Append the new extension to config/localextensions.xml file in the config project:
...
<extension dir= "${HYBRIS_BIN_DIR}/custom/cuppywstrail" />
</extensions>
|
- Run Ant's all task from Eclipse
- This will generate the Java Source files representing the Data Entities ("items") in all the -items.xml files (see buildprocessessentials for an overview)
- See the output in Eclipse's console view and wait for completion
- Load the generated files into Eclipse and build
- Select all top-level projects in the Package Explorer, right-click
and select refresh - this will reload all generated files into Eclipse
- Ensure that in Eclipse the option Project|Build Automatically is checked
- Eclipse will now start to build your project
- Explore your new extension's structure
- Run hybris and ensure your new extension is accessible
- Start hybris (by executing hybrisserver.bat or ./hybrisserver.sh from the command line in the directory <YOURPATH>/bin/platform)
- Open http://localhost:9001/cuppywstrail and verify that you get a simple message with the extension name, "cuppywstrail" and "welcome to my extension" below it.
- You can also verify that your extension is running by opening http://localhost:9001 under Platform/Extensions. You should see "cuppywstrail" in the list.
This tells you that the extension is now running
Generated Classes
As discussed in
Trail+~+New+Data+Model, the hybris build framework generates a number of java source files for each item type defined in items.xml. This includes:
- models created for the service layer (business logic should go there)
- classes created to support CRUD logic via RESTful URIs
- low-level Jalo classes which we won't discuss as their use is discouraged
We will now explore the classes generated for supporting the CRUD cycle through RESTful webservice calls.
A Stadium Data Entity is defined in
cuppytrail's items.xml file. As described in
Trail+~+New+Data+Model, we should expect to see several files generated for this entity including DTOs and Resources. These were created for the
cuppytrail extension where we defined the Item type
Stadium.
It is important to note that they are actually created in the platform
project. To verify that these classes exist, search for them in Eclipse,
using the Navigate Menu / Open Type, or the shortcut key Ctrl-Shift-T.
If you search for "StadiumDTO", for example, you will see that it has
been created in the
platform project, in the package de/hybris/platform/cuppytrail/dto which is located in the web/gensrc folder.
- Since DTOs and Resources are located in the platform's web folder, they are in the web-layer of the platform. If we try and reference them in code which is in our web
layer, i.e. the web folder of the cuppywstrail extension, they will not
be in the build path. Web-layers within separate extensions are not
able to see each other's classes. Eclipse handles this by dynamically
applying a build path to the entire workspace, but when you build your
project with Ant, any references you make, for example to the data
transfer object for Stadium, will result in a build failure. Individual
web applications do not share the same class loaders which matches the
final deployment scenario. However this usually turns out to be quite
inconvenient for developing and deploying.
- Next we will see how to solve this problem.
Webservice nature
To allow the cuppywstrail extension to expose the Stadium item type to a web service client, we need to do two things:
First, we need make the cuppywstrail extension visible to the cuppytrail extension where the Stadium class is defined.
Add the following tags inside the extension tag in
extensioninfo.xml of the cuppywstrail project.
<requires-extension name= "cuppy" />
<requires-extension name= "cuppytrail" />
|
Next we need include the generated DTOs and Resources from cuppytrail in our classpath.
This is done by assigning cuppywstrail a "webservice nature which
generates the file core-webservices.jar containing the platform's
generated DTOs and Resources in cuppywstrail/webroot/WEB-INF/lib. As the
folder is included in cuppywstrail's classpath, we can now reference
and extend the DTOs and Resources. A new web.xml file will be created,
as well as the file cuppywstrail/resources/cuppywstrail-web-spring.xml
redirecting requests to our webservice request handler.
- In Eclipse, drag the file cuppywstrail/build.xml into your Ant View.
- Select the cuppywstrail target webservice_nature
- Clean your extension by running your extension's ant clean (Note this is not the platform clean's ant task)
- Finally run the platform all ant task
The DTO class will be extended later to demonstrate how to customise DTO and Resource behaviour.
Let's summarize the previous steps:
- we created a new extension referencing the cuppytrail extension
- classes in this extension were not able to access the generated
DTOs and Resources because they reside in the platform's web-layer
- we assigned a webservice nature to cuppywstrail and rebuilt the
system resulting in a jar (core-webservices.jar) with DTOs and resources
from the cuppytrail extension to be copied to cuppywstrail
Webservice support for the Stadium Data Entity
We have now we have enabled web service support for the Stadium Data Entity.
Perform standard CRUD operations via RESTful URIs - Attempt 1
A regular web browser is not suitable for testing our RESTful calls
as we also need to be able to enter a client's username and password via
a pre-emptive BASIC protocol which is not supported by a regular
browser. To this end we will use a RESTful webservices client to test
the web-services exposure of our Stadium object. Note that as our
extension now has a web services nature, the default "welcome to my
extension" message will no longer be returned from
http://localhost:9001/cuppywstrail. In fact, you will get a 404 error saying "The requested resource (/cuppywstrail/) is not available.".
- Start hybris
- Start a RESTful Client
- Go to http://code.google.com/p/rest-client/downloads/list and download the REST Client
- Download the latest RESTClient GUI release
- Run the RESTClient and open Authentication tab, set the
Authentication Mode to Basic and Enter “admin” and “nimda” as
credentials
- Make a RESTful request to view a list of the Stadium
- Type and run the URI request http://localhost:9001/cuppywstrail/rest/stadiums in the RESTful Client
- You will (probably) receive a response stating that you are not allowed to view this resource
We will address this issue now.
Modify the RESTful access rights
As discussed in
WebService API - Security Architecture users must be a member of the webservicegroup to be able to access resource via REST which is not done by default.
To verify that this user group is set up for you:
- Open the hMC and see if the usergroup webservicegroup is listed; if not:
- Create the webservicegroup:
- Add the user group AdminGroup to the user group webservicegroup:
Perform standard CRUD operations via RESTful URIs - Attempt 2
- With a new user group webservicegroup defined as described in WebService API - Security Architecture and the admingroup added to it, our RESTful request with user name admin should now succeed.
The request returns an XML representation of the Stadiums that are currently in the system.
<?xml version= "1.0" encoding= "UTF-8" ?>
</stadiums>
|
- Enter the http://localhost:9001/cuppywstrail/rest/stadiums/Wembley to obtain an XML representation of the Wembley Stadium.
<?xml version= "1.0" encoding= "UTF-8" ?>
<comments/>
<creationtime> 2010 - 11 -08T16: 30 : 40 + 01 : 00 </creationtime>
<modifiedtime> 2010 - 11 -08T16: 30 : 40 + 01 : 00 </modifiedtime>
<capacity> 123456 </capacity>
<matches/>
<stadiumType>openair</stadiumType>
</stadium>
|
- Add some matches to Wembley Stadium in the hMC.
- Rerun the query http://localhost:9001/cuppytrail/rest/stadiums/Wembley and you will see the matches you just added.
<?xml version= "1.0" encoding= "UTF-8" ?>
<comments/>
<creationtime> 2010 - 11 -08T16: 30 : 40 + 01 : 00 </creationtime>
<modifiedtime> 2010 - 11 -10T13: 00 : 40 + 01 : 00 </modifiedtime>
<capacity> 123456 </capacity>
<matches>
<matchday> 0 </matchday>
</match>
<matchday> 0 </matchday>
</match>
</matches>
<stadiumType>openair</stadiumType>
</stadium>
|
- Notice that the URI attributes in the XML are also URIs pointing to
resources. This is a standard RESTful practice in which RESTful
responses may contain URIs that in turn can be interrogated.
| Tip You
may have noticed that responses are by default in XML format. hybris
optionally accepts and sends responses in JSON format. To change the
default, all you have to do is to set the headers for the request and
response:
Header Entry |
Value |
Result |
Accept |
application/xml |
Response is sent in XML format |
Accept |
application/json |
Response is sent in JSON format |
Content-type |
application/xml |
Body in request is expected to be in XML format |
Content-type |
application/json |
Body in request is expected to be in JSON format |
|
Modify a Stadium via REST
We will now send a RESTful PUT request to modify the capacity of the wembley stadium.
- In an earlier step we invoked a RESTful call with the URI http://localhost:9001/cuppytrail/rest/stadiums/Wembley and received the XML
<?xml version= "1.0" encoding= "UTF-8" ?>
<comments/>
<creationtime> 2010 - 11 -08T16: 30 : 40 + 01 : 00 </creationtime>
<modifiedtime> 2010 - 11 -08T16: 30 : 40 + 01 : 00 </modifiedtime>
<capacity> 123456 </capacity>
<matches/>
<stadiumType>openair</stadiumType>
</stadium>
|
- Modify the RESTClient's mode to PUT and set its context to text/xml.
Now enter the following code in the body field:
<capacity> 11111 </capacity>
</stadium>
|
- Note that this xml was obtained by stripping down the xml returned from http://localhost:9001/cuppytrail/rest/stadiums/Wembley entering a new value for capacity.
- Invoke the RESTful call and you should then see a HTTP 1.1 200 OK status
- Change the RESTful client's mode back to GET
- If you now rerun the request you will find the new capacity
returned. But note if you have implemented the Model Interceptor earlier
in this trail, the stadium's name will now be in lowercase. As a
result, the URI you need to invoke is http://localhost:9001/cuppytrail/rest/stadiums/wembley.
Custom DTOs and Custom Resources
Earlier we wrote code in your own extension that references the DTOs
and Resource generated in the Platform. Default DTO and Resource
implementations may be customized by extending the respective classes.
See
Customizing Resources and DTOs for a discussion on how to do this.
Triggering Commands via REST
In addition to performing CRUD on Data via REST, hybris allows you to
easily create commands that can then be triggered via RESTful calls.
See
REST Commands Tutorial for a discussion.
Summary
In this step you should have learned
- what classes are generated for supporting RESTful CRUD operations on your Data Entities
- what the webservice_nature target is and why it is needed
- how to perform RESTful CRUD operations on your Data Entities
- how to extend DTOs and Resources
- how to write virtual DTOs