0% found this document useful (0 votes)
39 views

Distributed Systems Lab 10

Java Data Objects (JDO) provides an interface-based abstraction for persisting Java objects to a data store. It allows separation of concerns so developers can focus on domain objects while the JDO implementation handles persistence details. JDO applications can access different data stores and take advantage of J2EE features. The example shows using JDO with JPOX to map domain objects to database tables and perform CRUD operations on persisted objects. Service Data Objects (SDO) provides a programming model and API to access and manage data from heterogeneous sources without needing technology-specific APIs.

Uploaded by

Ferenc Bondar
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
39 views

Distributed Systems Lab 10

Java Data Objects (JDO) provides an interface-based abstraction for persisting Java objects to a data store. It allows separation of concerns so developers can focus on domain objects while the JDO implementation handles persistence details. JDO applications can access different data stores and take advantage of J2EE features. The example shows using JDO with JPOX to map domain objects to database tables and perform CRUD operations on persisted objects. Service Data Objects (SDO) provides a programming model and API to access and manage data from heterogeneous sources without needing technology-specific APIs.

Uploaded by

Ferenc Bondar
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

Distributed Systems Techs

10. Data services (JDO & SDO) and Service Component Architecture (SCA)
December 14, 2009

Java Data Objects (JDO)


access data from data store using a standard interface-based abstraction model of persistence in Java that is, Java Data Objects (JDO). The original specifications (1.0) were done under the supervision of Sun and starting from 2.0, the development of the API and the reference implementation happens as an Apache open-source project. Usually program to retrieve data from relational stores using JDBC, -> Do we need yet another standard, JDO? Start with the business use cases and then do a business analysis at the end of which you will come out with a Business Domain Object Model (BDOM).
The BDOM will drive the design of your entity classes, which are to be persisted to a suitable data store.

Design your entity classes and their relationship Next question is should you be writing code to create tables, and persist or query data from these tables or data stores
It is preferable to answer 'No' for this question, since the more code you write, the more are the chances of making errors, and further, developer time is costly. Today you may write JDBC for doing the "technical functionalities", and tomorrow you may want to change all your JDBC to some other standard since you want to port your data from a relational store to a different persistence mechanism.

Features of JDO
Separation of Concerns: Application developers can focus on the BDOM and leave the persistence details (storage & retrieval) to the JDO implementation. API-based: JDO is based on a Java interface-based programming model. => All persistence behavior including most commonly used features of OR mapping is available as metadata, external to your BDOM source code. => We can also Plug and Play multiple JDO implementations. Data store portability: Irrespective of whether the persistent store is a relational or object-based file, or just an XML DB or a flat file, JDO implementations can still support the code =>JDO applications are independent of the underlying database. Performance: A specific JDO implementation knows how to interact better with its specific data store, which will improve performance as compared to developer written code. J2EE integration: JDO applications can take advantage of J2EE features like EJB and thus the enterprise features such as remote message processing, automatic distributed transaction coordination, security, etc

JDO using JPOX


JPOX (Java Persistent Objects): Apache open-source project, which aims at a heterogeneous persistence solution for Java using JDO. JPOX JDO support any combination of 4 main aspects of persistence: Persistence Definition: The mechanism of defining how your BDOM classes are to be persisted to the data store. Persistence API: The programming API used to persist your BDOM objects. Query Language: The language used to find objects due to certain criteria. Data store: The underlying persistent store you are persisting your objects to.

1.

2.

3.

4.

Example
two entity classes: OrderList and LineItem BDOM illustrates that
an Order can contain multiple line items. each line item is related to one and only one Order.

BDOM classes:

Example
OrderList is the class representing the Order, and is having a primary key attribute that is number. public class OrderList{ private int number; private Date orderDate; private Set lineItems; // other getter & setter methods go here // Inner class for composite PK public static class Oid implements Serializable{ public int number; public Oid(){ } public Oid(int param) { this.number = param; } public String toString(){ return String.valueOf(number); } public int hashCode() { return number; } public boolean equals(Object other){ if (other != null && (other instanceof Oid)){ Oid k = (Oid)other; return k.number == this.number; } return false; } } }

LineItem represents each item container in the Order. We don't explicitly define a primary key for LineItem even though JDO will have its own mechanism to do that. public class LineItem{ private String productId; private int numberOfItems; private OrderList orderList; // other getter & setter methods go here }

JDO configuration file


XML configuration file defines the fields that are to be persisted and to what JDBC or JDO wrapper constructs should be mapped to. Need to create an XML file called package.jdo to be put it in the same directory where we have the entities.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jdo SYSTEM "file:/javax/jdo/jdo.dtd"> <jdo> <package name="com.binildas.jdo.jpox.order"> <class name="OrderList" identity-type="application" objectid-class="OrderList$Oid" table="ORDERLIST"> <field name="number" primary-key="true"> <column name="ORDERLIST_ID"/> </field> <field name="orderDate"> <column name="ORDER_DATE"/> </field> <field name="lineItems" persistence-modifier="persistent" mapped-by="orderList"> <collection element-type="LineItem"> </collection> </field> </class> <class name="LineItem" table="LINEITEM"> <field name="productId"> <column name="PRODUCT_ID"/> </field> <field name="numberOfItems"> <column name="NUMBER_OF_ITEMS"/> </field> <field name="orderList" persistence-modifier="persistent"> <column name="LINEITEM_ORDERLIST_ID"/> </field> </class> </package> </jdo>

Example
In this sample, we will persist our entities to a relational database, Oracle. We specify the main connection parameters in jpox.PROPERTIES file. javax.jdo.PersistenceManagerFactoryClass=org.j pox.jdo.JDOPersistenceManagerFactory javax.jdo.option.ConnectionDriverName=oracle.jd bc.driver.OracleDriver javax.jdo.option.ConnectionURL=jdbc:oracle:thin: @127.0.0.1:1521:orcl javax.jdo.option.ConnectionUserName=scott javax.jdo.option.ConnectionPassword=tiger org.jpox.autoCreateSchema=true org.jpox.validateTables=false org.jpox.validateConstraints=false

Main class contains the code to test the JDO functionalities. it creates two Orders and adds few line items to each order. it persists these entities and queries back these entities using the id.
public class Main{ static public void main(String[] args){ Properties props = new Properties(); try{ props.load(new FileInputStream("jpox.properties"));} catch (Exception e){ e.printStackTrace();} PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props); PersistenceManager pm = pmf.getPersistenceManager(); Transaction tx = pm.currentTransaction(); Object id = null; try{ tx.begin(); LineItem lineItem1 = new LineItem("CD011", 1); LineItem lineItem2 = new LineItem("CD022", 2); OrderList orderList = new OrderList(1, new Date()); orderList.getLineItems().add(lineItem1); orderList.getLineItems().add(lineItem2); LineItem lineItem3 = new LineItem("CD033", 3); LineItem lineItem4 = new LineItem("CD044", 4); OrderList orderList2 = new OrderList(2, new Date()); orderList2.getLineItems().add(lineItem3); orderList2.getLineItems().add(lineItem4); pm.makePersistent(orderList); id = pm.getObjectId(orderList); System.out.println("Persisted id : "+ id); pm.makePersistent(orderList2); id = pm.getObjectId(orderList2); System.out.println("Persisted id : "+ id); orderList = (OrderList) pm.getObjectById(id); System.out.println("Retreived orderList : " + orderList); tx.commit(); } catch (Exception e){ e.printStackTrace(); if (tx.isActive()){ tx.rollback(); } } finally{ pm.close(); } } }

LOB, CDM and Data Services


When we define SOA strategies at an enterprise level, we deal with multiple Line of Business (LOB) systems;
some of them will be dealing with the same kind of business entity. For example, a customer entity is required for a sales system and a marketing system.

This necessitates a Common Data Model (CDM), which is often referred to as the Canonical Data Model or Information Model.
In such a model, you will often have entities that represent "domain" concepts, for example, customer, account, address, order, and so on. So, multiple LOB systems will make use of these domain entities in different ways, seeking different information-based on the business context.

Data Services are specialization of WSs which are data and information oriented.
They need to manage the traditional CRUD (Create, Read, Update, and Delete) operations as well as a few other data functionalities such as search and information modeling. The Create operation will give back a unique ID whereas Read, Update, and Delete operations are performed on a specific unique ID. Search done with some form of search criteria and information modeling, or retrieval happens when we pull useful information, for example, retrieving the address for a customer.

XQuery and XPath


XQuery or XPath expressions, similar to SQL capabilities on relational data, for XML documents Example: get the order status for a particular customer (getCustomerOrderStatus()) which will take the customer ID argument. The data services layer will have a retrieve operation passing the customer ID and the XQuery or the XPath statement will obtain the requested order information from the retrieved customer data. High level processing layers (e.g. LOB service tiers) can use highlevel interface (e.g. getCustomerOrderStatus operation) of the Application Specialization using a web services (data services) interface and need not know or use XQuery or XPath directly. The underlying XQuery or XPath can be encapsulated, reused, and optimized.

Service Data Objects (SDO)


tries to solve is the issue of heterogeneous manner of data management. By data management, we mean data storage as well as operations on data lifecycle. SDO provides developers an API, the SDO API, and a programming model to access data.
This API lets you to work with data from heterogeneous data sources, including RDBMS, entity EJBs, XML sources, web services, EIS data sources using the Java Connector Architecture, and so on. A developer need not be familiar with a technology-specific API such as JDBC or XQuery in order to access and utilize data - instead, just use SDO API.

SDO Architecture
In SDO, data is organized as a graph of objects, called DataObject.
A DataObject is the fundamental component which is a representation of some structured data, with some properties. These properties have either a single value or multiple values, and their values can be even other data objects. Each data objects also maintains a change summary, which represents the alterations made to it.

A Data Mediator Service (DMS) is responsible


for creating a data graph from data source(s), and also for updating the data source(s) based on any changes made to a data graph. A DMS will create a Data Graph, which is a container for a tree of data objects.

A single data graph can represent data from different data sources.
This is actually a design model to deal with data aggregation scenarios from multiple data sources. The data graphs form the basics of the disconnected architecture of SDO, since they can be passed across layers and tiers in an application. When doing so, they are serialized to the XML format.

SDO clients are disconnected from both the DMS and the data source. A Change Summary contains any change information related to the data in the data object.
Change summaries are initially empty and are populated as and when the data graph is modified.

Using Apache Tuscany SDO


Apache Tuscany SDO is a sub-project within opensource Apache Tuscany. Tuscany aims at defining an infrastructure that simplifies the development of Service-Oriented application networks, addressing real business probls. It is based on specifications defined by the OASIS Open Composite Services Architecture (CSA) Member Section, which advances open standards that simplify SOA application development. Tuscany SDO mainly provides implementations in Java and C++.
Both are available for download at: http://incubator.apache.org/tuscany/.

Example
SDO can handle heterogeneous data sources, but for the sample here, we will make use of an XML file as a data source. The sample will read as well as write an XML file, when the client program makes use of SDO API to do data operations. The main artifacts for running the samples in SDO include
an XSD schema file and an XML instance file.

Then we have two java programs,


one which reads the XML and another which creates an XML.

Example xsd file


hr.xsd restricts the structure of an employee XML file which can contain multiple employees. Each employee can have a name, address, organization, and office elements. Each of these elements can have sub-elements:
<?xml version="1.0"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.binildas.com/apache/tuscany/sdo/sample" targetNamespace="http://www.binildas.com/apache/tuscany/sdo/sample"> <xsd:element name="employees"> <xsd:complexType> <xsd:sequence> <xsd:element ref="employee" maxOccurs="unbounded" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="employee"> <xsd:annotation> <xsd:documentation>Employee representation</xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:sequence> <xsd:element name="name" type="xsd:string" /> <xsd:element ref="address" maxOccurs="2" /> <xsd:element ref="organization" /> <xsd:element ref="office" /> </xsd:sequence> <xsd:attribute name="id" type="xsd:integer" /> </xsd:complexType> </xsd:element> <xsd:element name="organization"> <xsd:complexType> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="id" type="xsd:integer" /> </xsd:complexType> </xsd:element> <xsd:element name="office"> <xsd:complexType>

