Para configurar el servicio de datos REST, edite el archivo de propiedades para REST y defina el esquema de entidad necesario para una cuadrícula de datos.
El archivo de propiedades del servicio de datos REST es el archivo de configuración principal para el servicio de datos REST de eXtreme Scale. Este archivo es un archivo de propiedades Java con pares clave-valor. De forma predeterminada, el tiempo de ejecución del servidor de datos REST para un archivo wxsRestService.properties con el nombre correcto en la classpath. El archivo también se puede definir explícitamente utilizando la propiedad del sistema: wxs.restservice.props.
-Dwxs.restservice.props=/usr/configs/dataservice.properties
Cuando se carga el servicio de datos REST, el archivo de propiedades utilizado se muestra en los archivos de registro:
CWOBJ4004I: Los archivos de propiedades de servicio de datos REST de eXtreme Scale se han cargado: [/usr/configs/RestService.properties]
El archivo de propiedades del servicio de datos REST soporta las propiedades siguientes:
Propiedad | Descripción |
---|---|
catalogServiceEndPoints | Lista delimitada por comas necesaria de hosts y puertos de un dominio de servicio de catálogo en el formato: <host:puerto>. Es opcional si utiliza WebSphere Application Server integrado con WebSphere eXtreme
Scale para alojar el servicio de datos REST. Si desea más información, consulte Inicio de un servicio de catálogo autónomo. catalogServiceEndPoints= server1:2809,server2:2809 |
objectGridNames | Los nombres necesarios de las cuadrículas de datos que se deben exponer al servicio REST. Como mínimo, se necesita un nombre de ObjectGrid. Separe varios nombres de ObjectGrid utilizando comas: ECommerceGrid,InventoryGrid |
objectGridClientXML | Nombre opcional del archivo XML de sustitución de cliente ObjectGrid. El nombre especificado aquí se cargará de la classpath. El valor predeterminado es: /META-INF/objectGridClient.xml. |
ogClientPropertyFile | Nombre opcional del archivo de propiedades del ObjectGrid. Este archivo contiene propiedades de seguridad para habilitar la seguridad del cliente ObjectGrid. Si está establecido el atributo "securityEnabled" en el archivo de propiedades, se habilitará la seguridad en el cliente ObjectGrid que el servicio REST utiliza. "credentialGeneratorProps" se debe establecer también en el archivo de propiedades en el formato de "user:pass" o un valor de {xor_encoded user:pass} |
loginType | El servicio REST utiliza este tipo de
autenticación cuando está habilitada la seguridad del cliente de ObjectGrid. Si no está habilitada la
seguridad del cliente de ObjectGrid, se pasa por alto esta propiedad. Si está habilitada la seguridad del cliente de ObjectGrid y loginType se establece en basic,
el servicio REST:
Si está habilitada la seguridad de cliente de ObjectGrid y loginType
se establece en none, el servicio REST:
|
traceFile | Nombre opcional del archivo al que se debe redirigir la salida del rastreo. El valor predeterminado es logs/trace.log. |
traceSpec | Especificación de rastreo óptimo que el servidor de ejecución de eXtreme Scale debe utilizar inicialmente. El valor predeterminado es *=all=disabled. Para realizar el seguimiento del servicio de datos REST, utilice: ObjectGridRest*=all=enabled |
verboseOutput | Si se establece en true, los clientes del servicio de datos REST reciben información de diagnóstico adicional cuando se producen anomalías. El valor predeterminado es false. Este valor opcional se debe definir como false para los entornos de producción, ya que se puede revelar información sensible. |
maxResultsPerCollection | El número máximo opcional de resultados que se devolverán en una consulta. El valor predeterminado es unlimited. Cualquier entero positivo es un valor válido. |
wxsRestAccessRightsFile | El nombre opcional del archivo de propiedades de derechos de acceso del servicio REST de eXtreme Scale que especifica los derechos de acceso de las operaciones de servicio y las entidades ObjectGrid. Si se especifica esta propiedad el servicio REST intentará cargar el archivo de la vía de acceso especificada, si no intentará cargar el archivo desde su vía de acceso de clases. |
El servicio de datos REST de eXtreme Scale interactúa con eXtreme Scale mediante la API EntityManager. Se define un esquema de entidad para una cuadrícula de datos de eXtreme Scale y los metadatos para las entidades los consume automáticamente el servicio de datos REST. Consulte Definición de un esquema de entidad para obtener información sobre la configuración de un esquema de entidad.
@Entity
public class Person {
@Id String taxId;
String firstName;
String lastName;
}
El servicio REST crea automáticamente un documento de modelo de datos de entidad ADO.NET para servicios de datos (EDMX), que está disponible utilizando el URI $metadata:
http://localhost:8080/wxsrestservice/restservice/NorthwindGrid/$metadata
Una vez que se ha configurado la cuadrícula de datos y está en ejecución, configure y empaquete un cliente de eXtreme Scale. Para obtener información detallada sobre cómo configurar el paquete de cliente de servicio de datos REST de eXtreme Scale, consulte la información sobre empaquetamiento y despliegue del apartado Instalación del servicio de datos REST.
Las entidades de WebSphere eXtreme Scale se modelan utilizando las anotaciones de entidad o un archivo de descriptor de metadatos de entidad. Para obtener información sobre cómo configurar un esquema de entidad, consulte Definición de un esquema de entidad. El servicio REST de eXtreme Scale utiliza los metadatos de entidad para crear automáticamente un modelo EDMX para el servicio de datos.
Por ejemplo:
@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;
}
El protocolo OData define la lista siguiente de tipos de modelo de datos de entidad (EDM) en su sistema de tipos abstractos. Los temas siguientes describen cómo selecciona el adaptador REST de eXtreme Scale el tipo EDM basándose en el tipo básico definido en la entidad. Para obtener detalles sobre los tipos EDM, consulte MSDN Library: Abstract Type System (Biblioteca MSDN: sistema de tipo abstracto).
Los tipos de EDM siguientes están disponibles en WCF Data Services:
El tipo EDM: Edm.Guid no está soportado por el servicio de datos REST de eXtreme Scale
Tipo Java | Tipo EDM |
---|---|
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 |
Otros tipos | Edm.Binary |
Para las solicitudes de actualización y las solicitudes de inserción, la carga útil especifica los datos que se deben actualizar o insertar en el servicio de datos REST de eXtreme Scale. El servicio puede convertir automáticamente tipos de datos compatibles a los tipos de datos definidos en el documento EDMX. El servicio de datos REST convierte las representaciones de serie codificadas en XML del valor en el tipo correcto utilizando el siguiente proceso de dos pasos:
Tipo EDM | Tipo Java |
---|---|
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 incluye cinco tipos temporales para almacenar la fecha, la hora, o ambos: java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp y java.util.Calendar. Todos estos tipos se expresan en el modelo de datos de entidad como Edm.DateTime. El servicio de datos REST de eXtreme Scale convierte automáticamente y normaliza los datos en función del tipo Java. Este tema describe varias cuestiones que los desarrolladores deben tener en cuenta al utilizar cualquier tipo temporal.
Diferencias de huso horario
En WCF Data Services, las descripciones de valores de hora en el tipo Edm.DateTime siempre se expresa utilizando el estándar UTC (hora universal coordinada), que es el nombre internacionalmente reconocido la hora media de Greenwich (GMT). La hora universal coordinada es la hora medida a una longitud de cero grados, el punto de origen UTC. El horario de verano no es aplicable a la hora universal coordinada.
Conversión entre tipos de entidad y EDM
Cuando un cliente envía una solicitud al servicio de datos REST, la fecha y la hora se representan como una hora de huso horario GMT, como en el ejemplo siguiente:
"2000-02-29T21:30:30.654123456"
A continuación, el servicio de datos REST construirá la instancia de tipo temporal Java correspondiente y la insertará en la entidad en la cuadrícula de datos.
Cuando un cliente solicita una propiedad que es un tipo temporal Java del servicio de datos REST de eXtreme Scale, el valor siempre se normaliza como un valor de huso horario GMT. Por ejemplo, si una entidad java.util.Date se construye tal como se indica a continuación:
Calendar c = Calendar.getInstance();
c.clear();
c.set(2000, 1, 29, 21, 30, 30);
Date d = c.getTime();
La fecha y la hora se representan utilizando el huso horario predeterminado del proceso Java porque Calendar.getInstance() creará un objeto Calendar con el huso horario local. Si el huso horario local es CST, entonces la fecha, cuando se recupere del servicio de datos REST, será la representación GMT de la hora: "2000-03-01T03:30:30"
Normalización de java.sql.Date
Una entidad de eXtreme Scale puede definir un atributo con el tipo Java java.sql.Date. Este tipo de datos no incluye la hora y el servicio de datos REST lo normaliza. Esto significa que el tiempo de ejecución de eXtreme Scale no almacena ninguna información de horas, minutos, segundos o milisegundos en el atributo java.sql.Date. Independientemente del desplazamiento de huso horario, la fecha siempre se representa como una fecha local.
Por ejemplo, si el cliente actualiza una propiedad java.sql.Date con el valor “2009-01-01T03:00:00”, el servicio de datos REST, que está en el huso horario CST (-06:00), creará simplemente una instancia de java.sql.Date cuya hora se define como “2009-01-01T00:00:00” de la hora CST local. No se realiza ninguna conversión de huso horario para crear el valor de java.sql.Date. Cuando el cliente del servicio REST recupere el valor de este atributo, se mostrará como “2009-01-01T00:00:00Z”. Si se realizase una conversión de huso horario, el valor se mostraría como si tuviese la fecha "2008-12-31", lo que sería incorrecto.
Normalización de java.sql.Time
De forma similar a java.sql.Date, los valores de java.sql.Time se normalizan y no incluyen la información de la fecha. Esto significa que el tiempo de ejecución de eXtreme Scale no almacena el año, el mes ni el día. La hora se almacena utilizando la hora media de Greenwich a partir del 1 de enero de 1970, lo que es coherente con la implementación de java.sql.Time.
Por ejemplo, si el cliente actualiza una propiedad java.sql.Time con el valor "2009-01-01T03:00:00", el servicio de datos REST creará una instancia de java.sql.Time con el valor de milisegundos definido como 3*60*60*1000, que equivale a 3 horas. Cuando el servicio REST recupere el valor, se mostrará como "1970-01-01:03:00:00Z".
Las asociaciones definen la relación entre dos entidades iguales. El servicio REST de eXtreme Scale refleja las asociaciones modeladas con entidades definidas con entidades anotadas de eXtreme Scale o entidades definidas mediante un archivo XML descriptor de entidad.
Mantenimiento de asociaciones
El servicio de datos REST de eXtreme Scale no soporta las restricciones de integridad referencial. El cliente debe asegurarse de que las referencias se actualicen cuando se eliminen o añadan entidades. Si una entidad de destino de una asociación se elimina de la cuadrícula de datos, pero el enlace entre la entidad de origen y de destino no se elimina, el enlace se romperá. El servicio de datos REST de eXtreme Scale y la API EntityManager toleran enlaces rotos y los registran como avisos CWPRJ1022W. Las asociaciones rotas se eliminarán de la carga útil de la solicitud.
Utilice una solicitud por lotes para agrupar actualizaciones de asociaciones en una sola transacción para evitar enlaces rotos. Consulte la sección siguiente para obtener detalles sobre las solicitudes por lotes.
El servicio de datos REST de eXtreme Scale no utiliza el elemento ReferentialConstraint del modelo de datos de entidad ADO.NET.
Multiplicidad de asociaciones
Las entidades pueden tener asociaciones con varios valores o asociaciones con un solo valor. Las asociaciones con varios valores, o colecciones, son asociaciones "de uno a muchos" o "de muchos a muchos". Las asociaciones con un solo valor son o asociaciones "de uno a uno" o "de muchos a uno".
En una cuadrícula de datos particionada, todas las entidades deben tener una única vía de acceso de asociación de clave de un solo valor a la entidad raíz. En otro apartado de este tema se muestra cómo definir una asociación de claves. Dado que la entidad raíz se utiliza para particionar la entidad, no se permiten asociaciones de muchos a muchos para cuadrículas de datos particionadas. Para ver un ejemplo sobre cómo modelar un esquema de entidad relacional para una cuadrícula de datos particionada, consulte Modelo de datos escalable de eXtreme Scale.
El ejemplo siguiente describe cómo los tipos de asociación de la API EntityManager, modelados utilizando clases Java anotadas, se correlacionan con el modelo de datos de entidad ADO.NET:
@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>
Asociaciones bidireccionales y unidireccionales
Las asociaciones de entidades pueden ser unidireccionales o bidireccionales. Especificando el atributo "mappedBy" en la anotación @OneToOne, @OneToMany o @ManyToMany o el atributo "mapped-by" en la etiqueta XML one-to-one, one-to-many o many-to-many, la entidad se vuelve bidireccional. El protocolo OData requiere actualmente que todas las entidades sean bidireccionales, que permiten a los clientes generar vías de acceso de navegación en ambas direcciones. La API EntityManager de eXtreme Scale permite modelar asociaciones unidireccionales que pueden ahorrar memoria y simplificar el mantenimiento de las asociaciones. Si se utiliza una asociación unidireccional, el cliente del servicio de datos REST sólo debe navegar por la asociación utilizando la asociación definida.
Por ejemplo: Si se define una asociación unidireccional de muchos a uno entre Address y Country, no se permite el URI siguiente:
/restservice/CustomerGrid/Country('USA')/addresses
Asociaciones de clave
También se pueden incluir asociaciones de un solo valor (de uno a uno y de muchos a uno) como toda la clave de entidades o parte de ella. Esto se conoce como asociación de clave.
Se requieren asociaciones de clave al utilizar una cuadrícula de datos particionada. La asociación de clave se debe definir para todas las entidades hijo en un esquema de entidad particionada. El protocolo OData requiere que todas las entidades sean directamente direccionables. Esto significa que la clave de la entidad hijo debe incluir la clave utilizada para el particionamiento.
En el ejemplo siguiente, Customer tiene una asociación de uno a muchos con Order. La entidad Customer es la entidad raíz y el atributo customerId se utiliza para particionar la entidad. Order tiene incluido Customer como parte de su identidad:
@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;
}
Cuando el servicio de datos REST genera el documento EDMX para este modelo, los campos de clave de Customer se incluyen automáticamente incluidos como parte de la entidad Order:
<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>
Cuando se crea una entidad, la clave nunca debe cambiar. Esto significa que si la asociación de clave entre una entidad hijo y su padre debe cambiar, la entidad hijo se debe eliminar y se debe volver a crear con un padre diferente. En una cuadrícula de datos particionada, esto requerirá dos conjuntos de cambios por lotes distintos ya que el traslado probablemente implicará más de una partición.
Operaciones en cascada
La API EntityManager permite una política de cascada flexible. Las asociaciones se pueden marcar para realizar una operación de persistencia, eliminación, invalidación o fusión en cascada. Estas operaciones en cascada pueden realizarse en uno o ambos lados de una asociación bidireccional.
El protocolo OData sólo permite operaciones de supresión en el lado único de la asociación. La anotación CascadeType.REMOVE o el atributo XML cascade-remove no se pueden definir a ambos lados de una asociación bidireccional de uno a uno ni en el múltiple de una asociación de uno a muchos. El ejemplo siguiente ilustra una asociación bidireccional Cascade.REMOVE válida:
@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;
}
La asociación resultante debe ser tal como se indica a continuación:
<Association Name="Customer_orders">
<End Type="NorthwindGridModel.Customer" Role="Customer"
Multiplicity="1">
<OnDelete Action="Cascade"/>
</End>
<End Type="NorthwindGridModel.Order" Role="Order"
Multiplicity="*"/>
</Association>