Buscar este blog

sábado, 22 de agosto de 2015

Remote Desktop with SSH Tunnel

In this post I will show you how to access to a PC with Windows Remote Desktop. Well, this would be quite easy, so to make it more funny, the target Machine is not accessible from the Source Machine, but do there is a third machine which is accessible from both of them.

The topology of the problem is depicted in the following image:



We have these elements:
  • Target PC (windows). This is the machine I want to connect to.
  • Source PC (windows). This is the machine from where I want to connect to the Target PC.
  • Gateway (windows/Unix). This is the intermediary between Source and Target.
You have to keep in mind these constraints:
  • Source cannot reach Target
  • Source can reach Gateway
  • Target can reach Gateway
  • Gateway cannot reach Target
So, the idea is to use Gateway as a bridge between Source and Target. To make this happen we will use SSH Tunnels.

Previous preparation

In my concrete scenery, Gateway is a Windows Server PC, so I will have to configure SSH Server in it, but if you have a Unix Machine this step is already taken for granted.

You can use FreeSSHD as SSH Server. It is free (obvious) and very easy to configure. For example you can check this page.
The basic steps to configure it are:
  1. Install with default options
  2. Run as a service
  3. Configure SSH port, only if 22 were already in use
  4. Configure authentication to require password
  5. Add some user
Besides, I'll add another step. Enable Tunneling options



Once you are done, you can check that all works properly by connecting with Putty to this machine. You should see one active user connected:


Tunneling

There will be two SSH tunnels: 
  • From Target to Gateway
  • From Source to Gateway
The topology of the solution is depicted in the following image:



Target will open a tunnel in which all connections in Gateway to port 9999 will be redirected to itself in port 3389. Port 3389 is the default Windows Remote Desktop port.

Source will open a tunnel in which all connections in Source to port 13389 will be redirected to Gateway in port 9999.

Now you should have noted that the bridge is Gateway´s port 9999.

Tunnel from Target to Gateway

Working on Target PC, with putty you have to set the following configuration.
In Session category:
  • Host name and port of the SSH Server of Gateway
In Connection category:
  • Set the parametter "Seconds beween keepalives" to 180
In Connection > SSH > Tunnels category:
  • Check "Local ports accept connections from other hosts" option
  • Check "Remote ports do the seame (SSH-2 only)" option
  • Set source port 9999, destination localhost:3389 and check the option Remote. Then push "Add"

Tunnel from Source to Gateway

Working on Source PC, with putty you have to set the following configuration.
In Session category:
  • Host name and port of the SSH Server of Gateway
In Connection category:
  • Set the parametter "Seconds beween keepalives" to 180
In Connection > SSH > Tunnels category:
  • Check "Local ports accept connections from other hosts" option
  • Check "Remote ports do the seame (SSH-2 only)" option
  • Set source port 13389, destination 192.168.65.133:9999 and check the option Local. Then push "Add"

Testing the tunnel

From Source, you only need to try to connect with remote desktop to localhost:13389. The connection will travel throught the first tunnel to Gateway, and from Gateway to Target throught the other tunnel.



Thanks to Mr V (alias coffee man) for helping me with this.


Bonus

In Target, you can configure a script to use Putty Command Line options to connect automatically.
In my example I named my session as "Tunel a Gateway", but for command line is better to set a one-word name, for example gatewayTunnel.

putty.exe -load gatewayTunnel -l userName -pw password

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