viernes, 10 de julio de 2015

GIT

Git tutorial:
http://www.vogella.com/tutorials/Git/article.html

Just to know
  • Bare Repository: A remote repository on a server typically does not require a working tree. A Git repository without a working tree is called a bare repository. are used on servers to share changes coming from different developers
  • No-bare Repository: Allow you to create new changes through modification of files and to create new versions in the repository
  • Always need to initialize a git repository before call any commands

Creating Bare repository (shared/server repository)
  • git --bare init

Creating Non-bare repository (local?developer repository)
  • git init

Global Configuration (applies to all repositories)
  • Configure your user and email for Git
  • # configure the user which will be used by Git
  • # this should be not an acronym but your full name
  • git config --global user.name "Firstname Lastname" 
  • # configure the email address 
  • git config --global user.email "your.email@example.org"
  • Configures Git to push only the active branch ( for older versions )
  • # set default so that only the current branch is pushed
  • git config --global push.default simple 

Adding remote repository
  • Inside the non-bare repository type the following command:
  • git remote add origin /home/etc/repo.git
  • git remote add origin http://bla.com/github/bla

List the remote repository (in the non bare repository)
  • git remote -v

Pushing from the non-bare (developer) repository to bare (shared) repository
  • git add .
  • git commit -m "init commit"
  • git push origin master
origin=>the name of the repo
master=>the default branch


Cloning from the bare repository to non-bare repository
  • Initialize a git non bare repository
  • $ git init
  • Initialized empty Git repository in /home/Damian Ciocca/clone.git3/.git/
  • $ git remote add origin /home/etc/repo.git
  • $ git clone /home/Damian\ Ciocca/repo.git/ repo
  • Cloning into 'repo'...
  • done.

Pulling from the bare repository to non-bare repository
  • git pull orifin master

Another commands
  • git log
  • git status -s
  • git remote -v

miércoles, 8 de julio de 2015

Elasticsearch (Lucene)

Elasticsearch Basic Concepts Link:

Elasticsearch excellent tutorial:

Just to know:
  • First way to talk to the Elasticsearh is over the port 9300, using the native Elasticsearch transport protocol
  • The second way to talk to the Elasticsearh is over port 9200 using a RESTful API.
  • You can even talk to Elasticsearch from the command line by using the curl command
  • A document belongs to a type, and those types live inside an index. We can draw some (rough) parallels to a traditional relational database: 
  • Relational DB ⇒ Databases ⇒ Tables ⇒ Rows ⇒ Columns
  • Elasticsearch ⇒ Indices ⇒ Types ⇒ Documents ⇒ Fields 
  • An Elasticsearch cluster can contain multiple indices (databases), which in turn contain multiple types(tables). These types hold multiple documents (rows), and each document has multiple fields (columns). (https://www.elastic.co/guide/en/elasticsearch/guide/current/_indexing_employee_documents.html)
  • To identify unequivocally to one document, we need to know is: a index, type and id.

A request to Elasticsearch consists of the same parts as any HTTP request:
  • curl -X<VERB> '<PROTOCOL>://<HOST>/<PATH>?<QUERY_STRING>' -d '<BODY>'
  • Note:
VERB The appropriate HTTP method or verb: GET, POST, PUT, HEAD, or DELETE.
QUERY_STRING Any optional query-string parameters (for example ?pretty will pretty-print the JSON response to make it easier to read.)
BODY A JSON-encoded request body (if the request needs one.)

CURL Example:
  •  curl -i -X GET localhost:9200/_count?pretty
  • Note:
-i allows to see the http headers

Creation document example using REST API:

PUT
  • curl -i -X PUT localhost:9200/megacorp/employee/1 -d '{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]}'
  • Note:
The path /megacorp/employee/1 contains three pieces of information: 
megacorp => The index (database) name
employee => The type name (table)
1 => The ID of this particular employee (row)
-d (....)  => The Json document (row)
  • curl -i -X PUT localhost:9200/megacorp/employee/1/_create -d '{}'
HTTP/1.1 409 ConflictContent-Type: application/json; charset=UTF-8
Content-Length: 110
{"error":"DocumentAlreadyExistsException[[megacorp][3] [employee][40]: document already exists]","status":409}
  • Note:
In that case you can see that we can use _create to help us in order to prohibit create an existing document.
POST
If our data doesn’t have a natural ID, we can let Elasticsearch autogenerate one for us. Here we show how to use POST instead of use PUT to autogenerate the ID.
  • curl -i -X PUT localhost:9200/megacorp/employee/4 -d '{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]}'
HTTP/1.1 201 CreatedContent-Type: application/json; charset=UTF-8Content-Length: 78{"_index":"megacorp","_type":"employee","_id":"4","_version":1,"created":true}
  • curl -i -X POST localhost:9200/megacorp/employee/ -d '{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]}'
HTTP/1.1 201 CreatedContent-Type: application/json; charset=UTF-8Content-Length: 97{"_index":"megacorp","_type":"employee","_id":"AU5uz7mdzFHxYLzn_JYw","_version":1,"created":true}
Note that the he response is similar to what we saw before, except that the _id field has been generated for us 
Remember that the combination of _index, _type, and _id uniquely identifies a document. So the easiest way to ensure that our document is new is by letting Elasticsearch autogenerate a new unique_id, using the POST version of the index request.

Retrieve document example using REST API (simple mode)

GET
  • $ curl -i -X GET localhost:9200/megacorp/employee/3?pretty
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 290

{
  "_index" : "megacorp",
  "_type" : "employee",
  "_id" : "3",
  "_version" : 1,
  "found" : true,
  "_source":{
    "first_name" :  "Douglas",
    "last_name" :   "Fir",
    "age" :         35,
    "about":        "I like to build cabinets",
    "interests":  [ "forestry" ]
}
}
  • $ curl -i -X GET localhost:9200/megacorp/employee/12?pretty
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=UTF-8
Content-Length: 92

{
  "_index" : "megacorp",
  "_type" : "employee",
  "_id" : "12",
  "found" : false
}

Retrieve part of a document example using REST API 

GET
  • $ curl -i -X GET localhost:9200/megacorp/employee/4?_source=first_name,age
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 117

{"_index":"megacorp",
 "_type":"employee",
 "_id":"4",
 "_version":1,
 "found":true,
 "_source":{"first_name":"John","age":25}
}

Retrieve just a document without any metadata example using REST API 

GET
  • $ curl -i -X GET localhost:9200/megacorp/employee/4/_source
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 168
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]}

Retrieve document example using REST API (DSL mode)

GET
  • curl -i -X GET localhost:9200/megacorp/employee/_search -d '{
    "query" : {
        "match" : {
            "last_name" : "Smith"
                  }
              } 
   }'


Check if any document exists:

HEAD (because this action does not return the body, just HTTP headers)
  • $ curl -i -X HEAD localhost:9200/megacorp/employee/4
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 0
  • $ curl -i -X HEAD localhost:9200/megacorp/employee/121
HTTP/1.1 404 NOT FOUND
Content-Type: text/plain; charset=UTF-8
Content-Length: 0

Update a document

PUT (twice)
  • $ curl -i -X PUT localhost:9200/megacorp/employee/40 -d '{
>     "first_name" : "John",
>     "last_name" :  "Smith",
>     "age" :        25,
>     "about" :      "I love to go rock climbing",
>     "interests": [ "sports", "music" ]}'

HTTP/1.1 201 Created
Content-Type: application/json; charset=UTF-8
Content-Length: 79
{"_index":"megacorp","_type":"employee","_id":"40","_version":1,"created":true}

  • $ curl -i -X PUT localhost:9200/megacorp/employee/40 -d '{
>     "first_name" : "John",
>     "last_name" :  "Smith",
>     "age" :        25,
>     "about" :      "I love to go rock climbing",
>     "interests": [ "sports", "music" ]}'

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 80
{"_index":"megacorp","_type":"employee","_id":"40","_version":2,"created":false}



















lunes, 6 de julio de 2015

Couchbase (NoSQL) & Java SDK

Couchbase Basic Concepts Link
https://es.wikipedia.org/wiki/CouchDB
https://en.wikipedia.org/wiki/Couchbase_Server
http://docs.couchbase.com/admin/admin/Misc/admin-basics.html
http://docs.couchbase.com/admin/admin/Views/views-intro.html