Example xml file


hr.xml provided is fully constrained as per the above schema. XML file contains data on two employees:
<?xml version="1.0"?> <employees xmlns="http://www.binildas.com/apache/tuscany/sdo/sample"> <employee id="30379"> <name>Binildas C. A.</name> <address> <street1>45 Bains Compound Nanthencode</street1> <city>Trivandrum</city> <state>KL</state> <zip-code>695003</zip-code> </address> <organization id="08"> <name>Software</name> </organization> <office id="31> <address> <street1>101 Camarino Ruiz</street1> <street2>Apt 2 Camarillo</street2> <city>Callifornia</city> <state>LA</state> <zip-code>93012</zip-code> </address> </office> </employee> <employee id="30380"> <name>Rajesh R V</name> <address> <street1>1400 Salt Lake Road</street1> <street2>Appartment 5E</street2> <city>Boston</city> <state>MA</state> <zip-code>20967</zip-code> </address> <organization id="15"> <name>Research</name> </organization> <office id="21"> <address> <street1>2700 Cambridge Drive</street1> <city>Boston</city> <state>MA</state> <zip-code>20968</zip-code> </address> </office> </employee> </employees>

Example - ReadEmployees class


The class shown below: first read the XML file, mentioned previously, and load it into a root DataObject. A DataObject is a graph of other DataObjects. Hence, we can iterate over the graph and get each item DataObject.
public class ReadEmployees extends SampleBase{ private static final String HR_XML_RESOURCE = "hr.xml"; public static final String HR_XSD_RESOURCE = "hr.xsd"; public ReadEmployees(Integer commentaryLevel) { super(commentaryLevel, SampleInfrastructure.SAMPLE_LEVEL_BASIC); } public static void main(String[] args)throws Exception{ ReadEmployees sample = new ReadEmployees(COMMENTARY_FOR_NOVICE); sample.runSample(); } public void runSample () throws Exception{ InputStream inputStream = ClassLoader.getSystemResourceAsStream(HR_XML_RESOURCE); byte[] bytes = new byte[inputStream.available()]; inputStream.read(bytes); inputStream.close(); HelperContext scope = createScopeForTypes(); loadTypesFromXMLSchemaFile(scope, HR_XSD_RESOURCE); XMLDocument xmlDoc = getXMLDocumentFromString(scope, new String(bytes)); DataObject purchaseOrder = xmlDoc.getRootObject(); List itemList = purchaseOrder.getList("employee"); DataObject item = null; for (int i = 0; i < itemList.size(); i++) { item = (DataObject) itemList.get(i); System.out.println("id: " + item.get("id")); System.out.println("name: " + item.get("name")); } } }

