Buscar este blog

domingo, 16 de agosto de 2015

wsdl2java - Use java.util.Date instead of XMLGregorianCalendar

If you have a web service definition, WSDL, and you want to generate the equivalent java code (either for the client or for the server side) one of the simplest way is by using Apache CXF wsdl2java Maven plugin. Check here: http://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html

Problems with XMLGregorianCalendar

The conversion between wsdl dataTypes and java dataTypes is held automatically by this plugin, so in most cases, you don´t need to worry about anything more.
But one annoying thing most people notes is the conversión between date/dateTime and XMLGregorianCalendar.

For example, by having this detifintion:
<xs:complexType name="operacionesPagoFiltroDTO">
 <xs:sequence>
  <xs:element minOccurs="0" name="entidad" type="xs:long" />
  <xs:element minOccurs="0" name="fechaDesde" type="xs:dateTime" />
  <xs:element minOccurs="0" name="fechaHasta" type="xs:dateTime" />
  <xs:element minOccurs="0" name="nifUsuario" type="xs:string" />
  <xs:element minOccurs="0" name="seccion" type="xs:long" />
 </xs:sequence>
</xs:complexType>

You will get this POJO:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "operacionesPagoFiltroDTO", propOrder = {
    "entidad",
    "fechaDesde",
    "fechaHasta",
    "nifUsuario",
    "seccion"
})
public class OperacionesPagoFiltroDTO {

    protected Long entidad;
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar fechaDesde;
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar fechaHasta;
    protected String nifUsuario;
    protected Long seccion;

    (...)

}

So, you have to manually make the conversion in order to obtain java.util.Date.

Solution

The solution is to use a custom binding file and a dateAdapter. When CXF plugin is executed, it will check the binding configuration and will generate the java.util.Date automatically.

In pom.xml you have to specify the custom binding file:
<plugin>
 <groupId>org.apache.cxf</groupId>
 <artifactId>cxf-codegen-plugin</artifactId>
 <version>${cxf.version}</version>
 <executions>
  <execution>
   <id>generate-sources</id>
   <phase>generate-sources</phase>
   <configuration>
    <sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>
    <wsdlOptions>        
     <wsdlOption>
      <wsdl>${basedir}/src/main/resources/wsdl/gestionEconomica/GestionEconomica.wsdl</wsdl>       
      <bindingFiles>
       <bindingFile>${basedir}/src/main/resources/wsdl/gestionEconomica/GestionEconomicaBinding.xml</bindingFile>
      </bindingFiles>
     </wsdlOption>
    </wsdlOptions>
   </configuration>
   <goals>
    <goal>wsdl2java</goal>
   </goals>
  </execution>
 </executions>
</plugin>

And this would be the binding file:
<jaxws:bindings wsdlLocation="GestionEconomica.xsd.wsdl"
 xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">

 <jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='http://mytargetspace.es/']">
  
  <jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <jxb:javaType 
       name="java.util.Date" 
       xmlType="xs:dateTime"
    parseMethod="org.apache.cxf.xjc.runtime.DataTypeAdapter.parseDateTime"
    printMethod="org.apache.cxf.xjc.runtime.DataTypeAdapter.printDateTime" />
  </jxb:globalBindings>
 </jaxws:bindings>
</jaxws:bindings>

By doing so, you will get this POJO:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "operacionesPagoFiltroDTO", propOrder = {
    "entidad",
    "fechaDesde",
    "fechaHasta",
    "nifUsuario",
    "seccion"
})
public class OperacionesPagoFiltroDTO {

    protected Long entidad;
    @XmlElement(type = String.class)
    @XmlJavaTypeAdapter(Adapter1 .class)
    @XmlSchemaType(name = "dateTime")
    protected Date fechaDesde;
    @XmlElement(type = String.class)
    @XmlJavaTypeAdapter(Adapter1 .class)
    @XmlSchemaType(name = "dateTime")
    protected Date fechaHasta;
    protected String nifUsuario;
    protected Long seccion;

    (...)
}

You can specify any adapter you want, but CXF also provides you with a basic implementation: org.apache.cxf.xjc.runtime.DataTypeAdapter. In order to use it, you need to add this extra dependency to your pom.xml:
<dependency>
 <groupId>org.apache.cxf.xjc-utils</groupId>
 <artifactId>cxf-xjc-runtime</artifactId>
 <version>${cxf-xjc-runtime.version}</version>
</dependency>


Note: You can check more about wsdl2java and eclipse in one of my previous posts: http://trabajosdesisifo.blogspot.com.es/2015/04/eclipse-maven-configure-wsdl2java.html

sábado, 8 de agosto de 2015

JBoss CLI - Domain monitoring