Couchbase example (install, create data and query data) 
http://tugdualgrall.blogspot.com.ar/2012/07/couchbase-101-install-store-and-query.html

Couchbase querying
http://docs.couchbase.com/admin/admin/Views/views-querySample.html
http://hardlifeofapo.com/basic-couchbase-querying-for-sql-people/

Couchbase & Java
http://docs.couchbase.com/developer/java-2.1/java-intro.html
http://docs.couchbase.com/developer/java-2.1/documents-basics.html
http://www.javacodegeeks.com/2013/01/couchbase-101-create-views-mapreduce-from-your-java-application.html
https://dzone.com/articles/hello-world-couchbase-and-java

Just to know:
  • 8092 is the Couch API REST port used to access data (where 8091 is the port for the Admin console)
  • default is the bucket in which the document is stored
  • A bucket is used by Couchbase to store data. It could be compared to a “database” in RDBMS world.
  • Couchbase can store any type of data, but when you need to manipulate some data with a structure the best way is to use JSON Documents. 
  • Access document directly from its ID: Use the REST API in port 8092)
  • Search your data with queries: Use Views (written in javascripts)

Quickly creation (via REST API / port 8092)

You can use the REST API to create the documents or buckets (databases)

Bucket (database) creation:
  • curl -X PUT 'http://localhost:8092/defaultDB
Document creation:
  • curl -X PUT 'http://localhost:8092/defaultDB/10' -d '{"name":"My Name 1"}'
In the couchbase server you will find the following new json document with the ID = 10:

{
"name": "My Name 1"

}

lunes, 29 de junio de 2015

Eclipse & XML

Para poder integrar con eclipse XML tenemos que instalar el plung llamado WTP (Web Tool Plugin)

https://eclipse.org/webtools/

o bien buscar en

https://marketplace.eclipse.org/

Acceso directo: https://marketplace.eclipse.org/content/eclipse-wtpxml-search

Mediante el Marketplace de Eclipse, podemos descargar dicho plugin:





Nota: La versión de eclipse Luna es la 4.4.x







miércoles, 1 de abril de 2015

Semaphores in java

Please, see this tutorial

http://tutorials.jenkov.com/java-concurrency/semaphores.html

Example of Semaphore as a lock:

public class Semaphore {

private static final Logger LOG = LoggerFactory.getLogger(Semaphore.class);
private boolean signal = true; // It means that the first threads could get the light green

/**

*/
public Semaphore() {

super();
}

/**

*/
public synchronized void release() {

this.signal = true;
this.notifyAll();
}

/**

*/
public synchronized void take() {

while(this.signal == false) {
try {
wait();
} catch (InterruptedException e) {
LOG.error(e.getMessage(), e);
}
}
this.signal = false;
}
}

viernes, 25 de julio de 2014

Importando certificado a la JVM

Importando un certificado a la JVM (cacerts)

Esto permite evitar configurar programaticamente el certificado

System.setProperty(SSL_TRUSTSTORE, trustStore);
System.setProperty(SSL_TRUSTSTORE_PASSWORD, trustStorePwd);

donde:
trustStore=C\:\\ejemplo.jks
trustStorePwd=

y donde
public static final String SSL_TRUSTSTORE_PASSWORD  = "javax.net.ssl.trustStorePassword";
public static final String SSL_TRUSTSTORE                      = "javax.net.ssl.trustStore";

1. Listamos los certificados importados en la JVM
Entramos a <JAVA_HOME>\jre\lib\security\

  • keytool -list -v -keystore cacerts 


2. Importamos el certificado descargado desde el sitio HTTPS al cacerts de la JVM

  • keytool -importcert -alias "TEST_CERT" -file e:\\pepe.cer -keystore cacerts
  • password: changeit

Y si queremos generar un truestore (jks) a partir del certificado para poder utilizarlo programaticamente:

  • keytool.exe -import -file e:\pepe.cer -keystore e:\jjjjj.jks

