(APIs de cliente) API Java para trabajar de forma transparente con ontologías

EN | ES

Esta funcionalidad está disponible a partir de la versión 2.0.2-RELEASE de la librería cliente, y 2.0.0-fireball de la onesait Platform

 

Introducción

Como sabemos, Onesait Platform posee una arquitectura Data Centric, en la que las Ontologías (abstracción de la entidad de base de datos) son el núcleo de la Plataforma, es por esto que todos los módulos de la plataforma necesitan de su existencia para operar correctamente. Leer: https://onesaitplatform.atlassian.net/wiki/spaces/OP/pages/56066346

La plataforma ofrece una abstracción de las ontologías para trabajar con ellas a través de un Repository Spring: https://onesaitplatform.atlassian.net/wiki/spaces/OP/pages/46137868

No obstante, hay situaciones en las que por requisitos técnicos u otras decisiones, se prefiere trabajar directamente con las entidades de base de datos utilizando frameworks como Spring Data, iBatis…, y se realizan las operaciones CRUD con estos frameworks, en vez de ser la plataforma la que las realiza.

En muchos de estos casos a su vez, interesa utilizar los módulos de la plataforma, entonces ¿Cómo podemos utilizar la plataforma, de modo que pueda manejar de forma transparente el concepto de Ontología?

La librería cliente de Java de la Onesait Platform ahora provee un cliente -NotifierClient- que nos permite crear las ontologías desde clases Java e informar a la plataforma de las operaciones CRUD que realizamos con nuestro framework, de tal forma que aunque la plataforma no realice estas operaciones, estará al tanto de ellas, y al existir la definición de la ontología, se podrán usar todos los módulos sin ningún inconveniente.

Cliente NotifierClient

Operaciones provistas

Este cliente provee las siguientes operaciones:

  • Creación/actualización de una ontología en base a una clase Java: a partir de una clase Java, se generará un JSON Schema para posteriormente crear la ontología.

  • Validación de un JSON de una entidad esta operació debería ejecutarse antes de su inserción o actualización: plataforma comprobará que el JSON es válido comparándolo con el JSON Schema de la ontología referenciada.

  • Notificación de operaciones CRUD: esta operación se debe ejecutar tras completarse el proceso en mi aplicación Java, cuando realicemos operaciones de CRUD, podremos usar el cliente para notificar a plataforma. Esta operación está tanto en formato síncrono como asíncrono.

Creación del cliente

Podemos crear el cliente de dos formas:

  1. Con un token de API de plataforma (X-OP-APIKey)

  2. Con usuario y contraseña: se utilizará Oauth 2 para la autenticación

Ejemplo:

El último parámetro del constructor sirve para saltarse la validación SSL para el caso de entornos que tengan certificados auto-firmados.

Creación de la ontología a partir de la clase Java

Supongamos que tenemos una entidad definida con Spring Data sobre MongoDB -Message.java-

Nótese la anotación @Attributes, necesario para que el JSON Schema generado se marque el atributo en cuestión como requerido, de lo contrario se marcará como opcional por defecto. Esto se debe a que por debajo se utiliza la librería JJSchema para la conversión , y requiere estas anotaciones.

Un buen momento para crear la ontología en plataforma de nuestra entidad, puede ser al inicio de la aplicación. De esta forma siempre nos aseguraremos de que nuestra entidad existe y está actualizada a su última versión del JSON Schema.

Como vemos, esto nos creará la ontología con el siguiente JSON Schema:

Validación del JSON Schema

Cuando queramos guardar datos o actualizarlos, podremos usar este método para comprobar que la instancia JSON es correcta. Deberemos pasarle o bien el nombre de la ontología y el JSON en formato String, o bien el objeto que será serializado a JSON internamente:

Si la validación fallase, se lanzaría una excepción del tipo NotifierException con los errores de validación, por ejemplo:

 

1 ERROR com.minsait.onesait.platform.client.NotifierClient - Validation failed with following errors Error processing data:{"message":"hello"}by:{"level":"error","schema":{"loadingURI":"#","pointer":""},"instance":{"pointer":""},"domain":"validation","keyword":"required","message":"object has missing required properties ([\"idMessage\",\"toMessage\"])","required":["idMessage","toMessage"],"missing":["idMessage","toMessage"]}

 

En caso contrario, el código seguirá su flujo.

Notificación a la Onesait Platform

Podemos utilizar la versión síncrona o la asíncrona, en función de nuestras necesidades.

Deberemos pasarle un objeto Notification, en el que le indicaremos:

  • QueryType: Solo si es operación QUERY. Enum {SQL, NATIVE}

  • Query: Solo si es operación QUERY. La query en sí.

  • Payload: Para INSERT/UPDATE, contendrá la instancia de la ontología serializada, el equivalente a un toString()

  • Operation: Enum {INSERT,UPDATE,DELETE,QUERY}

  • Id: id de la instancia, para casos como el DELETE/UPDATE por ID