These are some commands to get insight of the health of your deployments.
The idea was to have one script and run it periodically to get some KPI. This script invokes jboss-cli by passing the command as a parameter.
You can ask why don´t have a jboss-cli script file and to pass it as a parameter (./jboss-cli --file ). By doing so, you can not print custom messages, because we were using JBoss EAP 6.2. In 6.4 you do have an echo command in CLI.

echo "--------------------------------------------------"
echo "$(date)"

echo "Session info"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=web:read-attribute(name=expired-sessions)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=web:read-attribute(name=rejected-sessions)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=web:read-attribute(name=max-active-sessions)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=web:read-attribute(name=session-max-alive-time)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=web:read-attribute(name=sessions-created)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=web:read-attribute(name=session-avg-alive-time)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=web:read-attribute(name=context-root)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=web:read-attribute(name=virtual-host)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=web:read-attribute(name=active-sessions)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=web:read-attribute(name=duplicated-session-ids)"


echo "EJB info"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=methods)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=timers)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=pool-available-count)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=peak-concurrent-invocations)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=invocations)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=pool-create-count)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=declared-roles)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=security-domain)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=pool-name)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=run-as-role)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=component-class-name)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=pool-max-size)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=wait-time)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=execution-time)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=pool-remove-count)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/deployment=<deployment>/subsystem=ejb3/stateless-session-bean=EjbInvoker:read-attribute(name=pool-current-size)"


echo "Memory info"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/core-service=platform-mbean/type=memory : read-attribute(name=heap-memory-usage)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/core-service=platform-mbean/type=memory : read-attribute(name=non-heap-memory-usage)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/core-service=platform-mbean/type=memory : read-attribute(name=verbose)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/core-service=platform-mbean/type=memory : read-attribute(name=object-name)"
./jboss-cli.sh -c --user=<user> --password=<pass> --command="/host=<host>/server=<server>/core-service=platform-mbean/type=memory : read-attribute(name= object-pending-finalization-count)"

lunes, 3 de agosto de 2015

JBoss Domain JConsole connection

JBoss EAP is shipped with its own JConsole, so you can get insight about your server via JMX.
In this post I´ll talk about domain mode in JBoss EAP 6.2.

JConsole is in ${JBoss.home}/bin/jconsole.sh

Topology

This is my topology:
  • Domain Controller in 192.168.56.101
  • Host Controller 1 in 192.168.56.102
  • Host Controller 2 in 192.168.56.103

I Have a server-group called jbossEAP6-sg1 with two servers, each one in its own HC:
  • server-full-ha-1 in HC 1, bound to 192.168.56.130
  • server-full-ha-2 in HC 2, bound to 192.168.56.140

This domain is in a CentOS remote PC and I Will connect from my Windows installation.

Configuration

I want to monitor Domain Controller in general, and my servers in particular. So I will make two different connections.

You have to configure jmx subsystem in domain.xml (this file is placed inside de Domain Controller). Once there you have to set the following config:
<subsystem xmlns="urn:jboss:domain:jmx:1.3">
 <expose-resolved-model/>
 <expose-expression-model/>
 <remoting-connector use-management-endpoint="false"/>
</subsystem>

Then, you need an application user in all the nodes (asuming you already have a management user in the domain). Simply use ./add-user.sh in DC, add a user, and copy the application-roles.properties and  application-users.properties files in the others HCs.

Connection to DC

You can start your connection with the followning parameters:
  • Remote Process: service:jmx:remoting-jmx://192.168.56.101:9999
  • Username/Password: domain user




Note that there is a CLI tab due to this is a DC.

Connection to server-full-ha-1 in HC 1

You can starts your connection with the followning parameters:
  • Remote Process: service:jmx:remoting-jmx://192.168.56.130:4447
  • Username/Password: application user
Note that in this case you need to set de 4447 port. I'm using a custom binding address for each server, so I don´t need to specify a port offset, otherwise you need to calculate the real port of your server.



Aditional info:

domingo, 2 de agosto de 2015

JBoss CLI - Datasources

I´ll show you the procedure to create a XA-DATASOURCE and a DATASOURECE in standalone and domain mode. First you have to create the driver, then create the datasource and finally enable it. As a bonus, you can check the connection.

The driver is created manually as a JBoss Module in directory ${JBossHome}/modules/com/microsoft/sqlserver/main. In this directory you need two files:
  1. module.xml
  2. the jdbc driver, sqljdbc4.0.jar
This is the content of module.xml:
<module xmlns="urn:jboss:module:1.1" name="com.microsoft.sqlserver"> 
  <resources> 
    <resource-root path="sqljdbc4.0.jar"/> 
  </resources> 
  <dependencies> 
    <module name="javax.api"/> 
    <module name="javax.transaction.api"/>
  </dependencies> 
</module>


My dabatabase configuration:
  • Type: SQL Server
  • Address: 192.168.65.133:1433
  • Database name: Pruebas
  • User/password: user-pruebas / user-pruebas

