To configure the REST data service, edit the properties file for REST and define the required entity schema for a WebSphere eXtreme Scale grid.
The REST data service properties file is the main configuration file for the eXtreme Scale REST data service. This file is a typical Java property file with key-value pairs. By default, the REST data service runtime will look for a well-named wxsRestService.properties file in the classpath. The file can also be explicitly defined by using the system property: wxs.restservice.props.
Dwxs.restservice.props=/usr/configs/dataservice.properties
When the REST data service is loaded, the property file used is displayed in the log files:
CWOBJ4004I: The eXtreme Scale REST data service properties files were loaded: [/usr/configs/RestService.properties]
The REST data service properties file supports the following properties:
Type | Description |
---|---|
Property | Description |
catalogServiceEndPoints | The required comma-delimited list of hosts and ports of
a catalog service grid in the format: <host:port>. This is optional
if using WebSphere Application Server integrated with eXtreme Scale
to host the REST data service. See the WebSphere eXtreme Scale product
documentation for details on how to configure and start a catalog
service. catalogServiceEndPoints= server1:2809,server2:2809 |
objectGridNames | The required names of the ObjectGrids to expose to the REST
service. At least one ObjectGrid name is required. Separate multiple
ObjectGrid names using a comma: ECommerceGrid,InventoryGrid |
objectGridClientXML | The optional name of the ObjectGrid client override XML
file. The name specified here will be loaded from the classpath.
The default is: /META-INF/objectGridClient.xml. See the WebSphere eXtreme Scale product documentation for details on how to configure an eXtreme Scale client. |
traceFile | The optional name of the file to redirect the trace output to. The default is logs/trace.log. |
traceSpec | The optional trace specification that the eXtreme Scale runtime server should initially use. The default is *=all=disabled. To trace the entire REST data service, use: ObjectGridRest*=all=enabled |
verboseOutput | If set to true, REST data service clients will receive additional diagnostic information when failures occur. The default is false. This optional value should be set to false for production environments as sensitive information may be revealed. |
The eXtreme Scale REST data service interacts with eXtreme Scale using the EntityManager API. An entity schema is defined for an eXtreme Scale grid and the meta-data for the entities is automatically consumed by the REST data service. For details on how to configure an entity schema, see the eXtreme Scale EntityManager documentation.
@Entity public class Person { @Id String taxId; String firstName; String lastName; }
The REST service will automatically create an ADO.NET Entity Data Model for Data Services (EDMX) document, which is available using the $metadata URI:
http://localhost:8080/wxsrestservice/restservice/NorthwindGrid/$metadata
Once the eXtreme Scale grid is configured and running, an eXtreme Scale client should be configured and packaged. For details on configuring the eXtreme Scale REST data service client package, see topic:
The following topics describe how eXtreme Scale is exposed as a REST service.
WebSphere eXtreme Scale entities are modeled using the entity annotations or an entity metadata descriptor file. See the topic on defining an entity schema in the Programming Guide of the WebSphere eXtreme Scale V7.1 documentation for details on how to configure an eXtreme Scale entity schema. The eXtreme Scale REST service uses the entity metadata to automatically create an EDMX model for the data service.
For example:
For example: @Entity(schemaRoot=true) public class Person { @Id String taxId; String firstName; String lastName; @OneToMany(mappedBy="person") List<Address> addresses; } @Entity public class Address { @Id int addrId; @Id @ManyToOne Person person; String street; }
Mapping between EDM data types and Java data types
The OData protocol defines the following list of Entity Data Model (EDM) types in its abstract type system. The following topics describe how the eXtreme Scale REST adapter chooses the EDM type based on the basic type defined in the entity. For details on EDM types, see: http://msdn.microsoft.com/en-us/library/dd541295(PROT.10).aspx.
The following EDM types are available in WCF Data Services:
* The EDM type: Edm.Guid is not supported by the eXtreme Scale REST data service.
Mapping Java types to EDM types
The eXtreme Scale REST data service will automatically convert basic entity types into EDM types. The type mapping can be seen by displaying the Entity Data Model Extensions (EDMX) metadata document using the $metadata URI. The EDM type is what is used by clients to read and write data to the REST data service. It shows the mapping from the Java type defined for an entity to the EDM data type.
When retrieving data using a query, the data will be represented with these types:
Type | Value |
---|---|
Java Type | EDM Type |
boolean java.lang.Boolean | Edm.Boolean |
byte java.lang.Byte | Edm.SByte |
short java.lang.Short | Edm.Int16 |
int java.lang.Integer | Edm.Int32 |
long java.lang.Long | Edm.Int64 |
float java.lang.Float | Edm.Single |
double java.lang.Double | Edm.Double |
java.math.BigDecimal java.math.BigInteger | Edm.Decimal |
java.lang.String char java.lang.Character Char[] java.lang.Character[] | Edm.String |
java.util.Calendar java.util.Date java.sql.Date java.sql.Timestamp java.sql.Time | Edm.DateTime |
Other types | Edm.Binary |
For Update requests and Insert requests, the payload specifies the data to be updated or inserted into the eXtreme Scale REST data service. The service can automatically convert compatible data types to the data types defined in the EDMX document. The REST data service converts the XML encoded string representations of the value into the correct type using the following two-step process:
Compatible EDM type to Java type
Type | Description |
---|---|
EDM Type | Java Type |
Edm.Boolean | boolean java.lang.Boolean |
Edm.SByte | byte java.lang.Byte short java.lang.Short int java.lang.Integer long java.lang.Long float java.lang.Float double java.lang.Double java.math.BigDecimal java.math.BigInteger char java.lang.Character |
Edm.Byte, Edm.Int16 | short java.lang.Short int java.lang.Integer long java.lang.Long float java.lang.Float double java.lang.Double java.math.BigDecimal java.math.BigInteger char java.lang.Character |
Edm.Int32 | int java.lang.Integer long java.lang.Long float java.lang.Float double java.lang.Double java.math.BigDecimal java.math.BigInteger |
Edm.Int64 | long java.lang.Long double java.lang.Double java.math.BigDecimal java.math.BigInteger |
Edm.Double | double java.lang.Double java.math.BigDecimal |
Edm.Decimal | double java.lang.Double java.math.BigDecimal java.math.BigInteger |
Edm.Single | float java.lang.Float double java.lang.Double java.math.BigDecimal |
Edm.String | java.lang.String char java.lang.Character Char[] java.lang.Character[] java.math.BigDecimal java.math.BigInteger |
Edm.DateTime | java.util.Calendar java.util.Date java.sql.Date java.sql.Time java.sql.Timestamp |
Edm.Time | java.sql.Time java.sql.Timestamp |
Java includes five temporal types for storing date, time or both: java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp and java.util.Calendar. All of these types are expressed in the entity data model as Edm.DateTime. The eXtreme Scale REST service automatically converts and normalizes the data depending on the Java type. This topic describes several issues that developers must be aware of when using any temporal type.
Time zone differences
In WCF Data Services, the descriptions of time values in the Edm.DateTime type are always expressed using the Coordinated Universal Time (UTC) standard, which is the internationally recognized name for Greenwich Mean Time (GMT). Coordinated Universal Time is the time as measured at zero degrees longitude, the UTC origin point. Daylight saving time is not applicable to UTC.
Converting between entity and EDM types
When a client sends a request to the REST data service, the date and time is represented as a GMT time zone time, like the following example:
"2000-02-29T21:30:30.654123456"
The REST data service will then construct the appropriate Java temporal type instance and insert it into the entity in the grid.
When a client requests a property which is a Java temporal type from the eXtreme Scale REST data service, the value is always normalized as a GMT time zone value. For example, if an entity java.util.Date is constructed as follows:
Calendar c = Calendar.getInstance(); c.clear(); c.set(2000, 1, 29, 21, 30, 30); Date d = c.getTime();
The date and time are represented using the default time zone of the Java process because Calendar.getInstance() will create a Calendar object with local time zone. If the local time zone is CST, then the date, when retrieved from the REST data service will be the GMT representation of the time: "2000-03-01T03:30:30"
java.sql.Date normalization
An eXtreme Scale entity can define an attribute with Java type java.sql.Date. This data type does not include the time and is normalized by the REST data service. This means that the eXtreme Scale runtime does not store any hours, minutes, seconds, or milliseconds information in the java.sql.Date attribute. Regardless of the time zone offset, the date is always represented as a local date.
For example, if the client updates a java.sql.Date property with the value “2009-01-01T03:00:00”, the REST data service, which is in the CST time zone (-06:00), will simply create a java.sql.Date instance of which the time is set to “2009-01-01T00:00:00” of the local CST time. There is no time zone conversion done to create the java.sql.Date value. When the REST service client retrieves the value of this attribute, it will be displayed as “2009-01-01T00:00:00Z”. If a time zone conversion were done, the value would be displayed as having the date of “2008-12-31”, which would be incorrect.
java.sql.Time normalization
Similar to java.sql.Date, the java.sql.Time values are normalized and do not include date information. This means that the eXtreme Scale run time does not store the year, month or day. The time is stored using the GMT time from the epoch January 1, 1970, which is consistent with the java.sql.Time implementation.
For example, if the client updates a java.sql.Time property with the value "2009-01-01T03:00:00", the REST data service, will create a java.sql.Time instance with the milliseconds set to 3*60*60*1000, which is equal to 3 hours. When the rest service retrieves the value, it will be displayed as "1970-01-01:03:00:00Z".
Associations define the relationship between two peer entities. The eXtreme Scale REST service reflects the associations modeled with entities defined with eXtreme Scale annotated entities or entities defined using an entity descriptor XML file.
Association maintenance
The eXtreme Scale REST data service does not support referential integrity constraints. The client should ensure that references are updated when entities are removed or added. If a target entity of an association is removed from the grid, but the link between the source and target entity is not removed, then the link is broken. The eXtreme Scale REST data service and EntityManager API tolerates broken links and will log them as CWPRJ1022W warnings. Broken associations will simply be removed from the request payload.
Use a batch request to group association updates in a single transaction to avoid broken links. See section for details on batch requests.
The ADO.NET Entity Data Model ReferentialConstraint element is not used by the eXtreme Scale REST data service.
Association multiplicity
Entities can have multi-valued associations or single-valued associations. Multi-valued associations, or collections, are one-to-many or many-to-many associations. Single-valued associations are one-to-one or many-to-one associations.
In a partitioned grid, all entities should have a single-valued key-association path to a root entity. Because the root entity is used to partition the entity, many-to-many associations are not allowed for partitioned grids. For an example on how to model a relational entity schema for a partitioned grid, see section . See the following section: for details on how to define a key association.
The following example describes how the EntityManager API association types, modeled using annotated Java classes map to the ADO.NET Entity Data Model:
@Entity public class Customer { @Id String customerId; @OneToOne TaxInfo taxInfo; @ManyToOne Address homeAddress; @OneToMany Collection<Order> orders; @ManyToMany Collection<SalesPerson> salespersons; } <Association Name="Customer_TaxInfo"> <End Type="Model1.Customer" Role="Customer" Multiplicity="1" /> <End Type="Model1.TaxInfo " Role="TaxInfo" Multiplicity="1" /> </Association> <Association Name="Customer_Address"> <End Type="Model1.Customer" Role="Customer" Multiplicity="1" /> <End Type="Model1.Address" Role="TaxInfo" Multiplicity="*" /> </Association> <Association Name="Customer_Order"> <End Type="Model1.Customer" Role="Customer" Multiplicity="*" /> <End Type="Model1.Order" Role="TaxInfo" Multiplicity="1" /> </Association> <Association Name="Customer_SalesPerson"> <End Type="Model1.Customer" Role="Customer" Multiplicity="*" /> <End Type="Model1.SalesPerson" Role="TaxInfo" Multiplicity="*" /> </Association>
Bi-directional and uni-directional associations
Entities associations can be uni-directional or bi-directional. By specifying the "mappedBy" attribute on the @OneToOne, @OneToMany or @ManyToMany annotation or the "mapped-by" attribute on the one-to-one, one-to-many or many-to-many XML attribute tag, the entity becomes bi-directional. The OData protocol currently requires all entities to be bi-directional, allowing clients to generate navigation paths in both directions. The eXtreme Scale EntityManager API allows modeling uni-directional associations which can save memory and simplify maintenance of the associations. If a uni-directional association is used, the REST data services client must only navigate through the association using the defined association.
For example: If a uni-directional many-to-one association is defined between Address and Country, the following URI is not allowed:
/restservice/CustomerGrid/Country('USA')/addresses
Key associations
Single-valued associations (one-to-one and many-to-one) can also be included as all or part of the entities key. This is known as a key-association.
Key associations are required when using a partitioned grid. The key association must be defined for all child entities in a partitioned entity schema. The OData protocol requires that all entities are directly addressable. This means that the key in the child entity must include the key used for partitioning.
In the following example, Customer has a one-to-many association to Order. The Customer entity is the root entity and the customerId attribute is used to partition the entity. Order has included the Customer as part of its identity:
@Entity(schemaRoot="true") public class Customer { @Id String customerId; @OneToMany(mappedBy="customer") Order orders } @Entity public class Order { @Id int orderId; @Id @ManyToOne Customer customer; java.util.Date orderDate; }
When the REST data service generates the EDMX document for this model, the Customer key fields are automatically included as part of the Order entity:
<EntityType Name="Order"> <Key> <PropertyRef Name="orderId"/> <PropertyRef Name="customer_customerId"/> </Key> <Property Name="orderId" Type="Edm.Int64" Nullable="false"/> <Property Name="customer_customerId" Type="Edm.String" Nullable="false"/> <Property Name="orderDate" Type="Edm.DateTime" Nullable="true"/> <NavigationProperty Name="customer" Relationship="NorthwindGridModel.Customer_orders" FromRole="Order" ToRole="Customer"/> <NavigationProperty Name="orderDetails" Relationship="NorthwindGridModel.Order_orderDetails" FromRole="Order" ToRole="OrderDetail"/> </EntityType>
When an entity is created, the key must never change. This means if the key association between a child entity and its parent must change, the child entity must be removed and re-created with a different parent. In a partitioned grid, this will require two different batch change sets since the move will likely involve more than one partition.
Cascading operations
The EntityManager API allows a flexible cascade policy. Associations can be marked to cascade a persist, remove, invalidate or merge operation. Such cascade operations can happen on one or both sides of a bi-directional association.
The OData protocol only allows cascade delete operations on the single-side of the association. The CascadeType.REMOVE annotation or cascade-remove XML attribute cannot be defined on both sides of a one-to-one bi-directional association or on the many-side of a one-to-many association. The following example illustrates a valid Cascade.REMOVE bi-directional association:
@Entity(schemaRoot="true") public class Customer { @Id String customerId; @OneToMany(mappedBy="customer", cascade=CascadeType.REMOVE) Order orders } @Entity public class Order { @Id int orderId; @Id @ManyToOne Customer customer; java.util.Date orderDate; }
The resulting EDMX association looks as follows:
<Association Name="Customer_orders"> <End Type="NorthwindGridModel.Customer" Role="Customer" Multiplicity="1"> <OnDelete Action="Cascade"/> </End> <End Type="NorthwindGridModel.Order" Role="Order" Multiplicity="*"/> </Association>