13 December 2017

30 November 2017

Patrones de Diseño (en un año)

Se han utilizado diferentes patrones de diseño para diferentes necesidades, tal como, de arquitectura de componentes a nivel de servicios y de patrones de construcción OOP.

A continuación es la lista de los patrones de diseños usados:

- Descomposición de servicios para poder tener un buen limite de dominios (DDD, separation of concerns)

- @Domains: usado en la capa Rest donde está la implementación de POJOs

- Repository: donde está desacoplado la implementación de varios repositorios, dejando expuesta el mismo contrato a los cliente.

- @Service: capa Rest, tiene Patrón: Service-layer, en donde implementamos diferentes servicios para llamar, sean base datos pertenecientes a CDN o directamente como cliente al bus de servicios.

- @Controller: Rest, es el controller de springmvc, que es parte del patrón de diseño MVC, el cual dejamos claro el manejo del flujo del servicio rest

- Factory: todos los datasources utilizados vienen del contenedor de aplicaciones (Weblogic), y es una factoría de la cual nos abstraemos de la implementación (Oracle) y usamos la conexión entregada, la cual es reutilizada en las siguientes interacciones.

- DAO: pl-generator, librería que genera DAO automático desde la metadata de oracle y tenemos la interfaz (Façade) de los stored procedures de la base de datos, por directriz (generalmente en bancos) siempre accedemos a través de esos SP, y la librería gracias a esta encapsulación entregada por DAO podemos abstraernos de todo lo necesario de conexiones JDBC.

- SAL: Service Access Layer: Rest, patrón que viene desde la arquitectura SOA y tenemos implementada los diferentes servicios en un solo package.

- MVC: angular/rest. Usamos el patrón Model-View-Controller en nuestra solución. View es AngularJS, Controller y Model está implementado en Rest en las clases con anotaciones @Controller y Pojos, aprovechando la separación entregada por Spring

- API-Proxy: Usamos servicios Rest para todos los accesos desde front hacia OSB/DB. nunca se puede acceder directo desde Front, asi se usa api-proxy como interfaz.

- Aggregator: se utiliza en message-aggregator-rest para encapsular la implementación de del motor de envio de emails. De esta manera le damos más valor al request del envío del correo (Decorator) y tenemos un fachada (facade) para la implementación final.

- Connection Factory: JMS, todos los JMS utilizan un Connection Factory implementada por WLS. de esta manera se reutilizan las conexiones JMS.

- Prototype: en javascript para extender funciones y hacer honor al límite de 100 líneas por función (modular), se utiliza el patrón prototype.

- Database per service: notificaciones utiliza 1 schema por su solución, y no compartimos la base de datos con otros servicios, si alguien más necesita insertar datos estos deben hacerse a través un el api-proxy expuesto por notificaciones.

- Shared database (base datos compartida), existen schemas que son utilizados por varios servicios, tal como, session_cn.

- Log aggregation, se logea las transacciones y funcionalidades importantes de cada uno de los servicios en un log de aplicación que está configurado en cada uno de los dominios de WLS.

- Client-side UI composition. Cada aplicación puede tener componentes propios que están encapsulados en directivas angular. Estas directivas pueden ser reutilizadas por otras aplicaciones. El equipo de Diseño se preocupa de generar el esqueleto de las páginas, componiendo diferentes componentes UI.

- además utilizamos de varios patrones de diseño de más bajo nivel GoF: iterator, façade, singleton, Factory method pattern, Decorator, Builder, etc.


Java Performance

This is a summary post of good practices (many easy) to improve performance in your Java code:

 - use Apache StringUtils.replace instead String.replace. The big difference is because Java replace() uses regexp which makes it more expensive immediately.

- avoid using Java7 UUID (there are other faster libraries for it)

- avoid regexp if possible (many times we use regexp and with a String.indexof() is enough).

try-with-resources

A known, and now kind of old feature of Java 7, but still isn't as popular as we wish.

Straightforward (and easy) implementation, where you need to declare resources (File, Stream) into parenthesis of "try" keyword:

private static void printFileJava7() throws IOException {

    try(FileInputStream input = new FileInputStream("hola.txt")) {

        int data = input.read();
        while(data != -1){
            System.out.print((char) data);
            data = input.read();
        }
    }
}

And JVM will have the responsibility to close those resources.

More info:

https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

http://tutorials.jenkov.com/java-exception-handling/try-with-resources.html

https://www.mkyong.com/java/try-with-resources-example-in-jdk-7/


24 November 2017

HTTP Codes

La arquitectura Rest se basa fuertemente en el protocolo HTTP, por lo cual es importante responder (y parsear al recibir) los diferentes códigos HTTP que existen.
Los códigos están agrupados por las siguientes categorías:
  • 1xx – Informational
  • 2xx – Successful
  • 3xx – Redirection
  • 4xx - Client Error
  • 5xx - Server Error
El proyecto rest-error-handler hace uso granular de estos códigos.
Deberíamos usar solo los códigos más útiles (top “10”) que son los siguientes:

HTTP Response codes

200OKSuccessfully executed. should be used to indicate nonspecific success
201CREATEDSuccessfully executed and a new resources has been created. The response body is either empty or contains a URI(s) of the created resource. The location header should should also contain the new URI
202ACCEPTEDThe request was valid and has been accepted but has not yet been processed. The response should include a URI to poll for status updates on the request. Allows for asynchronous request ( start of an asynchronous action)
204NO_CONTENTThe request was successful but the server did not have a response. should be used when the response body is intentionally empty.
Ejemplo: Si se busca el listado de productos para un cliente y el cliente existe pero la lista es vacía, el estado es 204
301MOVED_PERMANENTLYThe new location should be returned in the response ( should be used to relocate resources)
302REDIRECTThe HTTP response status code 302 Found is a common way of performing URL redirection.
400BAD_REQUESTMalformed or invalid request
401UNAUTHORIZEDInvalid authorization credentials
403FORBIDDENDisallowed request. Security error
404NOT_FOUNDResource not found.
Ejemplo: Si se busca un cliente por rut y éste no existe, el estado es 404
405METHOD_NOT_ALLOWEDMethod (verb) not allowed for requested resource. Response will provide an “Allow” header to indicate what is allowed
415UNSUPPORTED_MEDIA_TYPEClient submitted a media type that is incompatible for the specified resource.
500INTERNAL_SERVER_ERRORCatchall for server processing problem
503SERVICE_UNAVAILABLEResponse in the face of too many request

Mayor información:

https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

02 November 2017

Cannot retrieve WLS app info

Cannot retrieve:

The configuration for app is still being loaded from your last request, please wait a moment and retry.

####<Oct 30, 2017 9:59:44 AM CLT> <Error> <Console> <lablnx297> <AdminServer> <[ACTIVE] ExecuteThread: '5' for queue: 'weblogic.kernel.Default (self-tuning)'> <weblogic> <> <cc19eb40-e1ae-46e5-80cb-dbf2a3509811-00000f0c> <1509368384819> <BEA-240003> <Administration Console encountered the following error: java.lang.NullPointerException
  at weblogic.application.internal.ApplicationRuntimeMBeanImpl.getComponentRuntimes(ApplicationRuntimeMBeanImpl.java:449)
  at sun.reflect.GeneratedMethodAccessor1348.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:606)
  at weblogic.management.jmx.modelmbean.WLSModelMBean.getAttribute(WLSModelMBean.java:525)
  at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getAttribute(DefaultMBeanServerInterceptor.java:647)
  at com.sun.jmx.mbeanserver.JmxMBeanServer.getAttribute(JmxMBeanServer.java:678)
  at weblogic.management.jmx.mbeanserver.WLSMBeanServerInterceptorBase$12.run(WLSMBeanServerInterceptorBase.java:326)
  at java.security.AccessController.doPrivileged(Native Method)
  at weblogic.management.jmx.mbeanserver.WLSMBeanServerInterceptorBase.getAttribute(WLSMBeanServerInterceptorBase.java:324)
  at weblogic.management.mbeanservers.internal.JMXContextInterceptor.getAttribute(JMXContextInterceptor.java:157)
  at weblogic.management.jmx.mbeanserver.WLSMBeanServerInterceptorBase$12.run(WLSMBeanServerInterceptorBase.java:326)
  at java.security.AccessController.doPrivileged(Native Method)
  at weblogic.management.jmx.mbeanserver.WLSMBeanServerInterceptorBase.getAttribute(WLSMBeanServerInterceptorBase.java:324)
  at weblogic.management.mbeanservers.internal.SecurityInterceptor.getAttribute(SecurityInterceptor.java:300)
  at weblogic.management.jmx.mbeanserver.WLSMBeanServer.getAttribute(WLSMBeanServer.java:279)
  at weblogic.management.mbeanservers.internal.JMXConnectorSubjectForwarder$5$1.run(JMXConnectorSubjectForwarder.java:327)
  at java.security.AccessController.doPrivileged(Native Method)
  at weblogic.management.mbeanservers.internal.JMXConnectorSubjectForwarder$5.run(JMXConnectorSubjectForwarder.java:325)
  at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
  at weblogic.management.mbeanservers.internal.JMXConnectorSubjectForwarder.getAttribute(JMXConnectorSubjectForwarder.java:320)
  at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
  at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:97)
  at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1332)
  at java.security.AccessController.doPrivileged(Native Method)
  at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1431)
  at javax.management.remote.rmi.RMIConnectionImpl.getAttribute(RMIConnectionImpl.java:661)
  at javax.management.remote.rmi.RMIConnectionImpl_WLSkel.invoke(Unknown Source)
  at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:701)
  at weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:527)
  at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
  at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
  at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:523)
  at weblogic.rmi.internal.wls.WLSExecuteRequest.run(WLSExecuteRequest.java:118)
  at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
  at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)
>

HTTP Cluster WebLogic Server

Old Deprecated feature:

web.xml :

<servlet-name>ProxyServlet</servlet-name>
<servlet-class>weblogic.servlet.proxy.HttpProxyServlet</servlet-class>
<init-param>
<param-name>redirectURL</param-name>
<param-value>http://localhost:8080</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ProxyServlet</servlet-name>
<url-pattern>/MyProducerApp/*</url-pattern>
</servlet-mapping>

.

My Blog List

Blog Archive

There was an error in this gadget

Disclaimer

The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.