Standalone

/subsystem=datasources/jdbc-driver=sqlserver-xa:add(driver-module-name=com.microsoft.sqlserver, driver-name=sqlserver-xa, driver-xa-datasource-class-name=com.microsoft.sqlserver.jdbc.SQLServerXADataSource)

xa-data-source add --name=pruebasDSXA --jndi-name=java:jboss/datasources/pruebasDSXA --driver-name=sqlserver-xa --user-name="user-pruebas" --password="user-pruebas" --same-rm-override=false --background-validation=true --valid-connection-checker-class-name=org.jboss.jca.adapters.jdbc.extensions.mssql.MSSQLValidConnectionChecker --xa-datasource-properties=ServerName=192.168.65.133,PortNumber=1433,DatabaseName=PruebasDS,SelectMethod=cursor

xa-data-source enable --name=pruebasDSXA

/subsystem=datasources/xa-data-source=pruebasDSXA:test-connection-in-pool



/subsystem=datasources/jdbc-driver=sqlserver:add(driver-module-name=com.microsoft.sqlserver, driver-name=sqlserver, driver-datasource-class-name= com.microsoft.sqlserver.jdbc.SQLServerDriver)

data-source add --name=pruebasDS --jndi-name=java:jboss/datasources/pruebasDS --driver-name=sqlserver --connection-url="jdbc:sqlserver://192.168.65.133;DatabaseName=Pruebas" --user-name="user-pruebas" --password="user-pruebas" --background-validation=true

data-source enable --name=pruebasDS

/subsystem=datasources/data-source=pruebasDS:test-connection-in-pool

Domain

/profile=full-ha/subsystem=datasources/jdbc-driver=sqlserver-xa:add(driver-module-name=com.microsoft.sqlserver, driver-name=sqlserver-xa, driver-xa-datasource-class-name=com.microsoft.sqlserver.jdbc.SQLServerXADataSource)

xa-data-source --profile=full-ha add --name=pruebasDSXA --jndi-name=java:jboss/datasources/pruebasDSXA --driver-name=sqlserver-xa --user-name="user-pruebas" --password="user-pruebas" --same-rm-override=false --background-validation=true --valid-connection-checker-class-name=org.jboss.jca.adapters.jdbc.extensions.mssql.MSSQLValidConnectionChecker --xa-datasource-properties=ServerName=192.168.65.133,PortNumber=1433,DatabaseName=Pruebas,SelectMethod=cursor

xa-data-source --profile=full-ha enable --name=pruebasDSXA

/host=hc-001/server=server-full-ha-1/subsystem=datasources/xa-data-source=pruebasDSXA:test-connection-in-pool

/host=hc-002/server=server-full-ha-2/subsystem=datasources/xa-data-source=pruebasDSXA:test-connection-in-pool



/profile=full-ha/subsystem=datasources/jdbc-driver=sqlserver:add(driver-module-name=com.microsoft.sqlserver, driver-name=sqlserver, driver-datasource-class-name= com.microsoft.sqlserver.jdbc.SQLServerDriver)

data-source --profile=full-ha add --name=pruebasDS --jndi-name= java:jboss/datasources/pruebasDS --driver-name=sqlserver --connection-url="jdbc:sqlserver://192.168.65.133;DatabaseName=Pruebas" --user-name="user-pruebas"  --password="user-pruebas" --background-validation=true --valid-connection-checker-class-name=org.jboss.jca.adapters.jdbc.extensions.mssql.MSSQLValidConnectionChecker

data-source --profile=full-ha enable --name=pruebasDS

/host=hc-001/server=server-full-ha-1/subsystem=datasources/data-source=pruebasDS:test-connection-in-pool

/host=hc-002/server=server-full-ha-2/subsystem=datasources/data-source=pruebasDS:test-connection-in-pool

JBoss Domain set server binding address

The purpose of this blog is to show how to start each server inside a domain in its own IP address.

In JBoss domain you have:
  • Domain controller. One node is the DC that manage the Host Controllers.
  • Host controllers. There would be one HC for each physical node in the domain.
  • Server group: A server group is a logical group of servers that can span over multiple HC
  • Server. A server is the worker instance of a node in which applications are executed

Inside a HC you can have multiple servers, but in order they don't collide, you have to:
  • Set a port offset in each server. For example, server-1 starts in 0, server-2 starts in +150, etc.
  • Set a unique IP address for each one.

The cleanest way is to put each server in a separate IP and let the default port offset to 0. In order to do that, you have to set two System Properties in the server:
  • jboss.bind.address
  • jboss.bind.address.unsecure

I have two HCs and a server group called "jbossEAP6-sg1". This server group is composed by two servers, "server-full-ha1" and "server-full-ha-2" with a zero port offset:



Each server has its own bind address:, 192.168.56.130 and 192.168.56.140: