Last modified by admin on 2026/07/18 17:44

Show last authors
1 = Libertya REST API {{id name="libertya-rest-api" /}}=
2
3 == Manual de uso {{id name="manual-de-uso" /}}==
4
5 {{toc/}}
6
7 = Introducción {{id name="introducción" /}}=
8
9 El presente documento detalla los pasos para realizar el deploy de Libertya REST API en una instancia Libertya.
10
11 = Convenciones {{id name="convenciones" /}}=
12
13 A modo de ejemplo, en todos los casos del presente documento se indica como dirección del servidor y puerto **localhost:8080**.
14
15 = Requerimientos {{id name="requerimientos" /}}=
16
17 Al momento de escribir este documento, se requiere **Java 8** y **Libertya 23.0** para poder ejecutar adecuadamente LY REST API (en versiones anteriores a Libertya 23.0 podría funcionar adecuadamente pero no ha sido validado).
18
19 = Distribución {{id name="distribución" /}}=
20
21 El proyecto se distribuye en un único archivo (por ejemplo **lyrestapi-1.0.0.jar**) conteniendo tanto la lógica necesaria, así como las librerías de Libertya sobre las que se apoya.
22
23 Notar que dentro de dicho archivo jar, en **/BOOT-INF/lib/** se encuentran las librerías **OXP.jar** y **OXPXLib.jar** utilizadas en el build del proyecto. Por consiguiente, en caso de actualizar la versión de Libertya CORE (o sus componentes), será necesario reemplazar estos archivos con las nuevas versiones y si la nueva versión contiene cambios estructurales, deberá adecuarse el schema de los end-points implementados en función de dichos cambios.
24
25 = Preferencias {{id name="preferencias" /}}=
26
27 Dentro del archivo jar, en **/BOOT-INF/classes/** se encuentra el archivo **application.properties**. En dicho archivo se configuran - entre otras - las siguientes propiedades:
28
29 *. Información de conexión a la base de datos y el ID de la compañía a utilizar (por defecto 1010016).
30 **. Utilizada para - por ejemplo - poder validar la existencia de usuarios ante las solicitudes de tokens a la base de datos\\
31 **. Saber la compañía sobre la cual se estará ejecutando el servicio, y por consiguiente determinar datos relevantes para el contexto como la moneda.\\
32 **. Las gestiones operativas serán registradas bajo el usuario contenido en la información del token obtenido.\\
33 *. Secret key a utilizar para la generación de los JWT a utilizar, así como el tiempo de expiración de los tokens generados\\
34 *. Completar directamente los documentos o dejarlos en borrador\\
35 *. Generación de logs (ubicacion, formato, etc.)\\
36 *. Recuperación de valores para propiedades que referencian a otras entidades\\
37 *. Carga de valores por defecto en inserción
38
39 A lo largo de este documento se entrará en detalle sobre cada uno de estos ítems.
40
41 **IMPORTANTE** : las propiedades más relevantes (conexión a base de datos, compañía, puerto, etc.), pueden ser configuradas desde variables de entorno. La aplicación priorizará la configuración según las variables de entorno, y en caso contrario, utilizará las propiedades de **application.properties**.
42
43 = Ejecución {{id name="ejecución" /}}=
44
45 **java -jar lyrestapi-1.0.0.jar**
46
47 La salida debería ser similar a la siguiente:
48
49 . ____ _ __ _ _\\/\\ / ___‘_ __ _ _(_)_ __ __ _ \ \ \ \\\( ( )\___ |’_ | ‘_| |’_ \/ _` | \ \ \ \\\\\/ ___)| |_)| | | | | || (_| | ) ) ) )\\’ |____| .__|_| |_|_| |_\__, | / / / /\\=========|_|==============|___/=/_/_/_/\\:: Spring Boot :: (v2.7.6)
50
51 - Starting LYRestAPI using Java 1.8.0_362 on pc-usuario with PID 12553 (/home/usuario/workspace/org.libertya.api/build/classes/java/main started by usuario in /home/usuario/workspace/org.libertya.api)\\- No active profile set, falling back to 1 default profile: “default”\\- Tomcat initialized with port(s): 8080 (http)\\2023-08-03 09:29:33.973 INFO - Starting service [Tomcat]\\…\\- Tomcat started on port(s): 8080 (http) with context path ’’\\- Started LYRestAPI in 8.839 seconds (JVM running for 10.532)
52
53 == Inicio automático en distribuciones recientes de Linux {{id name="inicio-automático-en-distribuciones-recientes-de-linux" /}}==
54
55 Es posible configurar el inicio/detención de la aplicación como servicio de Linux. Para esto se debe crear el archivo en **/etc/systemd/system/lyrestapi.service** (o el nombre de preferencia) con un contenido similar al siguiente (suponiendo que la aplicación se almacena en **/opt/lyrestapi**):
56
57 [Unit]\\Description=Libertya REST API\\After=network.target
58
59 [Service]\\Type=simple\\User=libertya\\WorkingDirectory=/opt/lyrestapi\\ExecStart=/usr/bin/java -jar /opt/lyrestapi/lyrestapi-1.0.0.jar\\Restart=always\\RestartSec=5
60
61 [Install]\\WantedBy=multi-user.target
62
63 Luego deberá ejecutarse:
64
65 sudo systemctl daemon-reload\\sudo systemctl enable lyrestapi\\sudo systemctl start lyrestapi
66
67 == Ejecución mediante Docker {{id name="ejecución-mediante-docker" /}}==
68
69 De contar con una imagen Docker de **lyrestapi**, es posible disparar un container, indicando las variables de entorno relevantes, por ejemplo:
70
71 docker run -p 8080:8080 –name lyrestapi_app -e DB_HOST=192.168.1.35 -e DB_NAME=libertya_test lyrestapi
72
73 Lógicamente, se deberán cambiar los argumentos de entorno según corresponda.
74
75 = Token {{id name="token" /}}=
76
77 El primer paso es obtener un token a fin de poder interactuar con la API.
78
79 curl -X POST \\\http:~/~/localhost:8080/token \\\-H ‘username: AdminLibertya’ \\\-H ‘password: AdminLibertya’ \\\-H ‘clientid: 1010016’ \\\-H ‘orgid: 0’
80
81 Lógicamente, bajo **username**, **password**, **clientid**, **orgid** deberán indicarse credenciales de acceso adecuadas según la información alojada en la tabla de usuarios (AD_User). Un usuario registrado en AD_User bajo AD_Org_ID = 0 puede generar un token tanto con **orgid = 0** como con cualquiera de las organizaciones pertenecientes a la compañía indicada bajo **clientid**. Un usuario registrado en AD_User bajo un AD_Org_ID distinto a 0 podrá generar un token únicamente para la organización en cuestión.
82
83 En caso de haber especificado correctamente la información de acceso, obtendremos un token que podremos utilizar hasta su fecha de expiración:
84
85 Bearer eyJhbGciOiJIUzUxMiJ9eyJqdGkiOiJKV1RCdWlsZGVyIiwi…CMscA2rV7PIa9TXu-vYiq6VCuA3Ghv5fI2xGOs9IfB2UMepKp3L6ulXQ
86
87 **El token obtenido contiene el usuario con el cual se obtuvo dicho token. Cualquier actividad que se realice sobre la API con este token serán registrados con dicho usuario**. Si en las operaciones no se especifica la propiedad **ad_org_id**, se utilizará el **orgid** indicado en la solicitud del token. Por consiguiente, si el token fue generado con la organización 0, entonces bajo ciertas operaciones que requieren un orgId distinto a cero (por ejemplo la creacion de un OP/RC), se deberá especificar la propiedad **ad_org_id** como parte del payload a enviar.
88
89 **NOTA**: Los días de validez de un token pueden ser configurados bajo la propiedad **security.token.exp.days** (ver apartado [[Preferencias>>#preferencias]]).
90
91 **NOTA**: Adicionalmente al requerimiento del token, el usuario con el cual se generó dicho token debe existir y encontrarse activo. De esta manera, el control y limitación de acceso y a la API abarca tanto la validación del token así como la verificación del usuario en cuestión. Puede desactivar esta validación adicional modificando la preferencia **security.access.validate.user**.
92
93 **MUY IMPORTANTE**: en ambientes de producción, debe modificarse la propiedad **security.token.secret** con un valor distinto al definido por defecto, ya sea modificando el application.properties o especificando mediante la variable de entorno **TOKEN_SECRET**.
94
95 = Uso {{id name="uso" /}}=
96
97 == Recuperación de entidades {{id name="recuperación-de-entidades" /}}==
98
99 Una vez obtenido el token, la operatoria es sencilla. Simplemente se debe indicar dicho token en el header del request.
100
101 Por ejemplo, recuperar una **entidad comercial**:
102
103 curl -X GET \\\http:~/~/localhost:8080/v1.0/bpartners/1012142 \\\-H ‘authorization: Bearer eyJhbGciOiJIUzUxMiJ9…HFfythd7EgIQ49QkR3KhmfQuAmB9jBRcQ89tiw’ \\\-H ‘content-type: application/json’
104
105 Respuesta:
106
107 {\\“cbpartnerId”: 1012436,\\“cbpGroupId”: 1000026,\\“acqusitioncost”: 0,\\“actuallifetimevalue”: 0,\\…,\\“trxenabled”: true,\\“updated”: “2023-06-02 12:15:04.745344”,\\“updatedby”: 1010717,\\“value”: “U819383ua42”\\}
108
109 Recuperar una **factura**:
110
111 curl -X GET \\\http:~/~/localhost:8080/v1.0/invoices/1022033 \\\-H ‘authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJqd…0NFu0-8h-KOf1xyrZMZvmQ8-0J77GsA’ \\\-H ‘content-type: application/json’ \
112
113 Respuesta, notar que la misma estará formada por un encabezado (header), así como sus lineas (lines) e impuestos (taxes):
114
115 {\\“**header**”: {\\“cinvoiceId”: 1022033,\\“cbpartnerId”: 1012145,\\“cbpartnerLocationId”: 1012158,\\“ccurrencyId”: 118,\\…\\“totallines”: 350,\\“updated”: “2023-06-09 08:53:10.749484”,\\“updatedby”: 1010717,\\},\\“**lines**”: [\\{\\“ad_client_id”: 1010016,\\“ad_org_id”: 1010053,\\“c_invoice_id”: 1022033,\\“c_invoiceline_id”: 1030150,\\“qtyinvoiced”: 2,\\…\\“updated”: “2023-06-09 08:53:09.707834”,\\“updatedby”: 1010717\\},\\{\\“ad_client_id”: 1010016,\\“ad_org_id”: 1010053,\\“c_invoice_id”: 1022033,\\“c_invoiceline_id”: 1030151,\\…\\“qtyinvoiced”: 5,\\“taxamt”: 0,\\“updated”: “2023-06-09 08:53:09.992148”,\\“updatedby”: 1010717\\}\\],\\“**taxes**”: [\\{\\“cinvoiceId”: 1022033,\\“ctaxId”: 1010087,\\“ad_client_id”: 1010016,\\“ad_org_id”: 1010053,\\“c_tax_id”: 1010087,\\…\\“taxbaseamt”: 350,\\“updated”: “2023-06-09 08:53:10.164017”,\\“updatedby”: 1010717\\}\\]\\}
116
117 === Detalle de campos referenciados {{id name="detalle-de-campos-referenciados" /}}===
118
119 En caso de que la propiedad **restapi.libertya.app.referencedValues** sea **Y**, además de recuperar la entidad en cuestión se recuperará la información asociada a las propiedades que referencian otras entidades, considerando que la información relevante se obtiene del campo value o bien de los campos identificadores del registro en cuestión. La información correspondiente puede obtenerse como una map dinamica de valores bajo la propiedad **referencedvalues**, con los sufijos por defecto **__detail** y **__value**:
120
121
122 {{code}}
123 ...
124 "updated": "2023-05-29 09:57:44.081033",
125 "updatedby": 1010717,
126 "**referencedvalues**": \[
127 {
128 "key": "ad\_client\_id\_\_detail",
129 "value": "Libertya"
130 },
131 {
132 "key": "ad\_client\_id\_\_value",
133 "value": "Libertya"
134 },
135 {
136 "key": "ad\_org\_id\_\_detail",
137 "value": "Default"
138 },
139 {
140 "key": "ad\_org\_id\_\_value",
141 "value": "Default"
142 },
143 {
144 "key": "c\_bpartner\_id\_\_detail",
145 "value": "AFIP\_ADMINISTRACION FEDERAL DE INGRESOS PUBLICOS"
146 },
147 {
148 "key": "c\_bpartner\_id\_\_value",
149 "value": "AFIP"
150 },
151 {
152 "key": "c\_bpartner\_location\_id\_\_detail",
153 "value": "CAPITAL FEDERAL YRIGOYEN HIPOLITO 370 Piso:04 Depto:148\_1012296"
154 },
155 {
156 "key": "c\_currency\_id\_\_detail",
157 "value": "ARS"
158 },
159 {
160 "key": "c\_doctype\_id\_\_detail",
161 "value": "Factura de Cliente"
162 },
163 {
164 "key": "c\_doctypetarget\_id\_\_detail",
165 "value": "Factura de Cliente"
166 },
167 {{/code}}
168
169 Los sufijos a utilizar pueden modificarse cambiando las propiedades: **restapi.libertya.app.referencedValuesValueSuffix** y **restapi.libertya.app.referencedValuesDetailSuffix**.
170
171 === Criterios de filtrado {{id name="criterios-de-filtrado" /}}===
172
173 Es posible especificar un conjunto de parametros de URL a fin de acotar la recuperación de entidades:
174
175 *. **limit**: Limita el número de elementos a retornar. en caso de no especificar un valor retornará 100 elementos únicamente\\
176 *. **page**: Numero de pagina a retornar, el cual en conjunto con limit se utiliza para paginado.\\
177 *. **order**: Criterio de ordenamiento por algún campo en particular.\\
178 *. **filter**: Filtrado avanzado de recuperación de elementos.\\
179 *. **fields**: Retornar unicamente los campos especificados.
180
181 Ejemplo:
182
183 *. http:~/~/localhost:8080/v1.0/bpartners?limit=3&page=2&order=c_bpartner_id&filter=“c_bpartner_id>1012141 and c_bpartner_id<1012145”&fields=name,value
184
185 Se está solicitando obtener **3 elementos** de **Entidades Comerciales**, con **desplazamiento a la pagina 2**, ordenados por **c_bpartner_id**, filtrando únicamente las ECs cuyo **ID sea mayor a 1012429** y recuperar solo las propiedades **name** y **value**.
186
187 curl -X GET \\\‘http:~/~/localhost:8080/v1.0/bpartners?limit=3&page=2&order=c_bpartner_id&filter=%22c_bpartner_id%3E1012429%22&fields=name%2Cvalue’ \\\-H ‘authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiJ…TGz6vhkHFfythd7EgIQ49QkR3KhmfQuAmB9jBRcQ89tiw’ \
188
189 Salida:
190
191 [\\{\\“name”: “Ent. Comercial Ejemplo 3”,\\“value”: “BP3”\\},\\{\\“name”: “Ent. Comercial Ejemplo 4”,\\“value”: “BP4”\\},\\{\\“name”: “Ent. Comercial Ejemplo 5”,\\“value”: “BP5”\\}\\]
192
193 === Navegabilidad {{id name="navegabilidad" /}}===
194
195 Ante un GET a una lista de entidades, El header de la respuesta contendrá además los links a **prev** y **next** para la correspondiente navegabilidad. Por ejemplo:
196
197 Para el siguiente GET query en donde se recuperan los elementos de la página 2:
198
199 *. http:~/~/localhost:8080/v1.0/allocations?fields=documentno,docstatus,created&sort=documentno&limit=10&page=2
200
201 Obtendermos además las siguientes propiedades en el header:
202
203 *. **Prev**: http:~/~/localhost:8080/v1.0/allocations?fields=documentno,docstatus,created&sort=documentno&limit=10&page=1\\
204 *. **Next**: http:~/~/localhost:8080/v1.0/allocations?fields=documentno,docstatus,created&sort=documentno&limit=10&page=3
205
206 == Creación de entidades {{id name="creación-de-entidades" /}}==
207
208 La estructura a respetar en la creación de entidades dependerá del tipo de entidad a crear. Por ejemplo, la creación de un artículo simplemente implica el volcado de la información relacionada con el artículo a crear. Sin embargo, para la creación de una factura es necesario volcar tanto el contenido de la cabecera como el de sus líneas. Se detallan a continuación algunos ejemplos de la estructura básica a enviar. En todos los casos es necesario realizar un HTTP POST al end-point correspondiente, incluyendo el correspondiente token JWT generado previamente.
209
210 === Nuevo artículo {{id name="nuevo-artículo" /}}===
211
212 curl –request POST \\\–url http:~/~/localhost:8080/v1.0/products \\\–header ‘Content-Type: application/json’ \\\–header ‘authorization: Bearer eyJhbGciOiJ…g0DLlRES7Q’ \\\–data ‘{\\“name”: “Articulo de ejemplo 2”,\\“value”: “EJE02”,\\“c_uom_id”: 100,\\“m_product_category_id”: 1010146,\\“c_taxcategory_id”: 1010048\\}’
213
214 === Nueva factura de cliente {{id name="nueva-factura-de-cliente" /}}===
215
216 curl –request POST \\\–url http:~/~/localhost:8080/v1.0/invoices \\\–header ‘Content-Type: application/json’ \\\–header ‘authorization: Bearer eyJhbGciOiJIUzUxMi…cDrGVAHJmg’ \\\–data ‘{\\“**header**”:\\{\\“c_doctype_id”: 1010507,\\“c_doctypetarget_id”: 1010507,\\“issotrx”: true,\\“c_bpartner_id”: 1012145,\\“c_bpartner_location_id”: 1012158,\\“c_currency_id”: 118,\\“m_pricelist_id”: 1010595,\\“c_paymentterm_id”: 1010083,\\“paymentrule”: “S”,\\“ad_user_id”: 100\\},\\“**lines**”:\\[\\{\\“ad_org_id”: “1010053”,\\“qtyinvoiced”: “2”,\\“pricesactual”: “30”\\}\\]\\}’
217
218 **NOTA**: Las propiedades **c_doctypetarget_id** / **c_doctype_id** / **issotrx** definen si la factura a crear es de cliente o de proveedor.
219
220 === Nuevo recibo de cliente {{id name="nuevo-recibo-de-cliente" /}}===
221
222 curl –request POST \\\–url http:~/~/localhost:8080/v1.0/allocations \\\–header ‘Content-Type: application/json’ \\\–header ‘authorization: Bearer eyJhbGciOiJIUzUxMi…pmcDrGVAHJmg’ \\\–data ‘{\\“c_bpartner_id”: 1012142,\\“c_doctype_id”: 1010568,\\“earlypayment”: false,\\“**invoices**”:\\[\\{\\“c_invoice_id”: “1022046”,\\“amount”: “1”\\}\\],\\“**payments**”:\\[\\{\\“c_pospaymentmedium_id”: “1010269”,\\“amount”: “1”,\\“c_payment_id”: “1012189”\\}\\]\\}’
223
224 **NOTA**: En la creación de entidades no es necesario especificar la **compañía** (ad_client_id) o la **organización** (ad_org_id) dado que éstos valores (al igual que createdby, updatedby) son automáticamente cargados a partir de la información del token JWT.
225
226 **NOTA**: La propiedad **restapi.libertya.app.useDefaults** permite especificar si se desean cargar los valores por defecto (según la definición en metadatos) en la creación de nuevas entidades previo al volcado de la información recibida en el payload.
227
228 **NOTA**: La propiedad **org.libertya.api.service.doc.complete** por defecto se encuentra activa, la cual hace que se complete el documento (pedido, remito, factura, etc.) que se está creando inmediatamente. Puede cambiar el comportamiento desactivando esta propiedad. De esta manera los documentos creados quedarán en estado borrador.
229
230 === Creación de documentos en etapas {{id name="creación-de-documentos-en-etapas" /}}===
231
232 La manera más sencilla de crear documentos (pedidos, remitos, facturas, etc.) es utilizando el end-point principal correspondiente, el cual recibe - por ejemplo - tanto la información de la cabecera como la de sus líneas. Sin embargo, en caso de ser necesario es posible crear un documento en sucesivas invocaciones (*), por ejemplo:
233
234 1. Creación de cabecera de factura bajo POST a **/v1.0/invoices** (solo con la información de la cabecera)\\
235 1. Creación de linea/s de factura bajo POST/s a **/v1.0/invoicelines**\\
236 1. Completado de factura bajo PUT a **/v1.0/invoices/{id_invoice}/process?action=CO**
237
238 (*) En este caso es necesario desactivar la propiedad **org.libertya.api.service.doc.complete** a fin de que la API no intente completar el documento automáticamente luego de crear la cabecera de la factura.
239
240 == Actualización de entidades {{id name="actualización-de-entidades" /}}==
241
242 La actualización de entidades no presenta mayores considerandos, salvo la convención para forzar a null una propiedad en particular. En caso de necesitar forzar a null una propiedad se debe enviar al cadena **[NULL]** como body de la propiedad en cuestión en el end point de la operación HTTP PUT correspondiente, por ejemplo:
243
244 curl –request PUT \\\–url http:~/~/localhost:8080/v1.0/inventories/1010562 \\\–header ‘Content-Type: application/json’ \\\–header ‘authorization: Bearer eyJhbGciOiJIUzUxM…A4Bnrwk5TAw’ \\\–data ‘{\\**“description”: “[NULL]”,**\\“isactive”: false\\}’
245
246 **NOTA**: En caso de ser necesario, es posible definir una cadena especial distinta a **[NULL]** modificando la propiedad **restapi.libertya.app.nullValue** en el archivo **application.properties**.
247
248 === Actualización de entidades con estructuras complejas {{id name="actualización-de-entidades-con-estructuras-complejas" /}}===
249
250 A diferencia de la creación de nuevas entidades con estructuras complejas como facturas, remitos, pedidos, las actualizaciones sobre la cabecera y sus correspondientes líneas se realizan de manera independiente, con endpoints específicos en cada caso. Por ejemplo:
251
252 **HTTP POST http:~/~/localhost:8080/v1.0/invoices** para crear una factura, enviando el JSON con la estructura completa de cabecera / lineas.
253
254 **HTTP PUT http:~/~/localhost:8080/v1.0/invoicelines/{id_linea_de_factura}** para actualizar una línea de factura, enviando el JSON con la estructura de las propiedades a modificar de la línea de factura únicamente.
255
256 == Eliminación de entidades {{id name="eliminación-de-entidades" /}}==
257
258 La eliminación de entidades simplemente implica realizar un HTTP DELETE al endpoint correspondiente. Por ejemplo:
259
260 curl –request DELETE \\\–url http:~/~/localhost:8080/v1.0/products/1012096 \\\–header ‘authorization: Bearer eyJhbGciOiJIUzU…aUjpmcDrGVAHJmg’ \
261
262 == Procesamiento de entidades {{id name="procesamiento-de-entidades" /}}==
263
264 Las entidades de tipo documento (pedidos, remitos, facturas, etc.) pueden ser procesadas (cerradas, completadas, anuladas, revertidas, etc.) mediante un HTTP PUT al endpoint correspondiente, indicando además el tipo de acción a realizar:
265
266 *. CO: Completar\\
267 *. CL: Cerrar\\
268 *. VO: Anular\\
269 *. RE: Revertir
270
271 Por ejemplo:
272
273 curl –request PUT \\\–url ‘http:~/~/localhost:8080/v1.0/inventories/1010584/process?action=VO’ \\\–header ‘Content-Type: application/json’ \\\–header ‘authorization: Bearer eyJhbGciOiUzUxMiJ9.eyJq…f5GT3mvE6D2uvg’ \
274
275 **NOTA**: Si la propiedad **org.libertya.api.service.doc.complete** se encuentra activa, los documentos se completarán automáticamente en la creación de los mismos.
276
277 == Gestion dinámica de propiedades de entidades {{id name="gestion-dinámica-de-propiedades-de-entidades" /}}==
278
279 La propiedad **additionalvalues** eventualmente contenida en cada JSON permite gestionar propiedades adicionales pertenecientes a la entidad de manera dinámica. Si por algún motivo existieran columnas adicionales (en los metadatos de Libertya y a nivel físico) a las originalmente soportadas en las operaciones definidias en la API al momento de su release, es posible gestionar la información de dichos campos mediante el uso de la propiedad **additionalvalues**, bajo un esquema **key**/**value**. Esta funcionalidad está soportada tanto en la creación como en la actualización de entidades, así como en la recuperación de las mismas.
280
281 Para los ejemplos que se muestran a continuación, se supone que la instalación de un plugin ad-hoc creó dos nuevas columnas sobre la tabla usuario, llamadas **Facebook_ID** y **Instagram_ID**, las cuales no son parte de la estructura original de la API.
282
283 **NOTA**: También es posible actualizar la estructura de las entidades de Libertya REST API a fin de que considere esta ampliación estructural, pero en este caso será necesario regenerar y recompilar los fuentes del proyecto el proyecto LYRESTAPI en función de la estructura de la base de datos donde se utilizar la API.
284
285 === Carga de entidades con eventuales campos adicionales {{id name="carga-de-entidades-con-eventuales-campos-adicionales" /}}===
286
287 Se puede realizar la carga sobre las propiedades **Facebook_ID** y **Instagram_ID** mediante el uso de la property **additionalvalues** de la siguiente manera:
288
289 curl –request POST \\\–url http:~/~/localhost:8080/v1.0/users \\\–header ‘Content-Type: application/json’ \\\–header ‘authorization: Bearer eyJhbGciOiJIUzUxM…5GT3mvE6D2uvg’ \\\–data ‘{\\“name” : “un usuario de ejemplo”,\\“**additionalvalues**”: [\\{\\“key”: “facebook_id”,\\“value”: “myfacebookid”\\},\\{\\“key”: “instagram_id”,\\“value”: “myinstagramid”\\}\\]\\}’
290
291 === Actualizacion de entidades con eventuales campos adicionales {{id name="actualizacion-de-entidades-con-eventuales-campos-adicionales" /}}===
292
293 De manera similar a la creación de nuevas entidades, se puede realizar la actualizacion de las propiedades **Facebook_ID** y **Instagram_ID** de una entidad existente mediante el uso **additionalvalues** de la siguiente manera:
294
295 curl –request PUT \\\–url http:~/~/localhost:8080/v1.0/users/1010716 \\\–header ‘Content-Type: application/json’ \\\–header ‘authorization: Bearer eyJhbGciOiJIUzUxMiJ…5GT3mvE6D2uvg’ \\\–data ‘{ “description” : “una descripcion”,\\“**additionalvalues**”: [\\{\\“key”: “facebook_id”,\\“value”: “myotherfacebookid”\\},\\{\\“key”: “instagram_id”,\\“value”: “myotherinstagramid”\\}\\]\\}’
296
297 === Visualización de entidades con eventuales campos adicionales {{id name="visualización-de-entidades-con-eventuales-campos-adicionales" /}}===
298
299 Al ejecutar la recuperación del usuario obtendremos la estructura predefinida y bajo la propiedad **additionalvalues** la información adicional (**Facebook_ID** y **Instagram_ID**):
300
301 curl –request GET \\\–url http:~/~/localhost:8080/v1.0/users/1097718 \\\–header ‘Content-Type: application/json’ \\\–header ‘authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJqd…GeW5twOCOf5GT3mvE6D2uvg’ \
302
303 {\\“ad_client_id”: 1010016,\\“ad_user_id”: 1097718,\\…\\“**additionalvalues**”: [\\{\\“key”: “facebook_id”,\\“value”: “foobarfacebookid”\\},\\{\\“key”: “instagram_id”,\\“value”: “foobarinstagramid”\\}\\],\\…\\}
304
305 == Gestion de usuarios {{id name="gestion-de-usuarios" /}}==
306
307 La API soporta la gestión de usuarios (creación, modificación, eliminación, recuperación). Sin embargo, considerando que a partir de la información de usuarios se podría realizar operaciones sensibles o que afecten la seguridad del sistema, existe la posibilidad de deshabilitar estas operaciones mediante la siguiente propiedad de **application.properties**:
308
309 # Operaciones de gestion de usuarios habilitados: (C)reate, (R)etrieve, (U)pdate, (D)elete\\org.libertya.api.service.user.operations=CRUD
310
311 Si se desea quitar alguna de las operaciones relacionadas con la gestión de usuarios, simplemente deben quitarse los permisos correspondientes C, R, U o D según sea necesario.
312
313 **NOTA**: En la recuperación de entidades de tipo usuarios, el campo password es omitido del conjunto de información a retornar.
314
315 = Log de eventos {{id name="log-de-eventos" /}}=
316
317 Ante cada evento se volcará al log la información relacioanda con el evento en cuestión, por ejemplo:
318
319 2023-06-15 08:54:08.263 INFO - BPartnerController.addBPartner Arg1: class BPartner {, acqusitioncost: 0.0000, …, value: U8119383ua42, },\\2023-06-15 08:54:08.377 INFO - BPartnerController.addBPartner: <409 CONFLICT Conflict,No se pudieron guardar los cambios: : Existe un registro de Entidad Comercial que ya contiene el valor U8119383ua42 para el campo Clave. El valor de este campo no puede ser duplicado.,[]>
320
321 2023-06-15 09:03:26.630 INFO - InvoiceController.retrieveInvoice Arg1: 1022033,\\2023-06-15 09:03:27.239 INFO - InvoiceController.retrieveInvoice: <200 OK OK,class InvoiceDocument {, header: class Invoice {, adClientId: 1010016, adOrgId: 1010053, … authmatch: true,
322
323 La ubicación del archivo de log, así como el formato y límites pueden ser especificados en el archivo **application.properties**.
324
325 # Log de eventos - Ubicacion - Formato - Historial\\logging.file.name=~${LOG_FILENAME:/tmp/lyrestapi.log}\\logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} %level - %msg%n\\logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} %level - %msg%n\\logging.file.max-size=20MB\\logging.file.max-history=7\\# Limitar el tamaño del contenido a almacenar para cada request y response (-1 = sin limite)\\logging.request.max.length=-1\\logging.response.max.length=300
326
327 En donde:
328
329 *. **logging.file.name** permite indicar la ubicación y nombre del archivo a generar\\
330 *. **logging.pattern.*** permite especificar el formato de log\\
331 *. **logging.file.max-*** permite limitar el tamaño de archivos e historial\\
332 *. **logging.request.max.length** permite indicar la longitud a almacenar del request (o -1 si queremos almacenarla por completo)\\
333 *. **logging.response.max.length** idem anterior pero para responses
334
335 = API Docs y API UI {{id name="api-docs-y-api-ui" /}}=
336
337 Accediendo a **localhost:8080/api-docs** y **localhost:8080/api-docs.yaml** se puede recuperar la definición completa de los end-points de todas las operaciones que soporta Libertya REST API, en formato JSON como YAML respectivamente.
338
339 Accediendo a **localhost:8080/swagger-ui** es posible acceder a la visualización de las operaciones mediante la herramienta **Swagger UI**:
340
341 [[image:image1.png]]
342
343 **NOTA**: A fin de poder realizar las pruebas pertinentes bajo Swagger UI, es necesario previamente introducir un token (JWT) válido obtenido previamente (mediante la operación **POST** **localhost:8080/token** detallada al principio de este documento), sin incluir el prefijo Bearer.
344
345 [[image:image2.png]]
346
347 La funcionalidad de API Docs y API UI funcionalidad puede ser desactivada modificando a **false** las siguientes propiedades de **application.properties**:
348
349 *. springdoc.api-docs.enabled=true\\
350 *. springdoc.swagger-ui.enabled=true
351
352 = Información operacional de la aplicación {{id name="información-operacional-de-la-aplicación" /}}=
353
354 Accediendo a **http:~/~/localhost:8080/monitor** es posible acceder a información sobre la aplicación, salud de la misma, métricas, etc., mostrando la nómina de links habilitados:
355
356 {\\“_links”: {\\“self”: {\\“href”: “http:~/~/localhost:8080/monitor”,\\“templated”: false\\},\\“health”: {\\“href”: “http:~/~/localhost:8080/monitor/health”,\\“templated”: false\\},\\“info”: {\\“href”: “http:~/~/localhost:8080/monitor/info”,\\“templated”: false\\},\\…\\}
357
358 Por ejemplo accediendo a **http:~/~/localhost:8080/monitor/health** obtenemos:
359
360 {\\“status”: “UP”,\\“components”: {\\“diskSpace”: {\\“status”: “UP”,\\“details”: {\\“total”: 943412031488,\\“free”: 233513222144,\\“threshold”: 10485760,\\“exists”: true\\}\\},\\“ping”: {\\“status”: “UP”\\}\\}\\}
361
362 **NOTA**: Habilitar las métricas sin restricción puede representar un riesgo de seguridad, ya que dichas métricas pueden proporcionar información detallada sobre el estado interno y el comportamiento de la aplicación en ejecución. Esto puede abarcar datos sensibles o confidenciales que podrían ser aprovechados por potenciales atacantes para comprender mejor la arquitectura de la aplicación e identificar vulnerabilidades. Es por este motivo que por defecto la aplicación solo habilita las métricas básicas de información y salud de la aplicación.
363
364 En caso de querer ampliar las métricas deberá cambiar la siguiente línea de **application.properties**:
365
366 management.endpoints.web.exposure.include=info,uptime,health
367
368 incluyendo otras métricas adicionales, por ejemplo:
369
370 management.endpoints.web.exposure.include=info,uptime,health**,logfile,caches,dbinfo**
371
372 o si por ejemplo se desean habilitar todas las métricas:
373
374 management.endpoints.web.exposure.include=*****