NOTA: Si estamos ejecutando el código dentro de un jboss (es decir, tenemos alguna clase java dentro del jboss que intenta establecer una comunicacion segura con algun sitio) es factible que estas lineas (System.setProperty(..)...) no sean tenias en cuenta:

En un jboss 5.0.0.GA: Va a tomar en cuenta las lineas System.setProperty(...) sin problemas, con lo cual, programaticamente podemos setear el certificado y la conexion segura se establecera.

En un jboss 5.1.0.GA: Nunca va a tomar en cuenta las lineas System.setProperty(...), con lo cual, programaticamente NO podemos setear el certificado. Tenemos que agregarlo via configuracion del jboss como explicamos mas abajo.

***************************************************
IMPORTANTISIMO: Cuando se crea el keystore tiene que tener CN=localhost, sino esta como localhost no anda!
***************************************************


Importando varios certificados a un keystore (para no depender de la JVM en caso de futuros upgrades)

# Import VeriSign root certificate

  • keytool -import -v -keystore my.truststore -alias VeriSign_Root -storepass changeit -file VeriSign,Inc..crt


# Import VeriSign intermediate certificate

  • keytool -import -v -keystore my.truststore -alias VeriSignIntermediateCACert -storepass changeit -file VeriSignIntermediateCACert.txt


# Import server certificate

  • keytool -import -v -keystore my.truststore -alias server_cert -storepass changeit -file cert.cer


# List trust store certificates

  • keytool -list -v -keystore my.truststore


y en caso de querer levantar este keystore (certificado) generado previamente via configuracion del JBOSS

De esta manera, no es necesario setear programaticamente nada:

En jboss 5.1.0.GA:

Edit bin/run.conf

# Set trust store file location
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=c://server//jboss-5.0.0.GA_ConHTTPS_Activado//server//default//conf//demottrust.jks"
# Set trust store password
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStorePassword=password"
# Turn off host verification if needed
#JAVA_OPTS="$JAVA_OPTS -Dorg.jboss.security.ignoreHttpsHost=true"
# Turn on ssl handshake debugging if needed
#JAVA_OPTS="$JAVA_OPTS -Djavax.net.debug=ssl,handshake"

En jboss 5.0.0.GA

Edit bin/run.bat (no me tomaba el run,conf)

# Set trust store file location
set JAVA_OPTS=%JAVA_OPTS% -Djavax.net.ssl.trustStore=c:\server\jboss-5.0.0.GA_ConHTTPS_Activado\server\default\conf\demottrust.jks
# Set trust store password

set JAVA_OPTS=%JAVA_OPTS% -Djavax.net.ssl.trustStorePassword=changeit

Nota: para esta version de jboss va sin comillas

Ver: http://jianmingli.com/wp/?p=975

Es importante entender que de esta manera, no hace falta agregar programáticamente ningún comando para levantar el certificado en la JVM y asi establecer la conexión segura (HTTPS).

lunes, 19 de mayo de 2014

Web Service + REST + JAX-RS

En WebServices existen dos modalidades: SOAP y REST
  1. JAX-WS represents SOAP
  2. JAX-RS represents REST
SOAP es intercambio de mensajes SOAP (que son mensajes envueltos en XML).
JAX WS es la implementación estándar de web services SOAP en Java. Viene desde la versión de JDK 6.

REST es una implementación posterior. Más rica, no sólo utiliza un tipo de mensaje HTTP para el intercambio de mensajes, si no que permite más mensajes. Esto es, con Rest puedes tener un cliente que envíe mensajes HTTP de tipo GET, PUT, POST y DELETE. Cada mensaje enviará los datos correspondientes asociados hacia el servidor, que, recibirá la petición, la entenderá, y delegará en el método correspondiente. GET sirve para recuperar un dato desde el cliente al servidor, PUT para insertar un dato, POST para enviar información para modificar y DELETE para eliminar información del servidor.

The important thing to know about the request body is that it is unique to each service. The service designer must define the format of the request body and convey that to service consumers. Information in the request body is typically encoded in XML or JSON format. Here is a typical HTTP request that contains XML information within the body:

Service CallDescription
GET http://{server}/MyRestService/library/booksGet a list of books
PUT http://{server}/MyRestService/library/books/12345Create a new book with ISBN 12345
GET http://{server}/MyRestService/library/books/12345Get a single book with ISBN 12345
DELETE http://{server}/MyRestService/library/books/12345Delete a single book with ISBN 12345

Link muy util:



Algunas implementaciones REST:
  • Apache CXF
  • Jersey
  • RESTeasy (is JBOSS provided implementation of JAX-RS specification for building RESTful Web Services and RESTful Java applications. Though this is not limited to be used in JBOSS only, and you can use with other servers also. In this post, I am building such a hello world application in tomcat server)
  • Restlet
  • Apache Wink

Ejemplo usando RESTeasy:

http://howtodoinjava.com/2013/05/09/resteasy-tomcat-hello-world-application/

Ejemplo usando CXF con Spring:

http://dhruba.name/2008/12/08/rest-service-example-using-cxf-22-jax-rs-10-jaxb-and-spring/
http://www.luckyryan.com/2013/06/15/apache-cxf-with-spring-integration/

Luego para acceder a la URL, vamos a:

http://localhost:8081/WSRestWithSpringProject/services

Y haciendo clic en la URL, vemos lo siguiente:


Para acceder a alguno de los dos servicios expuestos hacemos:

  • http://localhost:8081/WSRestWithSpringProject/myservice/users
  • http://localhost:8081/WSRestWithSpringProject/myservice/customers

Si queremos acceder a un método pasando por parámetro un valor:


El método es del estilo:

    @GET
    @Path("/users")
    @Produces("application/xml") //The @Produces annotation is used to 
    specify the format of the response. W
    @Override
    public Response getUsers(@QueryParam("id")String id) {
  
    UserCollection usersList = new UserCollection(users.values());
    if (StringUtils.hasText(id)){
    Integer idAsInt = Integer.valueOf(id);
    User user = users.get(idAsInt);
    System.out.println("user: " + user);
        return Response.status(200).entity(user).build();
   
    return Response.status(200).entity(usersList).build();
    }

Leer:
http://stackoverflow.com/questions/11552248/when-to-use-queryparam-vs-pathparam

Otro Ejemplo usando CXF con Spring + JSON:

This is a simple link to demostrate how to create a simple JAX-RS Web Service in Java using Spring and Apache CXF. This service will be follow the request/response pattern, it will using HTTP POSTs which are formatted JSON requests and it will produce JSON responses:

http://www.dreamsyssoft.com/blog/blog.php?/archives/7-Simple-JAX-RS-Web-Service-in-Java-with-Spring-and-CXF.html

@Path("/myservice")
@Consumes("application/json")
@Produces("application/json")
public interface UserManagerJson {

@GET
@Path("/fetchUserById")
public UserResponseJson fetchUserById(@QueryParam("id")String request);

..
}

public class UserManagerimplJson implements UserManagerJson {

@Override
public UserResponseJson fetchUserById(String request) {
UserResponseJson userResponseJson = new UserResponseJson();
userResponseJson.setSuccess(true);
userResponseJson.setErrorMessage("OK");
userResponseJson.setUsers(new ArrayList<String>());
return userResponseJson;
}
..
}

ApplicationContext.xml

.....
.....        
   <!-- 2. CON JSON RESPONSE -->
  <jaxrs:server id="userManagerWithJson" address="/dos">
  <jaxrs:serviceBeans>
  <ref bean="userManagerService"/>
  </jaxrs:serviceBeans>
  <jaxrs:providers>
<ref bean='jsonProvider' />
</jaxrs:providers>
  </jaxrs:server>
 
  <bean id="jsonProvider" 
class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
    
<bean id="userManagerService" class="service.json.UserManagerimplJson"/>

.....
.....

POM.XML

....
....
 <!-- Provider para jax-rs para devolver una respuesta en formato json -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.1.1</version>
</dependency>
....
....


jueves, 15 de mayo de 2014

Implementing an EJB as Web Service using jax-ws

Creando un EJB como un Web Service utilizando JAX-WS

Requerimientos:
  • JBoss 5.0.0.GA 
  • librerias JBoss WS native.

Vamos a copiar las siguientes librerias desde c:\server\jboss-5.0.0.GA\client\ y a c:\server\jboss-5.0.0.GA\lib\endorsed\
  • jbossws-native-jaxrpc.jar
  • jbossws-native-jaxws-ext.jar
  • jbossws-native-saaj.jar
  • jbossws-native-jaxws.jar

Luego, creamos el EJB y le agregamos la anotación @WebService

@WebService
@Stateless
public class BancoServiceImpl implements BancoService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final long SALDO_ESTATICO=1000000;
/* (non-Javadoc)
* @see com.gemalto.inlakech.spring.ejb.template.example.BancoService#consultarSaldo(java.lang.String)
*/
@Override
public long consultarSaldo(String cuenta){
logger.info("Entering to method with paraemeters[cuenta:"+cuenta+"]");
//TODO here business logic to get REAL balance
logger.info("The current balance for cuenta["+cuenta+"] is ["+SALDO_ESTATICO+"]");
return SALDO_ESTATICO;
}
}

@Remote
public interface BancoService {

public long consultarSaldo(String cuenta);
}

POM.XML

<dependencies>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>

<dependency>
   <groupId>org.mockito</groupId>
   <artifactId>mockito-all</artifactId>
   <version>1.9.5</version>
</dependency>
       
<dependency>
<groupId>org.mockejb</groupId>
<artifactId>mockejb</artifactId>
<version>0.6-beta2</version>
</dependency>

<dependency>
    <groupId>jboss</groupId>
    <artifactId>jboss-ejb-api</artifactId>
    <version>4.2.0.GA</version>
    <scope>provided</scope>
  </dependency>

<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>openejb-client</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>

    <!-- slf4j dependencies for Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>

<!-- logback dependencies -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>

</dependencies>

Note: Existen dependencias de este POM que no son necesarias.

Y por ultimo, creamos un JAR utilizando mvn clean package y lo copiamos en c:\server\jboss-5.0.0.GA\server\default\deploy\

Para ver que el WS esta deployado correctamente, vamos a:

http://localhost:8099/jbossws/services


Para acceder al WSDL, vamos a:

http://localhost:8099/ejb-banco-service/BancoServiceImpl?wsdl

Utilizando el SOAP UI:



Creando un POJO como un Web Service utilizando JAX-WS

Deploying your ejb as webservice is not your only option: you can deploy a POJO as web service as well. In this case you just need to tag@WebService in a plain java class.

Pero para esto, vamos a necesitar armar un WAR y decir que el POJO sera un servlet



When you choose EJB over a POJO for a web service?

JAX-WS 2.0 allows both regular Java classes and stateless EJBs to be exposed as web services. If you
were using J2EE 1.4, you’re probably wondering why you’d use a stateless EJB as a web service. A
look at the code for a POJO and for EJB 3 web services reveals that there are hardly any differences,
with the exception that the EJB 3 web service will have a few extra annotations. A Java class web
service is packaged in a web module whereas an EJB web service is packaged in an EJB-JAR.
Both a Java web service and an EJB web service support dependency injection and lifecycle
methods such as @PostConstruct and @PreDestroy, but you get a few extra benefits from
using EJB 3 web services.

Leer: http://www.mastertheboss.com/jboss-web-services/jboss-web-services-part-1

Connecting to EJB using lookup + JBoss 5

Creamos un EJB

@Remote//Anotamos la interface como remote para poder ser accedida desde JNDI
public interface BancoService {

public long consultarSaldo(String cuenta);

}

@Stateless
public class BancoServiceImpl implements BancoService {

private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final long SALDO_ESTATICO=1000000;

/* (non-Javadoc)
* @see com.gemalto.inlakech.spring.ejb.template.example.BancoService#consultarSaldo(java.lang.String)
*/
@Override
public long consultarSaldo(String cuenta){
logger.info("Entering to method with paraemeters[cuenta:"+cuenta+"]");
//TODO here business logic to get REAL balance
logger.info("The current balance for cuenta["+cuenta+"] is ["+SALDO_ESTATICO+"]");
return SALDO_ESTATICO;
}
}

Deployamos el EJB en JBoss (version 5.0.0.GA)

Creamos un JAR con las dos clases y la deployamos en la carpeta apps:

