Angel "Java" Lopez

NET, Java, PHP y Desarrollo de Software

This Blog

Syndication

Search

Tags

Community

Email Notifications

Archives

.NET

ASP.NET

Windows Form

VB.NET

C#

Sitios

Blogs

July 2006 - Posts

Hacia el AjServer

Mientras sigo trabajando duro en mi proyecto AjGenesis (estoy generando código, scripts de SQL, y otros artefactos de texto, a partir de un modelo, y ahora, en la nueva versión aún no publicada, hasta alimentándome de la base de datos para generar las entidades), hace ya un tiempo comencé a delinear el AjServer. El año pasado lo había presentado en una charla del Microsoft Users Group de Argentina, y este año ha estado evolucionando.

El AjServer trata de ser un conjunto de librerías que se usan en un cliente y en un servidor. Desde el punto de vista del cliente, permite invocar a lo que podemos llamar una "acción", identificada por un nombre. Desde el cliente, alguna clase implementa:

Function Execute(ByVal action As String, ByVal ParamArray values As Object()) As Object

es decir, dado el nombre de la acción y los parámetros, el AjServer invoca a algo que se define por configuración. Lo más normal es que esa acción se encuentre en un servidor remoto basado en AjServer, pero también puede ser un método local. Un archivo de configuración de cliente podría incluir

 <AjClient>
  <EndPoints>
   <EndPoint Name="RemoteServer" Url="http://localhost:10000/RemoteServer.soap" Type="AjServer.Common.IServer, AjServer.Common"/>
   <EndPoint Name="OtherRemoteServer" Url="http://localhost:10000/OtherRemoteServer.soap" Type="AjServer.Common.IServer, AjServer.Common"/>
  </EndPoints>
  <Services>
   <Service>
    <Actions>
     <Action Name="HelloWorld" EndPoint="RemoteServer"/>
     <Action Name="OtherHelloWorld" EndPoint="OtherRemoteServer"/>
     <Action Name="NewPerson" EndPoint="RemoteServer"/>
    </Actions>
   </Service>
  </Services>
 </AjClient>

Los "endpoints" pueden corresponder a distintas tecnologías, ya sea remoting, como podría ser un web service especial que exponga algún AjServer remoto. Mientras, un programa servidor que albergue a la librería AjServer, puede exponer esos endpoints como quiera (se puede implementar un nuevo tipo de endpoint, me imagino que implementaré en algún momento uno en Windows Communication Foundation). Un clásico archivo de configuración servidor:

 <AjServer>
  <Channels>
   <Channel Port="10000" Protocol="http"/>
<!--   
   <Channel Port="10000"/>
-->   
  </Channels>
  
  <Servers>
  <Server>
  
  <Assembly Name="TestConsole01" Prefix="My"/>
  
  <Queues>
   <Queue Name="HelloQueue"/>
  </Queues>
  
  <Commands>
   <Command Name="PrintLine2">
    <Print Value="${Value}"/>
    <PrintLine Value="${Value2}"/>
   </Command>
   <Command Name="Print" Type="AjServer.Server.PrintCommand, AjServer.Server"/>
   <Command Name="PrintLine" Type="AjServer.Server.PrintLineCommand, AjServer.Server"/>
   <Command Name="Set" Type="AjServer.Server.SetCommand, AjServer.Server"/>
  </Commands>
  
  <Actions>
   <Action Name="HelloWorld">
    <ProcessStart Name="HelloProcessA"/>
    <PrintLine Value="Hello, World"/>
    <PrintLine Value="${Request.Action}"/>
    <ResponseNew/>
    <Set Var="Response.Message" Value="Hello, World"/>
    <PrintLine Value="${Response.Message}"/>
    <MyPrint Value="Hello, World again"/>
    <ProcessStart Name="HelloProcess"/>
    <IfPresent Test="${Message}">
     <PrintLine Value="Message is present"/>
    </IfPresent>
    <IfNotPresent Test="${Message}">
     <PrintLine Value="Message is not present"/>
    </IfNotPresent>
    <If Value="${Headers}">
     <PrintLine Value="There are headers"/>
    </If>
    <Else>
     <PrintLine Value="No headers"/>
    </Else>
    <ContextNew Var="NewContext">
     <Item Key="ProcessMessage" Value="${Request.Action}"/>
    </ContextNew>
    <ProcessStart Name="ContextProcess" Context="${NewContext}"/>
    <QueueEnqueue Name="HelloQueue" Value="${Request.Action}"/>
   </Action>
   <Action Name="NewPerson">
    <ObjectNew Var="Person" Type="TestConsole01.Person, TestConsole01"/>
    <Set Var="Person.Name" Value="Adan"/>
    <PrintLine Value="${Person.Name}"/>
    <Set Var="Person.Age" Value="800"/>
    <PrintLine Value="${Person.Age}"/>
    <PrintLine2 Value="Person " Value2="${Person.Name}"/>
    <Invoke Object="${Person}" Method="Describe"/>
    <Invoke Object="${Person}" Method="AddYears">
     <Parameter Value="100" Type="System.Int32"/>
    </Invoke>
    <Invoke Object="${Person}" Method="Describe"/>
    <Try>
     <Invoke Object="${Person}" Method="UnknowMethod"/>
    </Try>
    <Catch Var="Exception">
     <Print Value="Exception "/>
     <PrintLine Value="${Exception.Message}"/>
    </Catch>
    <For Var="k" From="1" To="10">
     <ContextClone Var="Ctx"/>
     <Start Context="${Ctx}">
      <Print Value="Starting "/>
      <Print Value="${k}"/>
      <PrintLine Value="..."/>
     </Start>
    </For>
    <Set Var="k" Value="10"/>
    <While Test="${k}">
     <Print Value="While"/>
     <Break/>
    </While>
   </Action>
  </Actions>

  <Processes>
   <Process Name="HelloProcess">
    <PrintLine Value="Hello Process"/>
    <QueueEnqueue Name="HelloQueue" Value="Message from Process"/>
    <PrintLine Value="Process ends"/>
   </Process>
   <Process Name="HelloProcessA">
    <PrintLine Value="Hello ProcessA"/>
    <PrintLine Value="Process begins"/>
   </Process>
   <Process Name="ContextProcess">
    <PrintLine Value="Context Process in action"/>
    <PrintLine Value="${ProcessMessage}"/>
   </Process>
  </Processes>
  
  <Workers>
   <Worker PoolSize="10">
    <Guid Var="WorkerId"/>
    <Print Value="Worker activated: "/>
    <PrintLine Value="${WorkerId}"/>
    <QueueDequeue Var="Msg" Name="HelloQueue"/>
    <Print Value="Worker in action: "/>
    <PrintLine Value="${WorkerId}"/>
    <PrintLine Value="${Msg}"/>
   </Worker>
  </Workers>

<!--
  <Workers>
   <Worker>
    <PrintLine Value="I'm still working"/>
    <Sleep Value="1000"/>
   </Worker>
   <Worker>
    <FileWait Var="File" Path="..\Dir1" Pattern="*.txt"/>
    <Print Value="Processing 1 "/>
    <PrintLine Value="${File}"/>
    <FileCombine Var="FullFile" Path="..\Dir1" File="${File}"/>
    <FileCombine Var="FullFile2" Path="..\Dir2" File="${File}"/>
    <FileMove From="${FullFile}" To="${FullFile2}"/>
    <Sleep Value="100"/>
   </Worker>
   <Worker>
    <FileWait Var="File" Path="..\Dir2" Pattern="*.txt"/>
    <Print Value="Processing 2 "/>
    <PrintLine Value="${File}"/>
    <FileCombine Var="FullFile" Path="..\Dir2" File="${File}"/>
    <FileCombine Var="FullFile2" Path="..\Dir1" File="${File}"/>
    <FileMove From="${FullFile}" To="${FullFile2}"/>
    <Sleep Value="200"/>
   </Worker>
   <Worker>
    <FileWait Var="File" Path="..\Dir1" Pattern="*.xml"/>
    <Print Value="Processing 1x "/>
    <PrintLine Value="${File}"/>
    <FileCombine Var="FullFile" Path="..\Dir1" File="${File}"/>
    <XmlLoad Var="Document" File="${FullFile}"/>
    <FileCombine Var="FullFile2" Path="..\Dir2" File="${File}"/>
    <XmlSave Value="${Document}" File="${FullFile2}"/>
    <FileDelete File="${FullFile}"/>
    <Sleep Value="100"/>
   </Worker>
   <Worker>
    <FileWait Var="File" Path="..\Dir2" Pattern="*.xml"/>
    <Print Value="Processing 2x "/>
    <PrintLine Value="${File}"/>
    <FileCombine Var="FullFile" Path="..\Dir2" File="${File}"/>
    <XmlLoad Var="Document" File="${FullFile}"/>
    <FileCombine Var="FullFile2" Path="..\Dir1" File="${File}"/>
    <XmlSave Value="${Document}" File="${FullFile2}"/>
    <FileDelete File="${FullFile}"/>
    <Sleep Value="100"/>
   </Worker>
  </Workers>
-->

  </Server>

  <Server Name="OtherServer">
  
  <Assembly Name="TestConsole01" Prefix="My"/>
  
  <Commands>
   <Command Name="Print" Type="AjServer.Server.PrintCommand, AjServer.Server"/>
   <Command Name="PrintLine" Type="AjServer.Server.PrintLineCommand, AjServer.Server"/>
   <Command Name="Set" Type="AjServer.Server.SetCommand, AjServer.Server"/>
  </Commands>
  
  <Actions>
   <Action Name="OtherHelloWorld">
    <PrintLine Value="Hello, World Other Server"/>
    <ResponseNew/>
    <Set Var="Response.Message" Value="Hello, Other World"/>
   </Action>
  </Actions>
  </Server>

  </Servers>
  
  <EndPoints>
   <EndPoint Name="RemoteServer.soap" Type="TestConsole01.RemoteServer, TestConsole01"/>
   <EndPoint Name="OtherRemoteServer.soap" Type="TestConsole01.OtherRemoteServer, TestConsole01" Server="OtherServer"/>
<!--   
   <EndPoint Name="RemoteServer.rem" Type="TestConsole01.RemoteServer, TestConsole01"/>
-->
  </EndPoints>
 </AjServer>

Noten que aparte de acciones, hay procesos, hilos de ejecución en paralelo, que se lanzan en cualquier momento, desde alguna acción o ante un evento externo al sistema. Contempla luego la existencia de workers: threads de ejecución que se quedan trabajando, esperando trabajo para realizar. Como ven, hay un lenguaje de comandos en XML incluido, y los comandos son predefinidos, o pueden definirse en la configuración, o pueden escribirse e incorporarse a la librería. Siguiendo las ideas de Spring, desde un comando se puede invocar en forma no intrusiva a un método de un objeto nuestro.

Faltan cosas, como un buen Proof of Concept, implementarlo como servicio windows, manejar múltiples AppDomains por configuración, y cuarenta mil etcéteras. Pero me pareció interesante publicarlo algo.

La idea es, luego de tener algún "feedback" en .NET, implementarlo de la misma forma en Java.

Angel "Java" Lopez
http://www.ajlopez.com/

Posted Thu, Jul 20 2006 11:34 by lopez | 4 comment(s)

How To de Arquitectura .NET

El jueves 27 de Julio dictaremos con el Gran Woloski una charla (gratuita) de arquitectura en Microsoft de Argentina, en Buenos Aires. El temario del evento es


Tema: Programación en capas arquitecturas y patrones
Fecha: 27 de Julio
Horario: 9:00 a 13:00
Lugar: Oficinas MS Buenos Aires, Bouchard e/Córdoba y Viamonte, Piso 4

Con la llegada de .NET, se abrieron posibilidades de desarrollo, usando
patrones y mejores prácticas. La amplitud del framework, las capacidades nuevas que
tenemos, desde aplicaciones web hasta aplicaciones distribuidas hasta servicios windows,
nos lleva a estudiar cuestiones de arquitectura: cómo se compone ahora una aplicación
.NET? qué patrones y mejores prácticas podemos usar, con las herramientas actuales?


En esta charla, trataremos estas cuestiones.

Arquitectura de Aplicaciones
  Arquitectura de Capas
    Qué Capas?
    Qué poner en cada Capa?
  Implementando la misma aplicación, con distintas presentaciones:
    Aplicación Windows
    Aplicación Web
    Aplicación Windows Remota
    Determinando el Transporte por configuración
 Pasaje de datos entre capas físicas
   DataSet vs Objetos Tipados
   Web Services
   Remoting
   Windows Communication Framework
 Modelado de Lógica de Negocio
   Patrón Service Layer
   Patrón Transaction Script
   Patrón Domain Model
 Conceptos de Persistencia de objetos
 Conceptos de Generación de código
 Software Factories
   Que son las Software Factores de Patterns and Practices
   Smart Client Software Factory
   Web Service Software Factory

Espero que les guste, pueden inscribirse aquí

Angel "Java" Lopez
http://www.ajlopez.com/

Posted Mon, Jul 17 2006 15:20 by lopez | with no comments

Filed under: ,

Scrum en Argentina

Los buenos de Alejandro Jack y Antonio Castaño, me avisan de este curso a realizarse en mi pais, muy interesante. Ya me anoté para asistir. Es un curso pago, pero me pareció importante compartir el aviso con Uds. He aquí el email que recibí con la promoción del curso:

=========================================

PRIMER CURSO DE CERTIFICACION DE SCRUM EN AMERICA LATINA

Scrum, la metodología ágil de mayor crecimiento en los  últimos años, se destaca por ofrecer un marco sencillo para atacar problemas complejos.

De los 3 roles que se  definen, sin duda el más crucial para su implementación es el de ScrumMaster, quien realizará las tareas propias de un Project Manager, pero siguiendo principios ágiles.

El curso Certified ScrumMaster, dictado únicamente por alguno de los 40 trainers autorizados por la ScrumAlliance, permite obtener, de forma interactiva y en solamente 2 días, el conocimiento y la práctica necesarios para  comenzar a utilizar Scrum en su proyecto.

Dictado hasta el momento únicamente en Europa y USA, el curso Certified ScrumMaster se dictará por primera vez en América Latina durante los días 8 y 9 de Agosto de 2006 en la Facultad de Ingeniería de la Universidad Católica Argentina.

El mismo estará a cargo de Tobias Mayer (trainer oficial - www.agilethinking.net) y el cupo es limitado.

El valor de la inscripción es de 300 dólares, a ser abonados integramente al momento de realizar la reserva.

El pago podrá realizarse en efectivo o mediante PayPal.

Es posible encontrar más información sobre el curso en http://agilethinking.net/argentina-csm.pdf
 

Para más detalles o aclaraciones, contactarse con Alan Cyment a la dirección de correo acyment@yahoo.com 
 
 
=========================================

Nos leemos!

Angel "Java" Lopez
http://www.ajlopez.com/ 
 

Posted Fri, Jul 14 2006 15:23 by lopez | with no comments