Aplicaciones Distribuidas: Un enfoque práctico
Framework
editarUna definición de framework podría ser que es una plataforma o un entorno de trabajo en el cual se puede desarrollar otro software. El contenido de estos frameworks pueden ser librerías necesarias, así como los lenguajes o lenguaje que permiten el desarrollo de varios componentes que se quiera desarrollar.
Los frameworks te ayudan al manejo y desarrollo de programas que se podrían realizar o los que ya están en desarrollo.
Un ejemplo muy claro es el sistema operativo Windows XP y Windows Vista, ya que el framework en el que está desarrollada es .Net. Si podemos apreciar, en windows, nos muestra el entorno gráfico y todos los beneficios que se muestra en ella.
Como último dato sobre el framework en Windows, es que el último sistema operativo creada por los desarrolladores de Microsoft utilizan el framework 4.0 beta que es especialmente para el Windows 7
Servidor de Aplicaciones - App Server
editarUn servidor de aplicaciones básicamente consiste en poder manejar lo que se refiere a la lógica de negocios, además cuando hablamos de un framework también debemos hablar de un app-server, ya que van de la mano. Uno de los principales objetivos de este servidor es que que tiene la facultad de manejar la gran mayoría de aplicaciones, como puede ser la de acceder a los datos, etc.
Se diría que un servidor de aplicaciones es como un motor de software cuyo principal objetivo es de brindar distintas aplicaciones para los clientes.
Un servidor de Aplicaciones debe tener por una parte las aplicaciones de los clientes y además debe tener donde almacenar los datos ingresados, es decir tener un repositorio de datos donde se puede alojar todo lo enviado por los clientes.
Implementación de patrón de diseño Facade
editarCreamos la clases de la facade Bank.java: El cual va a ir verificando en cada uno de las demás clases de q banco pertenecen
- Ubicamos el siguiente código:
public boolean sufficientSavings( Customer c )
{
System.out.println("Check bank for " + c.getName() );
return true;
}
Customer.java:La clase define los nombres de las variables que va a manejar
- Ubicamos el siguiente código:
private String name
public Customer( String name )
{
this.name = name;
}
public String getName()
{
return name;
}
MortgageApplication.java: Es la que se comunica con las demás clases y aquí es el concepto de facade
- Ubicamos el siguiente código:
int amount;
private Bank bank = new Bank();
private Credit credit = new Credit();
public MortgageApplication( int amount )
{
this.amount = amount;
}
public boolean isEligible( Customer c )
{
if( !bank.sufficientSavings( c ) ) return false;
if( !loan.goodLoan( c ) ) return false;
if( !credit.goodCredit( amount, c )) return false;
return true;
}
Client.java: Llama a la clase Mortage que es la que se comunica con el resto de las clases
- Ubicamos el siguiente código:
public static void main(String[] args)
{
MortgageApplication mortgage = new MortgageApplication(125000);
// Call subsystem through Façade
boolean result = mortgage.isEligible(new Customer("Bob Newhouse"));
// send message to the client ...
}
Finalmente al correr la aplicación vemos lo siguiente y cómo interactúan las clases
Implementación de patrón de diseño Factory
editarDiagrama de clases de la aplicación
Creamos las clases Factory_One.java: Nos va a definir que cuando cambiemos 1 o por 0 las conexiones en la clase cliente
- Ubicamos el siguiente código:
int opción;
public void createConnection(int cero)
{
System.out.println("");
opción=cero;
if(opción==1)
{
System.out.println("Conexión Mysql");
}
else
{
System.out.println("Conexión Oracle");
}
}
Conexión.java:Es la clase interfaz que nos va a permitir poder interactuar con las clases de MySQL y Oracle
- Ubicamos el siguiente código:
public void description()
{
System.out.println("Está en clase Conexión y método Description");
}
MysqlConexion.java: Clase la que permite definir todas las variables de la clase y la función createconnection para definir que cuando se ponga el número 2 será MySQL con extend a la clase Conexión
- Ubicamos el siguiente código:
public class MysqlConexion extends Conexión
{
Factory_One obj_facone = new Factory_One();
Factory_One obj_mysql = new Factory_One();
public void description()
{
super.description();
System.out.println("Mysql conexión, método description");
obj_facone.createConnection(2);
}
}
OracleConexion.java: Clase la que permite definir todas las variables de la clase y la función createconnection para definir que cuando se ponga el número 2 será Oracle con extend a la clase Conexión
- Ubicamos el siguiente código:
public class OracleConexion extends Conexión
{
Factory_One obj_facone = new Factory_One();
Factory_One obj_oracle = new Factory_One();
public void description()
{
System.out.println("Oracle Conexión, método description");
super.description();
obj_facone.createConnection(1);
}
}
Cliente.java: simplemente se llama la función para saber si es 1 o 2 y definir la conexión
- Ubicamos el código:
public void main()
{
Factory_One factory;
factory = new Factory_One();
factory.createConnection(1);
}
Main.java:aquí se hace la llamada a la clase cliente la cual contiene la información de la conexión
- Ubicamos el código:
public static void main(String[] args)
{
// TODO code application logic here
Cliente obj_client = new Cliente();
obj_client.main();
}
Finalmente la corrida del ejercicio
Implementación de patrón de diseño Chain of Responsability
editarCreamos las clases Approver.java: Define simplemente las variables que vamos a utilizar como el nombre, montos
- Ponemos el código:
public abstract class Approver
{
String name;
Approver successor;
public Approver(String name)
{
this.name = name;
}
public void setSuccessor(Approver successor)
{
this.successor = successor;
}
abstract public void processRequest(int amount);
}
Director.java: Utiliza la clase extends para ir definiendo el monto de director
- Ponemos el código:
public class Director extends Approver
{
public Director (String name) {
super(name);
}
public void processRequest(int amount)
{
if (amount < 5000)
System.out.println(name + " approved request $" + amount);
else if (successor != null)
successor.processRequest(amount);
}
}
President.java: Define los momtos que gana el presidente
- Ponemos el código aquí:
public class President extends Approver
{
public President (String name) {
super(name) ;
}
public void processRequest(int amount)
{
if(amount < 100000)
System.out.println(name + " approved request $" + amount);
else
System.out.println("Requires an executive meeting for $" + amount);
}
}
Vicepresident.java: Utiliza la clase Approver y define los montos del Vice presidente
- Ponemos el código:
public class VicePresident extends Approver
{
public VicePresident (String name) {
super(name);
}
public void processRequest(int amount)
{
if (amount < 50000)
System.out.println(name + " approved request $" + amount);
else if (successor != null)
successor.processRequest(amount);
}
}
PurchaseRequest.java: Es la clase main
- Ubicamos el código:
public static void main(String[] args)
{
// Set up Chain of Responsibility
Approver Larry = new Director("Larry");
Approver Jerry = new VicePresident("Jerry");
Approver Tammy = new President("Tammy");
Larry.setSuccessor(Jerry);
Jerry.setSuccessor(Tammy);
// Generate and process different requests
Larry.processRequest(5000);
Larry.processRequest(30000);
Larry.processRequest(80000);
Larry.processRequest(120000);
}
Y finalmente la corrida del programa
Implementación Modelo Vista Controlador (MVC)
editarLa herramienta de aplicación Netbeans beans
La siguiente acción será la de crearnos 3 paquetes con los nombres modelo, vista y controlador
Desplegamos el paquete controlador y vamos a crear un java file 3 java file o que es lo mismo CLASES Primer java file : Lo que hará básicamente es controlar cuando un usuario se desconecta de la sesión C_SignoffAction.java
- Y ponemos el siguiente código:
public String Create(){
return "Realizado";
}
public String Perform(){
modelo.M_model OM=null;
OM=new modelo.M_model();
OM.SignoffUser();
return "Realizado";
}
Segundo java file : Interactúa con capa de la vista para la salida de los datos de mensajes C_TemplatingService.java
- Y ponemos el siguiente código:
public String fordward(){
vista.V_Screen OS =new vista.V_Screen();
OS.generate();
return "ok";
}
Tercer java file : esta clase permite poner el mensaje que queramos visualizar en la capa de salida nos controla los mensajes del mismo. C_controller.java
- Y ponemos el siguiente código:
public String Post()
{ //metodo post
C_SignoffAction OSOA=null;
OSOA=new C_SignoffAction();
OSOA.Create();
OSOA.Perform();
vista.V_ScreenFlowManager OSFM=new vista.V_ScreenFlowManager();
OSFM.SelectView();
C_TemplatingService OTS=new C_TemplatingService();
OTS.fordward();
return "Usuario Desconectado";
}
Una vez concluido vamos a la siguiente capa a la de modelo Creamos una clase: la cual simplemente es la representación en si de la aplicación M_model.java
- Ponemos el siguiente código:
public String SignoffUser()
{return "Usuario Desconectado";
}
Finalmente vamos a la capa de visualización vista Creamos 2 clases Primera java file:Realiza la coordinación para llamar al mensaje del Post de la clase del controlador en este caso C_controller el cual contiene el mensaje. V_Client.java
- Ponemos el siguiente código:
public String CallPost()
{
String retorno;
controlador.C_controller OC=null;
OC=new controlador.C_controller();
retorno=OC.Post();
return retorno;
}
Segundo java file:Simplemente indicará si todo salió bien un mensaje cuando se genera la aplicación de SATISFACTORIO. V_Screen.java
- Ponemos el siguiente código:
public String generate()
{
System.out.println("SATISFACTORIO");
return "ok";
}
Ahora nos falta crear la llamada a la función de la vista en nuestro index.jsp. Este jsp simplemente llama a la función de la vista la cual interactúa con esta a la V.Client la cual se comunicaba con la capa del controlador y finalmente llamamos a la función CallPost de la misma capa de vista Ponemos el siguiente código:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
</body>
<%
vista.V_Client prueba=null //Vista para cliente final
prueba=new vista.V_Client()
%>
<%=prueba.CallPost()%>
</html>
Y finalmente corremos la aplicación con MVC
ComponenteS
editarEJB
editarUn "Javabean" es un componente utilizado en Java que permite agrupar funcionalidades para formar parte de una aplicación, esto puede ser: un "Javabean" agrupando información personal, datos sobre un pedimento, requerimientos de órdenes, etc.
Un "Enterprise Java Bean" también agrupa funcionalidades para una aplicación, sin embargo, a diferencia de un "Javabean" un "Enterprise Java Bean" es un "deployable component", el término "deployable component" implica que existe un ambiente de ejecución , éste ambiente es precisamente un "EJB(Enterprise Java Bean) Container"
Un "Javabean" requiere ser integrado con otros componentes para que éste sea funcional, mientras un "Enterprise Java Bean" a través de un "EJB Container" puede ser activado("deployed"). Ventajas de EJB ("Enterprise Java Beans")
Un EJB a través de un "EJB Container" ofrece varios servicios y funcionalidades no disponibles en un "Javabean", algunas son las siguientes:
Servicios ("Middleware") Esta posiblemente sea la mayor ventaja de un EJB. Cuando se diseña un componente de Software se deben definir varios servicios para su funcionamiento, algunos pueden ser:
- Si ocurre un error que procedimiento debe ejecutarse ?
- Si la base de datos especificada se encuentra desactivada, existe otra alternativa ?
- No fue posible cumplir exitosamente "x" procedimiento, se deben retractar sus acciones parciales o reinvocar la transacción ?
- Estos Servicios (comúnmente llamados "Middleware") por lo general son requeridos además de la lógica contenida en los componentes principales, obviamente estos servicios ("Middleware") aún deben ser diseñados, sin embargo, mediante un "EJB Container" se ofrecen estos servicios y es a través de un "Enterprise Java Bean" que es posible desarrollar los componentes principales ("lógica de negocios").
.NET
editarLa plataforma .NET no es un solo producto. Es un conjunto de productos. Desde sistemas operativos como Windows XP, servidores de aplicaciones como SQL Server 2000, productos de oficina como Office XP, herramientas de desarrollo como Visual Studio .NET hasta servicios Web provistos por Microsoft como .NET Passport.
Los componentes de la plataforma .NET son: Smart Clients (Clientes Inteligentes): Son dispositivos muy variados. Lo que los hace 'Smart' o inteligentes es su capacidad para hacer uso de servicios Web.
Sus características son:
- Permiten acceder a la información en el formato apropiado, en cualquier momento y lugar.
- Hacen uso de Servicios Web.
- Optimizan de distintas maneras la forma en que la información es presentada y organizada. Por ejemplo: Pueden convertir texto en sonido en un celular o reconocer la escritura en un TabletPC.
- Proveen de una interfase sencilla y natural para que el usuario acceda a la información. Pueden utilizar la identidad del usuario, su perfil y datos para adaptar la información que es presentada.
- Pueden reconocer la presencia de otros dispositivos e intercambiar información.
- Pueden adaptarse a las características de la red donde están. Por ejemplo la velocidad de transmisión.
- Tienen capacidad de procesamiento propio, y distribuyen el procesamiento en la red haciendo uso de los servicios Web.
Ejemplo de estos son:
- PocketPC (PC de bolsillo)
- SmartPhone (Teléfono Inteligente)
- HandHelds
- TabletPC
- XBox (Consola de juegos de Microsoft)
Arquitectura Cliente servidor
editarLa arquitectura cliente servidor es la más utilizada al momento de enviar y recibir información.
Arquitectura por Componentes
editarLa arquitectura basada en componentes se caracteriza por:
Los beneficios que ofrece esta arquitectura:
Arquitectura MVC
editarLas características de la arquitectura son:
Formatos de datos
editarJSON
editarPara realizar la comunicación de datos entre un cliente y un servidor tenemos varias alternativas. Una de ellas es JSON, un formato de texto legible y fácil de interpretar así como simple y liviano en comparación a XML.
JSON nos permite realizar la misma tarea pero con menos código. Además permite representar estructuras de datos simples llamados objetos, además de arreglos o colecciones.
En el siguiente ejemplo podemos observar un texto en formato JSON:
{
"nombre": "Maribel",
"apellido": "Benavides",
"dirección": {
"calle": "Esmeraldas y García Moreno",
"número": 345
},
"teléfonos": [
"098738095",
"022847563"
]
}
En este ejemplo:
- nombre y apellido serían pares nombre:valor, los cuales son parte del objeto que empieza en las llaves ubicadas justo antes de este.
- dirección sería un objeto.
- teléfonos sería un arreglo.
XML
editarEn cuanto a XML, es muy similar al HTML, ya que se usan etiquetas pero no predefinidas como <IMG>, sino que podemos encontrar etiquetas personalizadas.
El siguiente es un ejemplo simple que nos permite observar esta característica:
<?xml versión="1.0"?>
<datosPersonales>
<nombre>Maribel</nombre>
<apellido>Benavidez</apellido>
<dirección>
<calle>Prólogo</calle>
<número>345</numero>
</direccion>
</datosPersonales>
Comparándolo a JSON con XML, se puede decir que este primero es más fácil de leer tanto para nosotros como para las PC, ya que no necesitamos definir etiquetas ni atributos para representar datos.
APIs y APIs
editarAPI (application programming interface - Interfaz de Programación de Aplicaciones) es el conjunto de funciones y procedimientos que ofrece ciertas librerías para ser usadas por otro software como otra capa de abstracción.
En otras palabras API es un conjunto de funciones que facilitan el intercambio de mensajes o datos entre dos aplicaciones que trabajan simultáneamente.
Un claro ejemplo de esto está en los Mashup como http://schlafen.zzl.org, que no son más que una mezcla de servicios en los cuales desde un blog, aplicación o página web se puede mostrar música videos, fotografías y más, con tan solo hacer el llamado a las APIs de los respectivos servicios.
El consumo de un API muestra la forma de llamar a cada función y la tarea que ésta desempeña, sin importar cómo se lleva a cabo dicha tarea. Un API hermetiza la complejidad de su operación y solo muestra al programador una fachada que permite acceder a ella.
Para empezar a consumir un API solo es necesario conocer su url y las diferentes funciones que ofrece con la descripción de parámetros.
Hay ciertas API como flickr que necesitan que las personas que desean utilizarlas se registren para obtener su clave de acceso; mientras que hay API de uso público que no necesitan de esta tarea.
Algunas API de ejemplo, que no necesitan de registro pueden encontrarse en http://jsonplaceholder.typicode.com/ que proveen endpoints de JSON para hacer prototipos o pruebas de integración con datos de ejemplos.
APIs Locales
editarEs un conjunto de funciones residentes en librerías generalmente dinámicas, que permiten que una aplicación corra bajo un determinado sistema operativo.
Las funciones API se dividen en varias categorías:
- Depuración y manejo de errores
- E/S de dispositivos
- Varias DLL, procesos e hilos
- Comunicación entre procesos
- Manejo de la memoria
- Monitoreo del desempeño
- Manejo de energía
- Almacenamiento
- Información del sistema
- GDI (interfaz para dispositivos gráficos)
- Interfaz de usuario
Ventajas de una API abierta
editar- Cualquier persona tiene acceso y pueden desarrollar aplicaciones que usen la API.
- No se requiere de mucho trabajo o administración de permisos.
- Permite solicitar información sin guardarla en en una base de datos, tan solo se consume los servicios directamente desde el servidor de la API.
Ventajas de una API cerrada
editar- Permite cifrar las respuestas de la API para que únicamente los usuarios autorizados las utilicen.
- Evita abusos, ya que una API no segura y abierta es blanco de todo tipo de ataques.
- Ideal para publicar información y también para solicitar.
Web Service
editarUn web service básicamente constituye una función accedida vía web por cualquier programa independiente de la plataforma en la cual reside el web service “servicio” o el lenguaje en el que ha sido desarrollado, cabe resaltar que el acceso es mediante el protocolo http pero existen protocolos de transporte que también pueden ser utilizados para este fin.
RESTful Web Services
editarLos RESTful Web Services son una implementación de un servicio usando HTTP y los principios de REST, el cual como resultado no retorna su base de datos completa, sino algún HTML, retornan un resultado en un tipo de dato que pueda ser interpretado por el cliente, estos pueden ser JSON, XML o YAML.
La siguiente gráfica muestra la arquitectura para la construcción de un RESTful Web Service
Las Relaciones que se podrían encontrar entre las acciones SQL y HTTP se explican en el siguiente cuadro
Dónde:
- POST: Crea un dato en el servidor
- PUT: Modificar un dato en el servidor
- GET: Recupera uno o varios datos del servidor
- DELETE: Elimina un dato del servidor
Una manera fácil de entender de mejor manera la creación de un RESTful Web Service, se muestra en el siguiente tutorial http://netbeans.org/kb/docs/websvc/rest.html
Utilizando JSON se puede recuperar la información que nos retorna la base de datos al realizar un test, una implementación fácil de JSON para el retorno de datos utilizando el método GET puede ser
@GET
@Path("/customer/")
@Produces("application/json")
public String getCustomer() {
StringBuilder sb=new StringBuilder();
sb.append("{\"clientes\":[\n\t{\"Número de Fila\":\""+lookupCustomerFacade().findAll().size()+"\"},\n");
try {
List<Customer> ls = lookupCustomerFacade().findAll();
int a=0;
for (Customer s : ls) {
a++;
sb.append("\t{\"Código\":\""+s.getCustomerId().toString()+"\",");
sb.append("\"Nombre\":\""+s.getName()+"\",");
sb.append("\"Ciudad\":\""+s.getCity()+"\",");
sb.append("\"CreditoLimite\":\""+s.getCreditLimit().toString()+"\",");
sb.append("\"Tipo\":\""+s.getAddressline1()+"\"}");
if(a<ls.size()){
sb.append(",\n");
}
}
sb.append("\n ]\n");
sb.append("}");
return sb.toString();
} catch (Exception ex) {
return "{\"Clientes\":[{\"httpStatus\":\"404\",\"Exception\":\"" + ex + "\"}]}";
}
SOAP
editarProporciona una vía de comunicación entre aplicaciones ejecutados en sistemas operativos diferentes, con diferentes tecnologías y lenguajes de programación.
- SOAP son siglas de Simple Object Access Protocol.
- SOAP es un protocolo de comunicación.
- SOAP usado para la comunicación entre aplicaciones.
- SOAP es un formato para el envió de mensajes.
- SOAP se comunica a través de internet.
- SOAP es independiente de la plataforma.
- SOAP es independiente del lenguaje.
- SOAP es basado en XML.
Un mensaje SOAP es un documento XML que contiene:
- Un Elemento que identifica el documento XML como un mensaje SOAP (envelope).
- Un elemento de encabezado (header) que contiene información de encabezado .
- Un elemento de cuerpo(body) que contiene la llamada y respuesta de información.
- Un elemento de culpa (Fault)que contienen errores e información de estado de la información.
Estructura de un mensaje SOAP
editarSu estructura es la siguiente
<? xml versión = "1.0"?
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header> <soap:Header>
... ...
</soap:Header> </ soap: Header>
<soap:Body> <soap:Body>
... ...
<soap:Fault> <soap:Fault>
... ...
</soap:Fault> </ soap: Fault>
</soap:Body> </ soap: Body>
</soap:Envelope> </ soap: Envelope>
SOAP Envelope
editarElemento raíz de un mensaje SOAP, define al XML como un mensaje SOAP.
<?xml versión="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
...
Mensaje
...
</soap:Envelope>
Encoding style se utiliza para definir los tipos de datos utilizados en el documento. Xmlns .El espacio de nombres define como una envoltura SOAP.
SOAP HEADER
editarEl elemento opcional, SOAP Header contiene información específica de aplicaciones sobre el mensaje SOAP.
<?xml versión="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
<m:Trans xmlns:m="http://www.demo.com/transaction/"
soap:mustUnderstand="1">234
soap: actor = "http://www.demo.com/appml/"> 234
</m:Trans>
</soap:Header>
...
...
</soap:Envelope>
SOAP define tres atributos en el espacio de nombres por defecto: MustUnderstand, actor y encodingStyle.
Los atributos definidos en el encabezado SOAP define como un receptor debe procesar el mensaje SOAP.
El atributo MustUnderstand SOAP indica si la entrada de la cabecera es obligatorio o facultativo para el destinatario del proceso.
El atributo de actor SOAP se utiliza para abordar el elemento de cabecera a un extremo específico
El atributo encodingStyle define tipos de datos utilizados en el documento
SOAP BODY
editar <?xml versión="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body>
<m:GetPrecio xmlns:m="http://www.demo.com/precios">
<m:Item>Macbookpro 13 inch</m:Item>
</m:GetPrecio>
</soap:Body>
</soap:Envelope>
El elemento requerido SOAP Body contiene el mensaje SOAP reales destinados para el extremo final del mensaje.
El mensaje de arriba pide el precio de una manzana.
Respuesta Soap
<? xml versión = "1.0"?
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body>
<m:GetPrecioResponse xmlns:m="http://www.demo.com/precios">
<m:Precio>1.390</m:Precio>
</ m: GetPrecioResponse>
</soap:Body>
</soap:Envelope>
SOAP Fault
editarInforman y mantiene información de estado de un mensaje SOAP.
<faultcode> Un código de identificación de la falla <faultstring> Una explicación legible del error <faultactor> Información acerca de quién causó el error de que ocurra <detail> Tiene información específica sobre la aplicación , error relacionados con el elemento Body