REST data service properties file
To configure the REST data service, edit the properties file for REST and define the required entity schema for a data grid.
The REST data service properties file is the main configuration file for the eXtreme Scale REST data service. This file is a Java™ property file with key-value pairs. By default, the REST data service runtime environment looks 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:
Property | Description |
---|---|
catalogServiceEndPoints | The required comma-delimited list of hosts and ports of a catalog service
domain in the format: <host:port>. This is optional if using WebSphere® Application Server integrated with WebSphere eXtreme Scale to host the REST data service. See Starting a stand-alone catalog service that uses the ORB transportor Starting a stand-alone catalog service that uses the IBM eXtremeIO (XIO) transport
for more
information. catalogServiceEndPoints= server1:2809,server2:2809 |
objectGridNames | The required names of the data grids 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. |
ogClientPropertyFile | The optional name of the ObjectGrid client property file. This file contains security properties that are required for enabling ObjectGrid client security. If the "securityEnabled" attribute is set in the property file, security will be enabled on the ObjectGrid client used by the REST service. The "credentialGeneratorProps" must also be set in the property file to a value in the format of "user:pass" or a value of {xor_encoded user:pass} |
loginType | The type of authentication used by the REST Service when ObjectGrid
client security is enabled. If ObjectGrid client security is not enabled, this property is ignored.
If ObjectGrid client security is enabled and loginType is set to basic,
the REST service will:
If ObjectGrid client security is enabled and loginType is set to
none the REST service will:
|
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 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. |
maxResultsPerCollection | The optional maximum number of results that will be returned in a query. The default value is unlimited. Any positive integer is a valid value. |
wxsRestAccessRightsFile | The optional name of the eXtreme Scale REST service access rights property file which specifies the access rights for the service operations and the ObjectGrid entities. If this property is specified, the REST service will try to load the file from the path specified, else it will try to load the file from its classpath. |
WebSphere eXtreme Scale configuration
The eXtreme Scale REST data service interacts with eXtreme Scale using the EntityManager API. An entity schema is defined for an eXtreme Scale data grid and the metadata for the entities is automatically consumed by the REST data service. See Defining an entity schema for details about configuring an entity schema.
@Entity
public class Person {
@Id String taxId;
String firstName;
String lastName;
}
The REST service automatically creates 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
After the data grid is configured and running, configure and package an eXtreme Scale client. For details on configuring the eXtreme Scale REST data service client package, see the packaging and deployment information in Installing the REST data service.
Entity model
WebSphere eXtreme Scale entities are modeled using the entity annotations or an entity metadata descriptor file. For details on how to configure an entity schema, see Defining an entity schema. The eXtreme Scale REST service uses the entity metadata to automatically create an EDMX model for the data service.
- When defining entities in a partitioned data grid, all entities must have a direct or indirect
single valued association to the root entity (a key association). The WCF data service client
runtime environment must be able to access every entity directly through its canonical address.
Therefore, the key of the root entity that is used for partition routing (the schema root) must be
part of the key in the child entity.
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; }
- Bi-directional and uni-directional associations are supported. However, uni-directional associations may not always work from a Microsoft WCF Data Services client since they can only be navigated in one direction and the Microsoft specification requires all associations to be bi-directional.
- Referential constraints are not supported. The WebSphere eXtreme Scale runtime environment does not validate keys between entities. Associations between entities must be managed by the client.
- Complex types are not supported. The EntityManager API does not support embeddable attributes. All attributes are expected to be simple type attributes (see the simple attribute types listed below). Non-simple type attributes are treated as a binary object from the perspective of the client.
- Entity inheritance is not supported. The EntityManager API does not support inheritance.
- Media Resources and Media Links are not supported. The HasStream attribute of the EntityType in the Conceptual Schema Definition Language Document for Data Services is never used.
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: MSDN Library: Abstract Type System.
The following EDM types are available in WCF Data Services:
- Edm.Binary
- Edm.Boolean
- Edm.Byte
- Edm.DateTime
- Edm.Time
- Edm.Decimal
- Edm.Double
- Edm.Single
- Edm.Float
- Edm.Guid *
- Edm.Int16
- Edm.Int32
- Edm.Int64
- Edm.SByte
- Edm.String
The EDM type: Edm.Guid is not supported by the eXtreme Scale REST data service.
Mapping Java types to EDM types
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 | Edm.Decimal |
java.math.BigInteger | java.math.BigInteger |
java.lang.String | Edm.String |
char | char |
java.lang.Character | java.lang.Character |
Char[] | Char[] |
java.lang.Character[] | java.lang.Character[] |
java.util.Calendar | Edm.DateTime |
java.util.Date | java.util.Date |
java.sql.Date | java.sql.Date |
java.sql.Timestamp | java.sql.Timestamp |
java.sql.Time | java.sql.Time |
Other types | Edm.Binary |
Mapping from EDM types to Java types
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:
- A type check is performed to make sure the EDM type is compatible with the Java type. An EDM type is compatible with a Java type if the data supported by the EDM type is a subset of the data supported by the Java type. For example, Edm.int32 type is compatible with a Java long type, but Edm.int32 type is not compatible with a Java short type.
- A target Java type object will be created which represents the string value in the payload.
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 |
Mapping temporal types
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 data 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 data 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 environment 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
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 data 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 logs the broken links as CWPRJ1022W warnings. Broken associations are removed from the request payload.
Use a batch request to group association updates in a single transaction to avoid broken links. See the following 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 data grid, all entities should have a single-valued key-association path to a root entity. Another section of this topic shows how to define a key association. Because the root entity is used to partition the entity, many-to-many associations are not allowed for partitioned data grids. For an example on how to model a relational entity schema for a partitioned data grid, see Scalable data model in eXtreme Scale.
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 data 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 data 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>