Ex:
c:\server\jboss-5.0.0.GA\server\default\deploy\ejb-banco-service.jar

Levantamos el JBoss

c:\server\jboss-5.0.0.GA\bin\run.bat


Aqui vemos como el EJB se deployó correctamente bajo el jndi name:

BancoServiceImpl/remote-com.gemalto.inlakech.spring.ejb.template.example.BancoService
óBancoServiceImpl/remote

Cremos un test de integracion

@BeforeClass
public static void setUp() throws NamingException {
Properties props = new Properties();
        props.setProperty("java.naming.provider.url", "localhost:1099");
        props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
        props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
        ctx = new InitialContext(props);

}

@AfterClass
public static void tearDown() throws NamingException {
ctx.close();
}

@Test//Consultar SALDO desde API de EE
public void conlsutarSaldoRemoteEJBTest() throws NamingException {

BancoService service = (BancoService) ctx.lookup("BancoServiceImpl/remote-com.gemalto.inlakech.spring.ejb.template.example.BancoService");
long result = service.consultarSaldo("666");
Assert.assertEquals(SALDO_ESPERADO, result);

BancoService service2 = (BancoService) ctx.lookup("BancoServiceImpl/remote");
long result2 = service2.consultarSaldo("666");

Assert.assertEquals(SALDO_ESPERADO, result2);

}

POM.XML (tanto para crear el jar con el EJB como para crear el test de integracion)

<dependencies>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>

<dependency>
    <groupId>jboss</groupId>
    <artifactId>jboss-ejb-api</artifactId>
    <version>4.2.0.GA</version>
    <scope>provided</scope>
   </dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>

            <!-- slf4j dependencies for Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>

<!-- logback dependencies -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>

</dependencies>

Nota: Existen dependencias en este POM que a los fines de esta prueba pueden no ser necesarias

Importante: la dependencia "jbossall-client" NO ESTA EN EL POM ya que tuve problemas para bajar dicha dependencia... PERO USE LA QUE TRAE EL JBOSS y la agregue al classpath, pero hay que tener en cuenta que este JAR esta vacio, solo tiene referencias a los JARs que se necesitan:

c:\server\jboss-5.0.0.GA\client\jbossall-client.jar

Esta dependencia es vital para acceder remotamente al EJB deployado en el JBOSS.

This jar file contains a classpath reference to various client jar files used by jboss client applications.
Each of the jar files in the following list must available in the same directory as the jbossall-client.jar, Otherwise they will not be found by the classloader.

The classpath includes the following files:
  • commons-logging.jar
  • concurrent.jar
  • ejb3-persistence.jar
  • hibernate-annotations.jar
  • jboss-aop-client.jar
  • jboss-appclient.jar
  • jboss-aspect-jdk50-client.jar
  • jboss-client.jar
  • jboss-common-core.jar
  • jboss-deployers-client-spi.jar
  • jboss-deployers-client.jar
  • jboss-deployers-core-spi.jar
  • jboss-deployers-core.jar
  • jboss-deployment.jar
  • jboss-ejb3-common-client.jar
  • jboss-ejb3-core-client.jar
  • jboss-ejb3-ext-api.jar
  • jboss-ejb3-proxy-client.jar
  • jboss-ejb3-proxy-clustered-client.jar
  • jboss-ejb3-security-client.jar
  • jboss-ha-client.jar
  • jboss-ha-legacy-client.jar
  • jboss-iiop-client.jar
  • jboss-integration.jar
  • jboss-j2se.jar
  • jboss-javaee.jar
  • jboss-jsr77-client.jar
  • jboss-logging-jdk.jar
  • jboss-logging-log4j.jar
  • jboss-logging-spi.jar
  • jboss-main-client.jar
  • jboss-mdr.jar
  • jboss-messaging-client.jar
  • jboss-remoting.jar
  • jboss-security-spi.jar
  • jboss-serialization.jar
  • jboss-srp-client.jar
  • jboss-system-client.jar
  • jboss-system-jmx-client.jar
  • jbosscx-client.jar
  • jbosssx-as-client.jar
  • jbosssx-client.jar
  • jmx-client.jar
  • jmx-invoker-adaptor-client.jar
  • jnp-client.jar
  • slf4j-api.jar
  • slf4j-jboss-logging.jar
  • xmlsec.jar
Leer para entender que pasa con las dependencias del JBoss 5:
http://www.javahelp.info/2010/01/27/get-the-right-dependencies-for-jboss-5-client-and-maven/


Segunda alternativa

Otra alternativa de configuracion y consumo de EJB gracias al aporte de Carlos Weckesser

- La configuración de nuestro pom es la siguiente:

                <properties>
                                ...
                                <jboss-as-client-version>5.1.0.GA</jboss-as-client-version>
                                ...
                </properties>

                <dependencies>
                                ...
                                <dependency>
                                                <groupId>org.jboss.jbossas</groupId>
                                                <artifactId>jboss-as-client</artifactId>
                                                <version>${jboss-as-client-version}</version>
                                                <type>pom</type>
                                                <scope>test</scope>
                                </dependency>
                                ...
                </dependencies>

- Luego definimos una interfaz comun con los metodos necesarios:

                package com.myCompany.myProject.interfaces;

                public interface MyPrettyInterfaceCommon {

                                /** Mapped name for this EJB custom */
                                public static final String MAPPED_NAME = "MyPrettyImplementationConnector";
                             
                                public void performPrettyAction1();
                             
                                public void performPrettyAction2();
                }

- Posteriormente, creamos nuestra interfaz local, extendiendo la misma de la interfaz comun y utilizando las anotaciones correspondientes a un componente "local":

                package com.myCompany.myProject.interfaces;

                @Local(MyPrettyInterfaceLocal.class)
                @LocalBinding(jndiBinding = MyPrettyInterfaceLocal.MAPPED_NAME + "/local")
                public interface MyPrettyInterfaceLocal extends MyPrettyInterfaceCommon {
                             
                }

- A continuación, creamos nuestra interfaz remota, extendiendo la misma de la interfaz comun y utilizando las anotaciones correspondientes a un componente "remoto":

                package com.myCompany.myProject.interfaces;

                @Remote(MyPrettyInterfaceRemote.class)
                @RemoteBinding(jndiBinding = MyPrettyInterfaceRemote.MAPPED_NAME + "/remote")
                public interface MyPrettyInterfaceRemote extends MyPrettyInterfaceCommon {

                }

- Después, definimos una implementación para las interfaces local y remota de la siguiente manera:

                package com.myCompany.myProject.implementations;

                @Stateless(mappedName = MyPrettyImplementationConnector.MAPPED_NAME)
                @TransactionAttribute(TransactionAttributeType.REQUIRED)
                public class MyPrettyImplementationConnector implements MyPrettyInterfaceLocal,
                                                MyPrettyInterfaceRemote {
                                ...
                }

- Por último, vemos un ejemplo de como podemos utilizar inyección de dependencias y resolución de componentes por JNDI para obtener instancias de nuestros componentes:

                package com.myCompany.myProject.implementations;

                public class AnotherClass {
                             
                                // Inyeccion de dependencia de interfaz local
                                @EJB
                                protected MyPrettyInterfaceLocal myPrettyConnectorLocal;
                             
                                // Inyeccion de dependencia de interfaz remota
                                @EJB
                                protected MyPrettyInterfaceRemote myPrettyConnectorRemote;

                                // Lookup via JNDI de interfaz local
                                public void useLocalInterface() {
                                                MyPrettyInterfaceLocal connector = (MyPrettyInterfaceLocal) ctx
                                                                                .lookup("MyPrettyImplementationConnector/local-com" +
                                                                                ".myCompany.myProject.interfaces.MyPrettyInterfaceLocal");
                                                connector.performPrettyAction1();
                                }
                             
                                // Lookup via JNDI de interfaz remota
                                public void useRemoteInterface() {
                                                MyPrettyInterfaceRemote connector = (MyPrettyInterfaceRemote) ctx
                                                                                .lookup("MyPrettyImplementationConnector/remote-com" +
                                                                                ".myCompany.myProject.interfaces.MyPrettyInterfaceRemote");
                                                connector.performPrettyAction1();
                                }
                }