Documentos de Académico
Documentos de Profesional
Documentos de Cultura
AUTOATENCIÓN V1.0
Documentación para tener los lineamientos generales que se debe seguir en el desarrollo de aplicaciones y
es la base para la creación de componentes(servicios por dominio) y la comunicación de las mismas de forma
asíncrona y síncrona en la infraestructura azure cloud.
Como parte fundamental de las aplicaciones bancarias en la nube es importante tener un diseño simple,
seguro y entendible de la arquitectura y las interacciones entre los componentes que lo integran con el fin de
cumplir con los objetivos de negocio.
Componentes de la arquitectura cloud
AZURE CLOUD
En esta se sección definimos los componentes azure que usamos y las respectivas nomenclaturas que se
deben de seguir como buenas practicas.
Api Management Interno: Exposición de las api’s https de selfcare, cuyo objetivo de esta APIM es
comunicación entre claster o la red interna del banco.
Azure Key Vault: Almacén de certificados TLS 1.2, keys y secretos de la aplicación. Así mismos
gestionará el acceso a los recursos.
AKS: Contenedor de 3 nodos worker para despliegue de los servicios ligeros y configuración de secrets.
Azure Redis Cache: Almacenamiento temporal y de gran velocidad como son tablas tipo o catálogo,
datos de seguridad.
Azure Service Bus: Tópicos de mensajería asíncrona para coumunicación de servicio ligero y tareas que
no requieran confirmación secuencial del proceso.
Azure Storage : almacenamiento cargas masivas e imágenes para el uso de la aplicación, volumes para
los servicios, es obligatorio si se guarda datos sensibles deben cifrarse en reposo (HSM).
Azure Scheduler: Scheduler funciona aunque se produzcan errores en la red, los equipos o el centro de
datos, por lo que los trabajos programados continúan ejecutándose puntualmente. Si es necesario,
cambia automáticamente a un centro de datos alternativo en la misma región.
OTHER CLOUDS
New Relic: Monitoreo y AMP de la infraestructura azure y de la aplicación backend y frontend.
ONPREMISE
Api Connect: Es el punto donde se disponibiliza la api para que los canales se suscriban y puedan hacer
uso de ello.
HSM: Máquina para generación de llave mediante tres tarjetas y tres custodios
Patrones de Diseño
Los patrones de diseño deben de usarse en la capa de lógica de negocio de forma obligatoria según apliquen
y solo en casos excepcionales y justificados no se usaran.
Patrones creacionales
Abstract Factory
Factory Method: Una buena práctica es que la implementación del método no debe superar los 30
líneas de código, si sucede se debe dividir en otros métodos más pequeños..
Builder
Prototype
Patrones estructurales
Adapter
Bridge
Decorator: @Qualifiers, @Service("nameService), @Repository("nameRepository).
Facade
Proxy
Patrones de comportamiento
Command: Una buena práctica es que los métodos no deben recibir más de tres parámetros si sucede
este escenario encapsular en un objeto.
Chain of responsibility
Mediator
Observer
State
Visitor
Cada servicio ligero que se crea debe tener un nombre que siga la siguiente estructura:
selfcare-<domain_name>
ConfigServer
DiscoveryServer
EdgeServer
TemporaryLock
CardBlock
Bitbucket
Estructura arquitectónica de un Servicio pot
Dominio
Para la construcción de los servicios se usara como estándar el framework Spring Boot cuya clase principal es
el único punto de arranque o ejecución del servicio.
@SpringBootApplication
public class <dominio-miniservicio>Application {
Versiones de SpringBoot
Para la construcción de las aplicaciones se usarán las siguientes librerías y las siguientes versiones de
springboot.
spring-boot-2.1.0.RELEASE
spring-boot-starter-actuator-2.1.0.RELEASE
spring-cloud-starter-config-2.1.0.M1
spring-boot-starter-test-2.1.0.RELEASE
spring-boot-starter-web-2.1.0.RELEASE
spring-cloud-starter-netflix-eureka-client-2.1.0.M1
spring-cloud-starter-netflix-eureka-server-2.1.0.M1
spring-cloud-config-server-2.1.0.M1
spring-cloud-starter-netflix-zuul-2.1.0.M1
spring-boot-starter-data-redis-2.1.0.RELEASE
spring-boot-starter-webflux-2.1.0.RELEASE
spring-boot-devtools-2.1.0.RELEASE
spring-boot-starter-security-2.1.0.RELEASE
spring-security-oauth2-autoconfigure-2.0.0.RELEASE
spring-security-jwt-1.0.5.RELEASE
spring-restdocs-mockmvc-1.0.5.RELEASE
lombok-1.18.4
mongo-java-driver-3.8.2
gson-2.8.2
commons-cli-1.4
jackson-databind-2.9.7
azure-keyvault-1.1.2
httpcore-4.4.10
commons-lang3-3.8.1
rest-assured-2.1.0.RELEASE
adal4j-1.6.3
azure-keyvault-1.1.2
NOTA: Cualquier librería adicional al estándar que se requiera usar debe ser coordinado y actualizado
en este documento.
selfcare-<domain_name>
selfcare-<domain_name>-app
src/main/java
...
src/main/resources
application.yml
bootstrap.yml
src/main/test
...
pom.xml
Dockerfile
selfcare-<domain_name>.yml
selfcare-<domain_name>-repo
pom.xml
selfcare-<domain_name>-core
pom.xml
selfcare-<domain_name>-esb
pom.xml
selfcare-<domain_name>-mocks
pom.xml
pom.xml
Los componentes cros que seran usados por los servicio ligero tendran la sigiente estructura:
selfcare-<domain_cross_name>
selfcare-<domain_cross_name>-commons
src/main/java
...
src/main/resources
application.yml
src/main/test
...
pom.xml
pom.xml
...
<modules>
<module>selfcare-<domain_name>-app</module>
<module>selfcare-<domain_name>-core</module>
<module>selfcare-<domain_name>-esb</module>
<module>selfcare-<domain_name>-repo</module>
<module>selfcare-<domain_name>-moks</module>
</modules>
...
selfcare-<domain_name>-app: Módulo principal y único del servicio, este será empaquetado e instalado en
los contenedores y para cuyo objetivo se usara los archivos de Dockerfile y selfcare-<domain_name>.yml
src/main/java: En esta sección se tienen los paquetes del servicio dentro del grupoId definido en el
maven [pe.interbank.selfcare].
main.test: En esta carpeta se tiene las pruebas unitarias que se usaran en TDD.
main.resources: En la carpeta resources tiene dos archivos de configuración: application.yml y
bootstrap.yml
...
- controller
- web //todo api se expone con el prefijo [api -> segurizados con oauth2, pub ->
públicas u otros formatos de segurización]
- config //Configuraciones adicionales de miniservicio decorados con @Component
- service //Interfaz de la lógica de negocio
- impl //Implementación de la lógica de negocio.
- dto
- request //contrato de ingreso al miniservicio
- response //contrato de respuesta del miniservicio
...
...
selfcare-<domain_name>-core: El componente que contiene los java beans, DTOs, Enums, clases utilitarias.
selfcare-<domain_name>-esb: El componente que se encarga de la integración entre servicio ligero o de un
servicio con algún otro componente para la gestión de tareas asíncronas mediante el patrón de publicación y
suscripción haciendo uso de los tópicos.
Publicación de mensajes
Suscripción a los mensajes
Reintento para procesar mensaje
Tópico de mensajes no procesados
selfcare-<domain_cross_name>-lib: El componente cros será usada por todos los servicio ligero que lo
requieran.
//Clase simple
public class Credit {..}
//Clase compuesta
public class CreditCustomer {..}
Objeto: Los objetos en ingles, siempre la primera letra en minuscula y si son compuesto los siguientes
nombres con los iniciales en mayúscula sin espacio. Este es un ejemplo de objeto:
//Objeto simple
Credit credit = new Credit(<parameters>);
//Objeto compuesto
Credit creditPerson = new Credit(<parameters>);
En lo sumo usar los principios de herencia, agregación y composición de acuerdo al escenario que aplique
el negocio.
Método: Los métodos son conjunto de instrucciones definidas para lograr un objetivo tanto de negocio o
sistema y estas deben seguir los siguientes lineamientos:
Atributo: Las variables en inglés y deben iniciar en minúscula, si son compuesto los iniciales después de la
primera palabra en mayúscula. Este es un ejemplo de atributo:
Comentario: los comentarios se deben realizar en idioma inglés, claro y siempre explicar el objetivo que
tiene la clase o método. Este es un ejemplo de clase:
Excepciones java: Las excepciones en java deben ser customizadas por cada capa, modulo y clase funcional,
no se debe usar excepciones por defecto generadas por JVM.
Errores genéricos:
Errores personalizados por miniservicio
En la primera línea se indica el nombre del App el cual debe ser igual al indicado en el archivo
newrelic.yml; propiedad: app_name.
El primer plugin indicado permite descomprir el contenido del agente de new relic: newrelic-agent-
4.8.0.jar, tener en consideración que se debe descargar la ultima versión del agente.
El segundo plugin indicado se indican configuraciones generales del agente de new Relic.
El tercer plugin, se debe indicar para indicar la clase principal Main que debe ejecutarse ya que el
agente New Relic también cuenta con una clase con método main. Para ello se debe colocar la
paqueteria en donde se encuentra la clase principal del miniservicio en el tag: < mainClass>
Como último paso se debe agregar la dependencia del agente indicando su ultima versión.
Luego de realizado los cambios en el archivo .pom del miniservicio, se debe realizar la compilación del
mismo.
Finalmente para poder ejecutar el minisercicio desde la máquina local se debe agregar en la sección VM
los siguientes parámetros:
-javaagent:Ruta completa donde se encuentra ubicado el archivo: newrelic.jar
-Dnewrelic.config.file=Ruta completa donde se encuentra ubicado el archivo:newrelic.yml; tener en
consideración que éste archivo debe encontrarse en la misma ruta en donde se ubica el agente de
new relic(newrelic.jar).
-Dnewrelic.environment=<profile> ejemplo:(-Dnewrelic.environment=DEV); ambiente de ejecución
de New Relic.
<!--
<name>Name Miniservicio</name>: Debe coincidir con lo indicado en el archivo newrelic.yml
-->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>newrelic-agent</includeArtifactIds>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Premain-Class>com.newrelic.bootstrap.BootstrapAgent</Premain-
Class>
<Can-Redefine-Classes>true</Can-Redefine-Classes>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>pe.interbank.selfcare.[domain].[Domain]Application</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<dependency>
<groupiId>com.newrelic.agent.java</groupId>
<artifactId>newrelic-agent</artifactId>
<version>${newrelic-version}</version>
<scope>provided</scope>
</dependency>
Modificar este dato con el valor obtenido de la página de new Relic después de haberse
license_key
logeado con su cuenta.
Indicar el nombre del(os) miniservicio(s) indicado en el pom tag separados por (;) en el
app_name
caso de requerirse realizar el monitoreo de más de un miniservicio.
En new relic no se deben guardar datos sensibles de Resquest y Response para este objetivo se usara una
colección en DynamoDB.
El nombre debe comenzar con el nombre de la aplicación tal como se declara en el servicio
correspondiente. Por ejemplo: - spring.application.name = blockcard
Si hay diferentes perfiles, el nombre del perfil debe aparecer después del nombre de la aplicación. Por
ejemplo: - blockcard-uat.yml, blockcard-dev.yml ( o .yml )
GET / {application}/{profile}[/{label}]
https://10.11.40.25:5020/ibk/sit/api/account/v1/accountid
https://ibbus:443/ibk/srv/MPO/Captaciones/cuenta.anular/v1.0
Recomendaciones
Análisis: Analizar la entrada y salida del proveedor, sea de mainframe, o de un distribuido, debido a que
por su antigüedad manejaban interfaces muy genéricas y se podían disgregar en varias actividades.
Futuro: Que no piensen en lo actual, que se mira a futuro sobre las otras cosas que puedan venir o que
puedan agregar.
Realizar las preguntas necesarias: para salir de toda duda antes de realizar una definición de negocio.
Preparación de un Release
Para empezar a desarrollar y seguir las políticas de versionado semántico, se debe tener en cuenta si el
desarrollo es nuevo o pertence a la iniciativa de modificar un release existente.
Si es un desarrollo nuevo
1. Al iniciar un desarrollo nuevo, debe empezar con la versión 0.1.0-SNAPSHOT.
2. A medida que se agreguen nuevas funcionalidades se debe incrementar la versión minor de esta
versión.
3. Cuando el desarrollo sea promovido a ambientes previos, el desarrollo de la librería o servicio debe
colocarse el en 1.0.0-RC1, este sufijo significa Release Candidate 1. Luego de esto están prohibos agregar
nuevas funcionalidades o cambios en el contrato que agreguen una incompatibilidad.
4. Cada iteración de corrección de bugs o fixes de este release debe agregarse como un nuevo número de
este Release Candidate. Ejemplo: Pasar de 1.0.0-RC1 a 1.0.0-RC2.
5. Cuando se despliegue a producción este activo, el release definitivo debe pasar a 1.0.0.
Seguridad en URIs publicas:
Cuando se invoquen URIs que no necesitan token de acceso, se debe generar una autenticacion basica
conformado por los atributos clientId y accessKey. Por ejemplo:
El atributo en el header debe estar formado por ambos atributos concatenados en base 64. Por ejemplo:
Authorization: Basic TWF2ZXJpY2tDbGllbnRJZEFwcDpNYXZlcmlja0NsaWVudElkQXBwMTIz
Request:
El nombre de los request debe tener como sufijo la palabra "Request", por ejemplo: SimulationRequest,
CampaignRequest, etc.
Todos los request deben estar acompañados de su token de sesion en el Header.
Cuando se envié en la url un id, se debe realizar una verificación, validando que dicho id coincida con el id
enviado en el token de sesion
El nombre de los Keys de los request debe tener nombres en inglés y sin abreviaturas.
Los nombres de los Keys deben empezar con minúscula y cada nueva palabra debe empezar con mayúsculas
sin espacios ni guiones (_).
Para realizar el tracking de los mensajes, se creará un componente intercepto el cual agregará un atributo X-
OPERATION-TRACE-ID en el header del request, dicho valor será recuperado al momento de generar el
response y devuelto en el header del response.
Cuando se define un servicio rest en la capa Controller en java se debe tener en cuenta si se mandan como
parámetro una variable o un objeto.
En caso enviar variables como atributos se debe usar la anotación @PathVariable. Por ejemplo:
@PostMapping("/employees/{id}")
Employee one(@PathVariable Long id) {
return repository.findById(id).orElseThrow(() -> new
EmployeeNotFoundException(id));
}
En caso enviar objetos como atributos se debe usar la anotacion @RequestBody. Por ejemplo:
@PostMapping("/employees")
Employee newEmployee(@RequestBody Employee newEmployee) {
return repository.save(newEmployee);
}
En caso se necesite pasar como parametro una variable y un objeto, se puede usar ambas anotaciones.
Response:
El nombre de los response debe tener como sufijo la palabra "Response", por ejemplo: SimulationResponse,
CampaignResponse, etc.
La estructura del response debe contener algunos atributos relacionados con el status del mensaje
Estructura del mensaje:
{
card : {
data1: 'data1',
data2: data2,
data3: {[]},
data4: {}
}
}
{
"code" : 10240,
"message" : "Validation Failed",
"errors" : [
{
"code" : 5432,
"message" : "First name cannot have fancy characters"
},
{
"code" : 5622,
"sub_system" : "Service-A",
"message" : "Password cannot be blank"
}
],
"additional_info" : [
// Pares de claves/valor arbitrarios. Se aceptan: boolean, int, double,
...
]
}
Estándar de commits
Lineamientos para los commits
La gestión de los commits es sumamente importante el cual deben seguir los siguientes lineamientos.
-<tipo>(<alcance>): <asunto>
[LINEA EN BLANCO]
<descripción>
[LINEA EN BLANCO]
<pie_detalle>
Asunto
Una descripción breve del cambio.
Oraciones en presente imperativo: “agrega. . . ” y no “agregado” ni “agregar”.
No poner la primera letra en mayúscula.
No poner punto “.” final.
Tipos
Alcance
Descripción
Es opcional.
Elabora la idea del cambio y hace un contraste con el comportamiento anterior.
Ejemplos
feat(pe.interbank.maverick.identityserver.security.CustomJDBC):
fix(pe.interbank.maverick.identityserver.security.CustomJWT): lint CustomJWT .
fix(pe.interbank.maverick.identityserver.security.CustomJWT): remove unnecessary method.
build(pe.interbank.maverick): exec clean after bundle
fix(pe.interbank.maverick.identityserver.security.CustomJWT): remove whitespaces.
feat(pe.interbank.maverick.identityserver.security.CustomJWT): create * favorite alias validator.
Pase a producción
Crear un [tag] para cada proyecto a subir con el formato: <nombre_app>-v<N.N.N>
Para el caso de front el tag debe tener el siguiente formato: <nombre_app>-v<N.N.N>-bk<N.N.N> para
poder asociar un front con una version especifica de backend.
Contar con la(s) historias definidas (s) y sus respectivos criterios de aceptación
1
definidos por el PO en base a lo indicado en el item: "Definición de features".
Contar con los casos de prueba funcionales, rendimiento (en caso aplique), seguridad
3
(en caso aplique) en base a lo indicado en el item: "Definición de casos de prueba".
Escribir una narrativa(en una frase) del feature indicando lo que ésta hace o de lo que trata, es
decir; la narrativa debe indicar que es lo que se va a implementar en esa feature.
Si un feature es muy grande; en el refinamiento se deberá dividirla en historias mas pequeñas.
El Cas debe describir siempre un contexto, un evento y la respuesta o consecuencia esperada del
sistema.
Se propone describir los criterios de aceptación usando Gherkin GWT (GIVEN-WHEN-THEN/DADO-
CUANDO-ENTONCES) ya que es la forma mas utilizada para realizar ésta tarea.
Given(DADO): Colocar las condiciones(pasado) previas a la ejecución de la prueba.
When(CUANDO): Colocar la descripción(presente) del evento o acción.
Then(THEN): Colocar la descripción (en futuro) del resultado esperado.
Ejemplo:
ESCENARIO 1: el nombre del cliente es obligatorio en el check-in
DADO un cliente en la ventana de check-in online
CUANDO deja el campo de nombre en blanco Y pulsa el botón de confirmación
ENTONCES se muestra un mensaje de error indicando que el campo nombre es obligatorio.
Definición de casos de prueba:
Depurar los casos de prueba definidos por el QA y determinar(en conjunto con el equipo de
desarrollo) los casos testeables.
En base a lo detallado en la definición de Criterios de aceptación, definir los casos de prueba en
base al formato indicado en la tabla, donde: