martes, 28 de noviembre de 2017

Diferencia entre git push -u y git push

En el post de hoy vamos a explicar las diferencias entre los comandos git push -u origin master y git push origin master. Aunque ambos comandos sirven para enviar nuestros cambios a un repositorio remoto, la bandera -u permite también agregar referencias ascendentes de seguimiento; en otras palabras, a partir de este punto, Git sabrá hacia dónde enviar y de dónde obtener los cambios sin la necesidad de utilizar argumentos en los comandos git push y git pull.

Si no establecemos el upstream para el seguimiento, cuando invoquemos al comando git pull, se nos presentará un error indicándonos que no existe información de seguimiento para la rama actual. La siguiente imagen ilustra este escenario.



Por otra parte, si ejecutamos el comando con la bandera -u, a partir de ese momento se creará una referencia de trazabilidad que nos permitirá invocar, por ejemplo, al comando git pull sin la necesidad de argumentos.

sábado, 25 de noviembre de 2017

Crear dominio en Servidor Glassfish

Un dominio Glassfish es un conjunto de instancias o espacio de nombres administrativos que se pueden administrar de forma conjunta. Este mismo proporciona una configuración preconfigurada para todas las aplicaciones del usuario o cliente, en este caso se pueden editar acorde a lo que necesitemos. Para crear un dominio, lo primero que debemos hacer es ubicarnos en la instalación de nuestro Glassfish y a continuación ejecutar el comando:
asadmin create-service domain1
Si todo se realizó correctamente, obtendremos el mensaje mostrado en la siguiente imagen:



Ahora inicimos nuestro Glassfish a través del comando:
asadmin start-domain


Si todo se ejecutó correctamente, al acceder a la ruta http://localhost:8080, podremos visualizar la consola de administración de nuestro contenedor de aplicaciones.
Para reiniciar nuestro dominio podemos usar el comando:
asadmin restart-domain domain1

miércoles, 22 de noviembre de 2017

RestController con Spring Boot

En este post vamos a revisar un ejemplo sencillo de lo que sería los servicios Rest utilizando Spring Framework. Las tecnologías requeridas para este proyecto son:
  • Spring Boot
  • H2
  • Maven
  • JDK 8
A continuación se muestra la estructura del proyecto Maven. En este proyecto, utilizaremos una base de datos H2 la cual podremos manipular a través de tres servicios Rest ya sea para insertar, consultar un registro o listar una tabla.



El archivo POM de dependencias Maven es el siguiente:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.rolandopalermo.git</groupId>
 <artifactId>base-api-rest-springboot</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>
 
 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.0.RELEASE</version>
    </parent>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    
 <dependencies>
  
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>
 
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  
  <dependency>
   <groupId>com.h2database</groupId>
   <artifactId>h2</artifactId>
  </dependency>
 </dependencies>
 <build>
  <finalName>base-api-rest-springboot</finalName>
 </build>
</project>
La clase principal utilizada para iniciar Spring Boot es la siguiente:
package com.rolandopalermo.rest.base;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

 public static void main(String[] args) {
  SpringApplication.run(Application.class, args);
 }

}
La siguiente clase representa el bean que será utilizado para manipular nuestra base de datos. Este bean utilizará anotaciones las cuales le permitirán validar la correcta estructura de campos en cualquier instancia así como también manipular este bean como objeto JSON.
package com.rolandopalermo.rest.base.model;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;

import org.hibernate.validator.constraints.NotBlank;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;

@Entity
public class User {

 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 private Long id;

 @JsonProperty("user_name")
 @NotBlank
 private String userName;

 @JsonProperty("last_name")
 @NotBlank
 private String lastName;

 @JsonProperty("gender")
 @NotNull
 private Gender gender;

 @JsonProperty("age")
 @Min(value = 18)
 @Max(value = 150)
 @NotNull
 private Integer age;

 @JsonProperty("birth")
 @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
 @Past
 @NotNull
 private Date dateOfBirth;

 public Long getId() {
  return id;
 }

 public void setId(Long id) {
  this.id = id;
 }

 public String getUserName() {
  return userName;
 }

 public void setUserName(String userName) {
  this.userName = userName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public Gender getGender() {
  return gender;
 }

 public void setGender(Gender gender) {
  this.gender = gender;
 }

 public Integer getAge() {
  return age;
 }

 public void setAge(Integer age) {
  this.age = age;
 }

 public Date getDateOfBirth() {
  return dateOfBirth;
 }

 public void setDateOfBirth(Date dateOfBirth) {
  this.dateOfBirth = dateOfBirth;
 }

}
package com.rolandopalermo.rest.base.model;

public enum Gender {
    MALE, FEMALE;
}
Esta clase se encargá de definir los métodos para acceder a base de datos. En este caso se reutilizará la clase genérica CrudRepository.
package com.rolandopalermo.rest.base.repository;

import org.springframework.data.repository.CrudRepository;

import com.rolandopalermo.rest.base.model.User;
 
public interface UserRepository extends CrudRepository<User, Long> {
 
}
La clase UserService conformará la capa de servicio y es en donde se invocará a los métodos definidos en la clase UserRepository que vendría siendo nuestra capa de datos.
package com.rolandopalermo.rest.base.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.rolandopalermo.rest.base.model.User;
import com.rolandopalermo.rest.base.repository.UserRepository;

@Service
public class UserService {

 @Autowired
 private UserRepository repository;

 public User get(long userId) {
  return repository.findOne(userId);
 }

 public List<User> list() {
  Iterable<User> users = repository.findAll();
  List<User> list = new ArrayList<User>();
  for(User user : users) {
   list.add(user);
  }
  return list;
 }

 public User create(User user) {
  return repository.save(user);
 }
}
La clase UserController expondrá los diversos métodos para manipular la tabla de Usuarios. Estos serán para insertar, consultar un registro o listarlos todos. Estos servicios serán expuestos a través de los métodos POST y GET.
package com.rolandopalermo.rest.base.controller;

import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.rolandopalermo.rest.base.model.User;
import com.rolandopalermo.rest.base.service.UserService;

@RestController
public class UserController {

 @Autowired
 private UserService userService;

 @RequestMapping(value = "/users", method = RequestMethod.GET)
 public ResponseEntity<User> list() {
  List<User> users = userService.list();
  return new ResponseEntity(users, HttpStatus.OK);
 }

 @RequestMapping(value = "/user", method = RequestMethod.GET)
 public ResponseEntity<User> userById(@RequestParam(value = "id") long id) {
  User user = userService.get(id);
  return new ResponseEntity(user, HttpStatus.OK);
 }

 @RequestMapping(value = "/create", method = RequestMethod.POST)
 public ResponseEntity<User> create(@Valid @RequestBody User user) {
  User userCreated = userService.create(user);
  return new ResponseEntity(userCreated, HttpStatus.CREATED);
 }

}
Al ejecutar el proyecto, tendremos lo siguiente:



Al enviar la siguiente petición utilizando POSTMAN, el resultado será el siguiente:
{
   "id":1,
   "user_name":"Juan",
   "last_name":"Perez",
   "gender":"MALE",
   "age":23,
   "birth":"12-10-1994"
}


Cuando consultemos los registros ingresados, obtendremos lo siguiente:
[
    {
        "id": 1,
        "user_name": "Juan",
        "last_name": "Perez",
        "gender": "MALE",
        "age": 23,
        "birth": "12-10-1994"
    },
    {
        "id": 2,
        "user_name": "Juan",
        "last_name": "De Arco",
        "gender": "FEMALE",
        "age": 23,
        "birth": "12-10-1994"
    }
]


El proyecto completo se encuentra disponible en el siguiente enlace:

martes, 14 de noviembre de 2017

Creating Web Services with PHP and SOAP

There are two basic approaches that are used to create web services from scratch. In this first of a two part series on web services I’ll talk about the 'top-down' approach. According with this approach, we need to produce the XML description of the service before it is implemented. So the service is fully described in terms of what it does, how it can be called and what result(s) it returns, but is not actually implemented. This (WSDL) specification is then used as a guide to writing the code that implements the service.

The project structure



The webservice will receive a string parameter and it will return the 'hello' string concatenated with the input parameter. For example, if the input is 'Andrea', then the output will be 'Hello Andrea'. In order to achieve this, we need to define the WSDL descriptor.

The descriptor.wsdl
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="HelloWS"
      targetNamespace="http://ws.rolandopalermo.com/"
      xmlns:tns="http://ws.rolandopalermo.com/"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">

 <wsdl:types>
 </wsdl:types>
  
 <wsdl:message name="helloRequest">
  <wsdl:part name="name" type="xsd:string"></wsdl:part>
 </wsdl:message>
 
 <wsdl:message name="helloResponse">
  <wsdl:part name="result" type="xsd:string"></wsdl:part>
 </wsdl:message>
  
 <wsdl:portType name="HelloWS">
  <wsdl:operation name="hello">
            <wsdl:input message="tns:helloRequest"/>
            <wsdl:output message="tns:helloResponse"/>
        </wsdl:operation>
 </wsdl:portType>
  
 <wsdl:binding name="HelloWSPortBinding" type="tns:HelloWS">
  <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
  <wsdl:operation name="hello">
   <soap:operation soapAction="http://localhost/soap_demo/server.php"/>
   <wsdl:input>
    <soap:body use="literal"/>
   </wsdl:input>
   <wsdl:output>
    <soap:body use="literal"/>
   </wsdl:output>
  </wsdl:operation>
 </wsdl:binding>
  
 <wsdl:service name="HelloWS">
  <wsdl:port name="HelloWSPort" binding="tns:HelloWSPortBinding">
   <soap:address location="http://localhost/soap_demo/server.php"/>
  </wsdl:port>
 </wsdl:service>
 
</wsdl:definitions>
We also need to implement the hello method in a php file.

The server.php file
<?php
// turn off WSDL caching
ini_set("soap.wsdl_cache_enabled","0");

function hello($name)
{
 return 'Hello '.' '.$name;
}

// initialize SOAP Server
$server = new SoapServer("descriptor.wsdl",[]);
// register available functions
$server->addFunction('hello');
// start handling requests
$server->handle();
Now, we can import the WSDL file into SoapUI for example and the results should look like this:

The SOAP request.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.rolandopalermo.com/">
   <soapenv:Header/>
   <soapenv:Body>
      <ws:hello>
         <name>Andrea</name>
      </ws:hello>
   </soapenv:Body>
</soapenv:Envelope>
The SOAP response.
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Body>
      <SOAP-ENV:helloResponse>
         <result>Hello  Andrea</result>
      </SOAP-ENV:helloResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Do not forget to enable the SOAP extension in the php.ini file. To do this, you have to find extension=php_soap.dll in php.ini, remove the semicolon(;) and restart the server.