6. Instrucciones de uso
Llamádas directas
El modo más básico de utilizar el motor de auditoría es creando un objeto de tipo AuditEvent e insertarlo en la auditoría. En el siguiente ejemplo puede verse como crear el objeto e invocar al motor de auditoría. Este modo puede utilizarse en cualquier parte de nuestro código:
// Creación del evento
AuditEvent event = new AuditEvent();
event.setObject("Episodio"); // Objeto auditado
event.setAction("Cancelar"); // Acción a realizar
// Listado de campos a auditar
// Los campos con ID "nuhsa", "episodio" y "unidad" se mapearán automáticamente
// con las columnas de mismo nombre en la tabla de adutoría.
// El resto de campos se almacenarán como información adicional
event.addField(new Field("nuhsa", pIn.getNuhsa()));
event.addField(new Field("episodio", "123456"));
event.addField(new Field("unidad", "1111"));
event.addField(new Field("apellido1", pIn.getApellido1()));
// Resultado: 0 Correcto, 1 Incorrecto
event.setResultCode(new Random().nextInt() % 2);
// Datos opcionales. Si no se indican se recuperarán del MetaData configurado
event.setActor("jparriazap");
event.setActorProfile("medico");
event.setActorService("Medicina Interna");
event.setOrigin("MPA");
// Llamada DIRECTA al motor de auditoría
AuditManager.getInstance().audit(event);
Anotaciones
La auditoría por anotaciones permiten configurar puntos de auditoría fácilmente sin necesidad de añadir código adicional a nuestros proyectos. Dentro de la auditoría por anotaciones nos encontramos con varios modos de funcionmiento de la librería, siendo el modo Manual el que se propone desde el área de gobernanza como el más indicado para las necesidades del SAS.
Es imporante destacar que por el propio funcionamiento de las anotaciones y los insterceptores de Java EE, este mecanismo funciona solamente cuando nos encontremos en un contexto CDI.
hay que añadir tambien en el bean.xml el interceptor de auditoria para que funcionen las anotaciones:
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class org.audit4j.integration.cdi.AuditInterceptor </class>
</interceptors>
</beans>
Las anotaciones disponibles son las siguientes:
@Audit: Es la anotación principal que indica que un método debe ser auditado. Permite las siguientes propiedades:
- object: Necesario para especificar el objeto sobre el que se está auditando.
- action: Acción que se está realizando sobre el objeto auditado.
- fields: Listado de anotaciones de tipo @AuditField, donde se especifican los campos exactos a auditar.
@AuditField: Es aplicable tanto a parámetros de un método como a atributos de una clase. Tiene las siguientes propiedades:
- field: Nombre que se le desea dar al parámetro o atributo auditado en la tabla de auditoría.
- fieldPath: Ruta hasta el parámetro. Por ejemplo, si el tercer párametro de entrada de un método a auditar es de tipo Episodio y este tiene un atributo de tipo Paciente y este a su vez tiene un atributo con el nuhsa, para auditar el nuhsa pondríamos el siguiente path: "[2].episodio.nuhsa"
@DeIdentify: Se utiliza para anonimizar parámetros sensibles que desean ser auditados. Tiene las siguientes propiedades:
- left: Anonimizar por la izquierda. Ejemplo: @DeIdentify(left=3) -> ***456789
- right: Anonimizar por la derecha. Ejemplo: @DeIdentify(right=3) -> 123456***
- fromLeft: Anonimizar todos los carácteres a partir de una posición, comenzando a contar por la izquierda. Ejemplo: @DeIdentify(fromLeft=3) -> 123******
- fromRight: Anonimizar todos los carácteres a partir de una posición, comenzando a contar por la derecha. Ejemplo: @DeIdentify(fromRight=3) -> ******789
@IgnoreAudit: Indica que un parámetro de un método debe ser ignorado. Sólo tiene sentido usar esta anotación en la auditoría por defecto, donde se auditan todos los parámetros de un método menos los marcados con esta anotación.
Default
Modo de funcionar por defecto, es el que aplica si no se indica el comando annotationTransformer en el fichero de configuración.
En este modo, se auditan todos los parámetros de entrada de un método a excepción de los marcados como @IgnoreAudit.
public class Paciente {
private long id;
private String nuhsa;
private String nombre;
@AuditIgnore
private String apellido1;
private String apellido2;
...
}
@Stateless
public class Pacientes {
@Audit (
object = "Paciente",
action = "Buscar"
)
public Paciente buscaPacienteDefault(Paciente pacienteIn, @IgnoreAudit int edad, boolean activo) {
...
}
}
En este ejemplo, todos los objetos que inyecten el servicio "Pacientes" e invoque al método "buscaPacienteStrict" generará un registro en la auditoría indicando que se ha actuado sobre el objeto "Paciente", realizando la acción "Buscar" y se auditarán todos los parámetros de entrada recursivamente (auditando también todos los atributos de los objetos complejos no marcados con @IgnoreAudit) salvo el parametro "edad" por estar marcado con la anotación @IgnoreAudit
Strict
El modo estricto audita sólo aquellos parámetros y atributos marcados a conciencia con la anotación @AuditField. En el caso de que uno de los parámetros de entradas no sea de tipo primitivo Java, el motor de auditoría recorrerá recursivamente los atributos internos y auditará sólo aquellos que estén marcados como @AuditField.
Para hacer uso de este módo es necesario indicar el comando annotationTransformer con el siguiente valor: org.audit4j.annotation.transformer.StrictAnnotationTransformer
public class Paciente {
private long id;
@AuditField(field="nuhsa")
private String nuhsa;
@AuditField(field="nombre")
private String nombre;
private String apellido1;
private String apellido2;
...
}
@Stateless
public class Pacientes {
@Audit (
object = "Paciente",
action = "Buscar"
)
public Paciente buscaPacienteStrict(@AuditField(field = "paciente") Paciente pacienteIn, @AuditField(field = "edad") int edad, boolean activo) {
...
}
}
En este ejemplo, todos los objetos que inyecten el servicio "Pacientes" e invoque al método "buscaPacienteStrict" generará un registro en la auditoría indicando que se ha actuado sobre el objeto "Paciente", realizando la acción "Buscar" y se auditarán los atributos "paciente.nuhsa", "paciente.nombre" y el segundo parámetro (edad).
Manual
El modo manual permite realizar toda la configuración a auditar directamente sobre la anotación padre @Audit o en ficheros de configuración XML. Al igual que en el modo estricto, auditará sólo aquellos parámetros y atributos marcados como auditables.
Para hacer uso de este módo es necesario indicar el comando annotationTransformer con el siguiente valor: org.audit4j.annotation.transformer.ManualAnnotationTransformer
Desde el área de gobernanza se aconseja usar este método para conseguir así un código resultante más limpio.
Dentro de este método nos encontramos dos formas utilizarlo.
Anotación
Permite indicar toda la configuración de la auditoría en la misma anotación @Audit:
public class Paciente {
private long id;
private String nuhsa;
private String nombre;
private String apellido1;
private String apellido2;
...
}
@Stateless
public class Pacientes {
@Audit (
object = "Paciente",
action = "Buscar",
fields = {
@AuditField(field="nuhsa", fieldPath="[0].nuhsa"),
@AuditField(field="id", fieldPath="[0].id"),
@AuditField(field="apellido1", fieldPath="[0].apellido1"),
@AuditField(field="edad", fieldPath="[1]"),
@AuditField(field="apellido2", fieldPath="result.apellido2")
}
)
public Paciente buscaPacienteAnotacion(Paciente pacienteIn, int edad, boolean activo) {
...
}
}
En este ejemplo, todos los objetos que inyecten el servicio "Pacientes" e invoque al método "buscaPacienteAnotacion" generará un registro en la auditoría indicando que se ha actuado sobre el objeto "Paciente", realizando la acción "Buscar" y se auditarán los atributos "nuhsa", "id" y "apellido1" del primer parámetro de entrada (pacienteIn), el segundo parámetro (edad) y del objeto devuelto como resultado, el atributo "apellido2"
XML
Permite indicar toda la configuración de la auditoría en un fichero XML, centralizando toda la configuración de auditoría de todo el proyecto completo en un sólo fichero de configuración. En este caso, a nivel de método sólo será necesario marcarlo como @Audit y no será necesario especificar más propiedades:
public class Paciente {
private long id;
private String nuhsa;
private String nombre;
private String apellido1;
private String apellido2;
...
}
@Stateless
public class Pacientes {
@Audit
public Paciente buscaPacienteXML(Paciente pacienteIn, int edad, boolean activo) {
...
}
}
<?xml version="1.0" encoding="UTF-8"?>
<auditConfiguration>
<method>...</method>
<method path="es.ja.csalud.sas.webexample.service.boundary.Pacientes.buscaPacienteXML" object="Paciente" action="Buscar">
<auditField field="nuhsa" fieldPath="[0].nuhsa"/>
<auditField field="id" fieldPath="[0].id"/>
<auditField field="apellido1" fieldPath="[0].apellido1"/>
<auditField field="edad" fieldPath="[1]"/>
<auditField field="apellido2" fieldPath="result.apellido2"/>
</method>
<method>...</method>
<method>...</method>
</auditConfiguration>
En este ejemplo, todos los objetos que inyecten el servicio "Pacientes" e invoque al método "buscaPacienteXML" generará un registro en la auditoría indicando que se ha actuado sobre el objeto "Paciente", realizando la acción "Buscar" y se auditarán los atributos "nuhsa", "id" y "apellido1" del primer parámetro de entrada (pacienteIn), el segundo parámetro (edad) y del objeto devuelto como resultado, el atributo "apellido2"
Campos especiales
Como puede verse en el apartado "¿Qué se debe auditar en el SAS?" de la normativa de auditoría, existen una serie de campos básicos que deben ser auditados, igualmente se reserva un espacio adicional para otros campos no básicos que también deban ser auditados.
Para poder especificar qué campos corresponden con cada uno de estos campos básicos se han definido un patrón de etiquetado que debe ser seguido para el buen funcionamiento del sistema. De esta forma, se definen los siguientes elmentos (No se diferencia entre mayúsculas y minúsculas):
- OPERADOR: Login del operador que realiza la acción
- OPERADOR_PERFIL: Perfil del operador que realiza la acción
- OPERADOR_UNIDAD: Unidad funcional del operador que realiza la acción
- NUHSA: Identificación del usuario o paciente
- EPISODIO: Episodio sobre el que se está realizando la acción
- UNIDAD_PACIENTE: Unidad funcional del episodio sobre el que se realiza la acción.
Mención especial requiere los campos Operador, Operador_Perfil y Operador_Unidad, ya que estos campos son normalmente recuperados de la implementación de la interfaz MetaData propia de cada producto. Pero pueden existir casos en los que la aplicación no tenga sesión (Aplicaciones REST) en donde no sea posible realizar una implementación de MetaData para recuperar datos del contexto. En estos casos esta información deberá ser configurada manualmente en cada evento a auditar.
Por orden de prioridades, el motor de auditoría mirará en primer lugar si se ha configurado un valor específico para un evento, en caso de no existir lo buscará en la implementación de la clase MetaData y en caso de no existir insertará un valor por defecto.
Ejemplo
@Stateless
public class Pacientes {
@Audit (
object = "Paciente",
action = "Buscar",
fields = {
@AuditField(field="operador", fieldPath="[0].login"),
@AuditField(field="operador_perfil", fieldPath="[0].perfil"),
@AuditField(field="nuhsa", fieldPath="[1].nuhsa"),
@AuditField(field="id", fieldPath="[1].id"),
@AuditField(field="apellido1", fieldPath="[1].apellido1"),
@AuditField(field="apellido2", fieldPath="[1].apellido2"),
@AuditField(field="edad", fieldPath="[2]")
}
)
public Paciente buscaPaciente(Usuario user, Paciente pacienteIn, int edad, boolean activo) {
...
}
}
En este ejemplo vemos como se ha configurado para que los campos operador y operador_perfil sean cargados directamente del primer parámetro de la función auditada. En el caso de la unidad del operador, al no estar configurado en el evento, se recuperará de la implementación de MetaData que se haya realizado y en caso de no existir el registro de auditoría se creará con el valor por defecto ("Default User Service")