Example - CreateEmployees
define DataObjects in code and build the SDO graph. the root DataObject is persisted to a file and also to the system output stream as shown in the following code.
public class CreateEmployees extends SampleBase { private static final String HR_XML_RESOURCE_NEW = "hr_new.xml"; public static final String HR_XSD_RESOURCE = "hr.xsd"; public static final String HR_NAMESPACE = "http://www.binildas.com/apache/tuscany/sdo/sample"; public CreateEmployees(Integer commentaryLevel) { super(commentaryLevel, SAMPLE_LEVEL_BASIC); } public static void main(String[] args) throws Exception{ CreateEmployees sample = new CreateEmployees(COMMENTARY_FOR_NOVICE); sample.runSample(); } public void runSample() throws Exception{ HelperContext scope = createScopeForTypes(); loadTypesFromXMLSchemaFile(scope, HR_XSD_RESOURCE); DataFactory factory = scope.getDataFactory(); DataObject purchaseOrder = factory.create(HR_NAMESPACE, "employees"); DataObject employee1 = purchaseOrder.createDataObject("employee"); employee1.setString("id", "3457"); employee1.set("name", "Cindy Jones"); DataObject homeAddress1 = employee1.createDataObject("address"); homeAddress1.set("street1", "Cindy Jones"); homeAddress1.set("city", "Stanchion"); homeAddress1.set("state", "TX"); homeAddress1.set("zip-code", "79021"); DataObject organization1 = employee1.createDataObject("organization"); organization1.setString("id", "78"); organization1.set("name", "Sales"); DataObject office1 = employee1.createDataObject("office"); office1.setString("id", "43"); DataObject officeAddress1 = office1.createDataObject("address"); officeAddress1.set("street1", "567 Murdock"); officeAddress1.set("street2", "Suite 543"); officeAddress1.set("city", "Millford"); officeAddress1.set("state", "TX"); officeAddress1.set("zip-code", "79025"); DataObject employee2 = purchaseOrder.createDataObject("employee");

Service Component Architecture (SCA)


aims at creating new and transforms existing, IT assets into reusable services more easily. introduces the notion of services and references. A component which implements some business logic offers their capabilities through service-oriented interfaces. Components may also consume functionality offered by other components through service-oriented interfaces, called service references. SCA composition aids recursive assembly of coarse-grained components out of fine-grained tightly coupled components. These coarse-grained components can even be recursively assembled to form higher levels of coarse-grained components. In SCA, a composite is a recursive assembly of fine-grained components.

SCA assembly model

Apache Tuscany SCA Java


a sub-project within open-source Apache Tuscany, which has got a Java implementation of SCA. Tuscany SCA is integrated with Tomcat, Jetty, and Geronimo. SCA Java runtime is composed of core and extensions.
The core wires functional units together and provides SPIs that extensions can interact with. Extensions enhance SCA runtime functionality such as service discovery, reliability, support for transport protocols, and so on.

Example
A single booking service with a default SCA binding. BookingAgentServiceComponent exercises this component by calling three other components: FlightServiceComponent, HotelServiceComponent, and CabServiceComponent

1. 2. 3.

Example
Fine-grained service components FlightServiceComponent public interface IFlightService{ String bookFlight(String date, int seats, String flightClass); } public class FlightServiceImpl implements IFlightService{ public String bookFlight(String date, int seats, String flightClass){ } } HotelServiceComponent public interface IHotelService{ String bookHotel(String date, int beds, String hotelClass); } public class HotelServiceImpl implements IHotelService{ public String bookHotel(String date, int beds, String hotelClass){ } } CabServiceComponent public interface ICabService{ String bookCab(String date, String cabType); } public class CabServiceImpl implements ICabService{ public String bookCab(String date, String cabType){ }

BookingAgentServiceComponent import org.osoa.sca.annotations.Reference; public class BookingAgentServiceComponent implements IBookingAgent{ private IFlightService flightService; private IHotelService hotelService; private ICabService cabService; @Reference public void setFlightService(IFlightService flightService) { this.flightService = flightService; } @Reference public void setHotelService(IHotelService hotelService) { this.hotelService = hotelService; } @Reference public void setCabService(ICabService cabService) { this.cabService = cabService; } public String bookTourPackage(String date, int people, String tourPack){ System.out.println("BookingAgent.bookTourPackage..."); String flightBooked = flightService.bookFlight(date, people, tourPack); String hotelBooked = hotelService.bookHotel(date, people, tourPack); String cabBooked = cabService.bookCab(date, tourPack); if((flightBooked.equals("Success")) && (hotelBooked.equals("Success")) && (cabBooked.equals("Success"))){ return "Success"; } else{ return "Failure"; } } }

Example
BookingAgentClient
creates an instance of SCADomain gets a reference of the BookingAgentServiceComponent using the name of the configured service component. executes the business method, bookTourPackage.

import org.apache.tuscany.sca.host.embedded.SCADomain; public class BookingAgentClient{ public static void main(String[] args) throws Exception { SCADomain scaDomain = SCADomain.newInstance("BookingAgent.composite"); IBookingAgent bookingAgent = scaDomain.getService(IBookingAgent.class, "BookingAgentServiceComponent"); System.out.println("BookingAgentClient.bookingTourPackage..."); String result = bookingAgent.bookTourPackage("20Dec2008", 5, "Economy"); System.out.println("BookingAgentClient.bookedTourPackage : " + result); scaDomain.close(); } }

You might also like