Veamos un ejemplo:

Ejemplo práctico

Podemos hacer uso de estas operaciones descritas en nuestra lógica de negocio, por ejemplo, cuando se cree un mensaje nuevo en base de datos, podemos previamente validar su contenido, y posteriormente notificar a la plataforma:

De esta forma, si por ejemplo tenemos un flujo creado en el FlowEngine que trabaja con la entidad/ontología Message, recibiremos las notificaciones como si fuese la plataforma quien estuviese haciendo las operaciones:

 

Tenemos un ejemplo de uso de esta librería con tests en: https://github.com/onesaitplatform/onesaitplatform-spring-boot-example

Wrapper para Spring Boot

Para el desarrollo de aplicaciones con Spring Boot, se provee un wrapper con el objetivo de facilitar el uso de esta librería.

 

Properties

Además de inyectar la dependencia correspondiente:

1 2 3 4 5 <dependency> <groupId>com.minsait.onesait.platform</groupId> <artifactId>onesaitplatform-iotclient4springboot</artifactId> <version>2.1.0-RELEASE</version> </dependency>

 

Se deberán indicar las siguientes propiedades:

1 2 3 4 5 6 7 onesaitplatform: notifierclient: enabled: true server: https://development.onesaitplatform.com username: developer password: P4SSw0rd! #apikey: alternativa a username + password

Podemos configurar el cliente para que use credenciales de usuario y contraseña, o que utilice una API Key de plataforma.

Anotación @OPEntity

Esta anotación se utilizará en las clases del modelo de nuestra aplicación, por ejemplo si utilizamos Spring Data:

 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Document(collection = "Message") @OPEntity public class Message { public enum MessageType { MAIL, SMS } @Id @Attributes(required = true) private String idMessage; private String txtMessage; private MessageType typeMessage; @Attributes(required = true) private String fromMessage; }

 

El uso de esta anotación provocará una creación/actualización de una ontología a partir de la propia clase Java en el arranque de la aplicación.

Para que los atributos queden como requeridos en el JSON Schema creado a partir de la clase, se deberá hacer uso de la anotación:

1 @Attributes(required = true)

 

Anotación @OPValidateSchema

Esta anotación lanzará una validación contra el schema de la ontología de manera síncrona, por lo que si falla, se lanzará una excepción y alterará el flujo del código. Se utiliza a nivel de atributo/argumento.

 

1 2 @Override Message save(@OPValidateSchema Message entity);

 

Anotación @OPNotifierOperation

 

Esta anotación permite notificar a la plataforma de operaciones que ocurren en nuestra aplicación, tanto de manera síncrona como de manera asíncrona. Se utiliza a nivel de método, y tiene los siguientes argumentos:

  • async: boolean default false. Indica si la notificación se manda de manera síncrona o asíncrona.

  • ontology: nombre de la ontología. P.e. Message

  • operationType: QUERY, INSERT, UPDATE, DELETE. Tipo de operación que se realiza

  • queryType: SQL, NATIVE, default NATIVE. Cómo en la mayoría de los casos se hará uso de las interfaces de Spring Data / JPA, no se hará uso de este campo.

  • id: expresión SpEL que indica que argumento/valor del método se utilizará como id para la notificación. Este id es el identificador único de la instancia con la que se está operando. P.e. “#p0”

  • payload: expresión SpEL que indica que argumento/valor del método se utilizará como cuerpo de la notificación. P.e. “#p1”.

Ejemplos de uso:

 

INSERT

 

1 2 3 4 @OPNotifierOperation(ontology = "Message", operationType = OperationType.INSERT, async = true) public void createMessage(@OPValidateSchema Message message) { .... }

QUERY

1 2 3 4 5 @OPNotifierOperation(ontology = "Message", async = true) List<Message> findByToMessage(String toMessage); @OPNotifierOperation(ontology = "Message", async = false) Message findByIdMessage(String idMessage);

 

UPDATE

 

1 2 3 4 5 @Override @OPNotifierOperation(ontology = "Message", id = "#p0.idMessage", payload = "#p0", operationType = OperationType.UPDATE, async = true) public void updateMessage(@OPValidateSchema Message message) { messageRepository.save(message); }

 

DELETE

 

1 2 3 4 5 @OPNotifierOperation(async = false, ontology = "Message", operationType = OperationType.DELETE, id = "#p0") public void deleteMessage(String idMessage) { messageRepository.deleteById(idMessage); }

 

Podéis encontrar un ejemplo que hace uso de esta librería en:

https://github.com/onesaitplatform/onesaitplatform-spring-boot-example.git