composición de requerimientos no funcionales

16
PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE Composición de Requerimientos No Funcionales Gerson Samaniego, José Pulido Universidad de los Andes [email protected], [email protected], Resumen. Incluir requerimientos no funcionales (RNF) en una aplicación de forma sencilla para el desarrollador es una de las características que debería ofrecer un modelo de componentes. Lograr que el desarrollador se centre en el diseño e implementación de la lógica funcional permite obtener mejores resultados en las aplicaciones. En este artículo planteamos una solución para incluir RNFs en un modelo de componentes. La estrategia consiste en definir los RNFs como componentes no funcionales (CNF) y en definir la composición de éstos con componentes funcionales (CF) u otros CNFs de manera externa. Para expresar la interacción entre los componentes proponemos un lenguaje de dominio específico orientado a aspectos. Ilustramos nuestra propuesta con un caso de estudio de una aplicación de comercio electrónico en donde incluimos algunos requerimientos no funcionales. Palabras claves. Programación orientada por aspectos (AOP), Software basado en componentes (CBSD), Requerimientos no funcionales. 1 INTRODUCCIÓN El objetivo del desarrollo de software basado en componentes (CBSD) es construir aplicaciones complejas mediante el ensamblado de partes, llamadas componentes. Un componente es una pieza de código pre-elaborado que expone su funcionalidad a través de interfaces estándar [28]. Son los "ingredientes de las aplicaciones", que se juntan y combinan para llevar a cabo una tarea [4]. Su objetivo principal es la separación de código en unidades auto-contenidas para promover la reutilización [8]. Por ser independientes, simplifican las pruebas facilitando la evaluación de su funcionalidad individualmente y mejoran la calidad de las aplicaciones [6]. Los componentes pueden existir y cooperar dentro de contenedores, entidades de software que permiten contener a otras entidades, proporcionando un entorno compartido de interacción [14]. En los modelos componente-contenedor, los contenedores simplifican el desarrollo de aplicaciones ofreciendo algunos aspectos no funcionales complejos, tales como transacciones, seguridad, persistencia entre otros, a todos los componentes. Estos servicios pueden ser utilizados por el desarrollador de manera declarativa facilitando así el desarrollo de las aplicaciones.

Upload: others

Post on 20-Jul-2022

28 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Composición de Requerimientos No Funcionales

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE

Composición de Requerimientos No Funcionales

Gerson Samaniego, José Pulido Universidad de los Andes

[email protected], [email protected],

Resumen. Incluir requerimientos no funcionales (RNF) en una aplicación de forma sencilla para el desarrollador es una de las características que debería ofrecer un modelo de componentes. Lograr que el desarrollador se centre en el diseño e implementación de la lógica funcional permite obtener mejores resultados en las aplicaciones. En este artículo planteamos una solución para incluir RNFs en un modelo de componentes. La estrategia consiste en definir los RNFs como componentes no funcionales (CNF) y en definir la composición de éstos con componentes funcionales (CF) u otros CNFs de manera externa. Para expresar la interacción entre los componentes proponemos un lenguaje de dominio específico orientado a aspectos. Ilustramos nuestra propuesta con un caso de estudio de una aplicación de comercio electrónico en donde incluimos algunos requerimientos no funcionales. Palabras claves. Programación orientada por aspectos (AOP), Software basado en componentes (CBSD), Requerimientos no funcionales.

1 INTRODUCCIÓN

El objetivo del desarrollo de software basado en componentes (CBSD) es construir aplicaciones complejas mediante el ensamblado de partes, llamadas componentes. Un componente es una pieza de código pre-elaborado que expone su funcionalidad a través de interfaces estándar [28]. Son los "ingredientes de las aplicaciones", que se juntan y combinan para llevar a cabo una tarea [4]. Su objetivo principal es la separación de código en unidades auto-contenidas para promover la reutilización [8]. Por ser independientes, simplifican las pruebas facilitando la evaluación de su funcionalidad individualmente y mejoran la calidad de las aplicaciones [6].

Los componentes pueden existir y cooperar dentro de contenedores, entidades de software que permiten contener a otras entidades, proporcionando un entorno compartido de interacción [14]. En los modelos componente-contenedor, los contenedores simplifican el desarrollo de aplicaciones ofreciendo algunos aspectos no funcionales complejos, tales como transacciones, seguridad, persistencia entre otros, a todos los componentes. Estos servicios pueden ser utilizados por el desarrollador de manera declarativa facilitando así el desarrollo de las aplicaciones.

Page 2: Composición de Requerimientos No Funcionales

2 Gerson Samaniego, José Pulido

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE

En otros modelos de componentes, los requerimientos no funcionales son expresados como capas de control que se pueden extender como en Fractal [5], o definidos en un lenguaje de aspectos por ejemplo en AspectJ2EE [25] para los EJBs o FractNet [15] para Fractal en .net.

La programación orientada a aspectos (AOP) [2], tiene como objetivo permitir el aislamiento, la composición y eficaz reutilización de código transversal presente en una aplicación. Basados en las propuestas, CBSD y AOP, se han planteado modelos de integración como el presentado en [17], cuyo objetivo principal es crear modelos que unan los componentes y los aspectos.

Nuestra propuesta busca separar los aspectos funcionales de los no funcionales y proveer una forma de composición que los relacione, basándonos en CBSD y AOP. Se crean componentes funcionales (CF) y componentes no funcionales (CNF) como elementos independientes.

Para la composición entre el CF y los CNFs, definimos un mecanismo que expresa la interacción de forma externa a los componentes, mediante un lenguaje de dominio específico orientado a aspectos. El lenguaje permite establecer el orden de llamado a los diferentes componentes (funcionales y no funcionales).

En el grupo de construcción de software de la Universidad de los Andes se ha desarrollado un modelo de componentes distribuidos que viven en una red de nodos llamado Gaita [19], [13], [27]. El modelo resuelve la localización de los servicios e instancias de forma transparente para el desarrollador. Es sobre dicho modelo que hemos realizado una propuesta para incluir requerimientos no funcionales.

El caso de estudio utilizado en nuestra propuesta es una aplicación de comercio electrónico que incluye: proveedores, despachadores, intermediarios y sistemas electrónicos de pagos en línea; estos se representaron en componentes funcionales y se incluyó el manejo de ciclo de vida, persistencia y seguridad; definidos en componentes no funcionales (CNF).

Para el desarrollo de esta propuesta en primer lugar analizamos la caracterización del problema y su respectivo caso de estudio, en segundo lugar realizamos una breve introducción al modelo de componentes Gaita, para posteriormente presentar nuestra estrategia con la solución al problema planteado y los detalles de implementación. En la sección siguiente describimos algunos trabajos relacionados y finalmente, conclusiones y trabajos futuros.

2 DESCRIPCIÓN DEL PROBLEMA

Para ilustrar los diferentes problemas y la estrategia de solución, presentamos un caso de estudio para una aplicación de comercio electrónico (E-Commerce) como se muestra en la figura 1, incluye: proveedores de productos, despachadores de paquetes, un intermediario y sistemas electrónicos de pagos en línea.

En los proveedores de productos debe ser posible recibir órdenes y manejar el inventario de los productos. Los despachadores de productos permiten enviar órdenes de clientes a diferentes destinos.

Page 3: Composición de Requerimientos No Funcionales

Composición de Requerimientos No Funcionales 3

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE VOL. 2 / NUM.2

El intermediario es una aplicación típica de mediación en línea que sirve para encontrar productos asociados a catálogos de proveedores por categorías y realizar envíos de paquetes a un destino a través de los despachadores.

Figura 1: Aplicación de comercio electrónico

Adicionalmente, la aplicación debe tener un sistema de almacenamiento de los datos; ofrecer un nivel de seguridad aceptable, que permita autenticar a los usuarios frente al sistema para acceder a los servicios; garantizar la integridad y consistencia de datos cuando se realice una operación. Los ítems anteriores representan los Requerimientos No Funcionales de la aplicación.

En la actualidad, el manejo de los RNFs es una tarea que se ha dejado a los modelos de componentes. Ellos resuelven la lógica no funcional usando diferentes técnicas.

Los modelos orientados al contenedor como EJB [24], CORBA Componente Model (CCM) [24] y Microsoft .NET [16], separan los requerimientos funcionales de los requerimientos no funcionales dejando el manejo de los últimos a al contenedor. Este, simplifica el desarrollo de aplicaciones permitiendo a los desarrolladores usar los RNFs de forma declarativa. El modelo de componentes Fractal [5] propone el manejo de los RNFs agregando una membrana o capa de control a cada componente. Se puede ver dicha membrana como si cada componente tuviese su propio contenedor.

Las soluciones mencionadas son algunas de las más comunes, sin embargo, no llenan completamente las expectativas en cuanto a lo esperado por el CBSD. En los modelos orientados al contenedor, los aspectos no funcionales que éste ofrece, pueden no aplicar en escenarios que impliquen necesidades específicas. Algunos de estos modelos permiten agregar nuevas características no funcionales mediante técnicas de interceptores, pero no se pueden extender las existentes. Los componentes son dependientes de contexto al depender de un contenedor específico. Por otra parte, en Fractal sólo se define una metodología para el desarrollo uniforme de los elementos, y el desarrollador debe realizar la implementación de las interfaces que forman la membrana de control. Se han propuesto diferentes soluciones en Fractal similares a las planteadas en éste trabajo, en las que se usan técnicas de AOP para separar preocupaciones transversales asociadas a RNFs de la lógica funcional, por ejemplo FAC [17]. Este trabajo presenta una propuesta, también basada en los principios de AOP, que se acerca más a los objetivos del CBSD.

La validación de la propuesta se realiza sobre el modelo de componentes Gaita. Este, ofrece localización transparente de servicios y otras características CBSD, pero no cuenta con soporte a requerimientos no funcionales.

Page 4: Composición de Requerimientos No Funcionales

4 Gerson Samaniego, José Pulido

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE

3 MODELO DE COMPONENTES GAITA

En ésta sección, se describe brevemente el modelo de componentes sobre el que se prueba nuestra solución. Gaita es un modelo de componentes distribuidos no jerárquicos que viven en una red de nodos. Gaita resuelve la localización de los servicios y sus instancias de forma transparente mediante la comunicación entre los nodos de la red y la consistencia de los elementos definida en el modelo [12].

Componentes

Representan funcionalidades que pueden estar expresadas en términos de contratos ofrecidos (facetas), contratos requeridos (receptáculos) y un conjunto de fábricas que permiten instanciar el componente. La figura 2 muestra un ejemplo de componente:

Figura 2: Componente en Gaita-S

Conectores

Los componentes en Gaita se comunican por medio de conectores. Un receptáculo de un componente espera poder ser resuelto por la faceta de otro. El Conector es el elemento encargado de unir el receptáculo y el componente. El conector puede encerrar la lógica de localización de los componentes requeridos, ocultando dicho trabajo al componente. De ésta forma, el componente tiene sólo la lógica que le corresponde.

Lenguaje de Definición de Componentes

Actualmente Gaita cuenta con un lenguaje de definición de Componentes (CDL) que permite definir tanto componentes simples, cuya implementación es una clase Java, como componentes compuestos, en donde la implementación es la composición de componentes predefinidos.

Figura 3: Ejemplo de componente compuesto (Calculadora)

En la figura 3, se muestra un ejemplo de componente compuesto llamado Calculadora, cuya implementación es resuelta por los componentes internos Sumador y Multiplicador.

Page 5: Composición de Requerimientos No Funcionales

Composición de Requerimientos No Funcionales 5

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE VOL. 2 / NUM.2

Aplicaciones Basadas en Componentes

Son aplicaciones cuya implementación es una red de componentes ensamblados: componentes unidos por sus interfaces (facetas y receptáculos). El Desarrollador de Aplicaciones Basadas en Componentes se encarga de ensamblar la aplicación utilizando componentes ya creados, resolviendo sus dependencias y creando nuevos componentes compuestos si es necesario. La aplicación resultante no debe tener receptáculos sin resolver.

E-Commerce con componentes Gaita

La primera tarea del diseñador de componentes consiste en distribuir la funcionalidad del mismo en uno o varios componentes. Nosotros identificamos ciertos componentes funcionales en la aplicación E-commerce, como se muestra en el diagrama de componentes de la figura 4.

Figura 4: Diagrama de componentes.

La figura muestra los componentes y sus relaciones en la aplicación de comercio electrónico donde un cliente realiza sus operaciones a través del componente intermediario. En el diagrama de diseño mostrado, sólo están los componentes funcionales. Para que la aplicación pueda ser ejecutada en un entorno real, hacen falta adicionar RNFs tal y como se mencionó en el problema.

4 ESTRATEGIA DE SOLUCIÓN

Nuestra propuesta para incluir RNF, busca principalmente cumplir con algunas de las premisas del CBSD relacionadas con los componentes: independencia del contexto, comunicación por medio de las interfaces, separación de responsabilidades y reutilización. En cuanto a la separación de responsabilidades, se intenta separar las preocupaciones transversales asociadas a RNFs mediante técnicas de AOP.

La separación de la lógica funcional de la no funcional tiene varias ventajas [2]: código menos enredado, fácil de depurar y mantener, reutilización de la lógica no funcional, el desarrollador sólo se centra en la lógica funcional, etc.

Page 6: Composición de Requerimientos No Funcionales

6 Gerson Samaniego, José Pulido

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE

Composición de Componentes

La propuesta se basa en composición de componentes no funcionales con componentes funcionales1 y en la expresión de la interacción entre ellos de manera externa (usando sus interfaces). Se trata de agregar lógica no funcional a un componente, componiendo éste con otros predefinidos que ya implementan lógica no funcional. Por ejemplo, si se quiere agregar manejo de seguridad al componente intermediario de E-Commerce - CF (Componente Funcional), se asocia éste con un componente de seguridad - CNF (Componente No Funcional) como se muestra en la figura 5.

Figura 5: Composición con Componentes No funcionales

El resultado es un nuevo componente con las facetas funcionales iniciales. En algunos casos pueden aparecer nuevas facetas producto de la adición de la lógica no funcional.

Componentes No Funcionales

Cuando un desarrollador de RNFs identifica la necesidad No funcional, lo primero que debe hacer es encapsularla en un componente con interfaces bien definidas (el CNF). Por ejemplo, un CNF de seguridad puede ofrecer servicios como autenticación y autorización, un CNF de persistencia servicios como guardar, actualizar y consultar. Los servicios ofrecidos por los CNFs deben ser genéricos, es decir, no dependen de los CF finales, para así permitir la reutilización.

Componentes Funcionales

Un punto clave de la propuesta es que tanto el CF como el CNF se desarrollan sin conocerse. Una vez creado el CF, solo se puede aplicar lógica no funcional usando sus interfaces, evitando la intrusión sobre su implementación. Con ésta limitación, es posible que no todos los RNF puedan ser aplicados, pero es una forma de garantizar desacoplamiento y reutilización.

Interacción Entre Componentes

Partiendo de la composición de ejemplo en la figura 5, surgen ciertas preguntas: ¿Cómo se relacionan el CF y el CNF? ¿Qué pasa cuando se invoca un servicio sobre el nuevo componente CF’? ¿En qué punto interviene la lógica no funcional? ¿Cuál es el orden de llamados? La interacción entre los componentes encierra la solución a los interrogantes

1 Katalina Marcos [14], presenta en su tesis la composición de requerimientos no funcionales mediante patrones de composición

Page 7: Composición de Requerimientos No Funcionales

Composición de Requerimientos No Funcionales 7

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE VOL. 2 / NUM.2

anteriores. Para resolver dicha interacción es necesario un nuevo componente mediador capaz de interceptar los llamados al CF para aplicar la lógica no funcional del CNF.

Figura 6: Mediador de la interacción

El mediador mostrado en la figura 6 es un componente generado mediante técnicas de AOP con la ayuda de un lenguaje de dominio específico llamado ISL (Interaction Specification Lenguage) 2 que hace parte de nuestra propuesta de solución. La interface del mediador (ICF’) es la misma exportada por el nuevo componente, y por lo tanto, debe contener los métodos de ICF. La implementación de los métodos del mediador debe resolver el orden de llamados entre los diferentes componentes.

Lenguaje de Interacción: ISL

El ISL es un Lenguaje Orientado a Aspectos (DSAL – Domain Specific Aspect Language). Los lenguajes orientados a aspectos buscan resolver el problema de los RNFs modificando la secuencia normal de ejecución de un programa para agregar la lógica no funcional [2]. La secuencia de ejecución se modifica con base en condiciones específicas del entorno de ejecución: si una condición se cumple, se ejecutan las acciones necesarias [7].

En AOP se usan diferentes formas de cuantificación (formas de especificar las condiciones [21]), la principal de ellas está asociada a la invocación de métodos: poder ejecutar acciones cuando un método de una clase es invocado. De ésta forma se puede interceptar la secuencia del programa y ejecutar instrucciones antes o después del método, o reemplazar por completo su ejecución. Éste es el concepto en el que se basa nuestra solución. En nuestro caso, podemos interceptar los llamados a los servicios de los componentes y también los eventos de su creación y destrucción. Un ejemplo en el lenguaje AspectJ [26]: before() : call(public * Prueba.set* (..)){

System.out.println("Setter invocado"); }

En el ejemplo anterior, cada vez que se invoque un método de la clase “Prueba” cuya firma cumpla con las siguientes condiciones: el nombre empieza por “set”, puede tener cualquier parámetro, esté definido como público y devuelva cualquier tipo, se ejecutará primero la instrucción: System.out.println("Setter invocado");

La expresión que permite cuantificar recibe el nombre de Pointcut y las acciones que se ejecutan cuando se cumple la condición se conocen como Advice. Estos términos se profundizan más adelante.

2 La idea original de expresar la interacción mediante un lenguaje la mostraron Anis Charfi, Michel Riveill y Mireille Blay-Fornarino en Transparent and Dynamic Aspect Composition. [1]

Page 8: Composición de Requerimientos No Funcionales

8 Gerson Samaniego, José Pulido

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE

No existe ninguna diferencia de estructura entre el ISL y los lenguajes tradicionales de AOP, por lo tanto, la sintaxis de éste es una adaptación de AspectJ [26]. La semántica varia: en AspectJ la unidad base del lenguaje (Aspect) representa el aspecto transversal en la aplicación mientras que en el ISL la unidad base es la interacción y los aspectos están encapsulados en los CNFs.

En nuestra solución, el rol encargado de describir la interacción mediante el ISL es el desarrollador de RNFs, por lo tanto, él provee tanto el CNF como la expresión de la interacción con cualquier CF.

En el ejemplo de AspectJ mostrado anteriormente, se puede definir el Aspecto conociendo los métodos de la clase “Prueba”. En nuestra solución, por tratarse de algo más general, el desarrollador de RNFs no conoce el CF objetivo lo que implica que no conoce sus servicios. Para ello, se propone expresar la interacción con base en propiedades asociadas a los servicios del CF.

Las propiedades son meta-data adicional asignada al CF y especificada por el desarrollador de RNFs. Por ejemplo, un CNF de seguridad puede necesitar de información que indique los roles de usuario que pueden acceder a un servicio. Las propiedades describen dicha información mediante sus atributos. Para el ejemplo mencionado, puede existir la propiedad RolesAllowed y uno de sus atributos sería roles, el cual tiene la lista de los roles permitidos. Las propiedades pueden estar asociadas tanto al componente como a sus servicios.

La figura 7 resume la interacción con un ejemplo de Seguridad:

Figura 7: Interacción y propiedades

En el caso de estudio, el servicio crearOrden del componente Intermediario, puede tener asociada la propiedad RolesAllowed y el atributo roles puede ser igual a: admin, client, etc. De igual forma, la propiedad asociada al componente puede ser Stateful, que indicaría que el componente tiene un ciclo de vida con estado. Un componente puede ser persistente, en el caso de los productos de los proveedores, y para ello el componente Producto podría tener asociada la propiedad Persistent o Entity. Tipos de interacción Cuando un desarrollador de RNFs crea un CNF, expresa la interacción de éste con un sólo CF. Dicha interacción (uno a uno) es conocida como Interacción Básica. Con la interacción básica y las propiedades, un cliente de la solución provista, puede aplicar lógica no funcional a un CF. Si quiere aplicar más de un RNF a su CF lo puede hacer,

Page 9: Composición de Requerimientos No Funcionales

Composición de Requerimientos No Funcionales 9

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE VOL. 2 / NUM.2

aplicando uno después de otro, por ejemplo: aplica Logger y obtiene su CF’ con funcionalidad de logging; aplica seguridad a su CF’ y obtiene su CF’’ con funcionalidad de logging y seguridad, y así sucesivamente.

Es posible que la interacción básica e incluso la secuencia de ellas, no sea suficiente en escenarios más complejos. Por ejemplo, en E-Commerce pueden interferir más de un RNF a la vez, en el momento de ejecutar una orden de pedido: el Intermediario tiene ciclo de vida con estado, seguridad y logger, el Proveedor tiene estado persistente y seguridad, el componente de Pagos tiene seguridad y logger, y todos deben tener en cuenta el manejo transaccional distribuido. Para resolver casos más complejos de interacciones nuestro modelo se puede extender creando interacciones complejas que permitan expresar la relación del CF con más de un CNF a la vez.

No hace parte del presente trabajo indicar la forma correcta de la aplicación de los RNFs ni el control de las posibles interferencias al aplicar más de uno a la vez. Un desarrollador de aplicaciones basadas en componentes debe ser conciente de las complejidades que surgen mientras ensambla su aplicación con lógica no funcional. Programación Orientada a Aspectos en el ISL

Antes de mostrar un ejemplo de interacción en el ISL definiremos algunos conceptos adoptados de AOP:

Join-Points: Son puntos bien definidos que se pueden interceptar en el flujo del programa. Inicialmente, nuestro lenguaje sólo soporta los Join-Points que son alcanzados cuando:

- Se crean nuevas instancias del un componente - Se liberan instancias de un componente - Se invocan servicios (métodos) del componente

Pointcuts: Permiten seleccionar o filtrar JoinPoints. Los pointcuts están orientados a las propiedades asignadas a los servicios de los componentes. Trabajos parecidos en AOP donde se intercepta con base en propiedades o meta-data, los podemos encontrar en Aspectivity [22] y AspectJ 5. El siguiente es un ejemplo de pointcut: pointcut logging() : call(@LogMessage);

En el ejemplo, se define el pointcut logging que selecciona los joinpoints alcanzados cuando se invoca la ejecución de cualquier método al que se haya asignado la propiedad LogMessage.

Pointcuts soportados por el ISL: - call(@Propiedad): pointcut asociado a la invocación de un servicio en el que

esté presente la propiedad dada. - if(condicion): permite evaluar los valores de las propiedades - creation(@Propiedad): asociado a la creación de instancias del componente - destruction(@Propiedad): asociado a la destrucción de instancias del

componente - @Property(propiedad): pointcut primitivo que permite asignar la propiedad

del contexto a la variable propiedad definida como parámetro del pointcut.

Page 10: Composición de Requerimientos No Funcionales

10 Gerson Samaniego, José Pulido

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE

Advices: Junto con los pointcuts, definen el punto exacto a interferir (Antes, después o reemplazo) más las instrucciones a ejecutar cuando el Join-Point sea alcanzado. El código (Java) del cuerpo del advice resuelve la interacción entre los componentes. Ejemplo de interacción del CNF de seguridad:

package uniandes.gaita.rnf.Security; import uniandes.gaita.rnf.security.property.RolesAllowed; import uniandes.gaita.rnf.security.cnf.ISecurity; import uniandes.gaita.rnf.security.interaction.ISecurityAux; public interaction Security implements ISecurityAux{ @InternalReceptacle("SecurityService") private ISecurity security; @Receptacle

private ISecurityAux security;

pointcut secure(RolesAllowed ra): call(@RolesAllowed) && @property(ra);

around(RolesAllowed ra) : secure(ra) { if (security.validate(ra.roles()){ proceed();

}else{ System.out.println("Permiso Denegado");

} } public boolean login(String user, String pwd){ security.login(user, pwd); }

}

En el ejemplo, se validan los permisos de un usuario para ejecutar los servicios de un CF que tengan la propiedad @RolesAllowed. Los CNFs son referenciados mediante su Interface (ISecurity) y dicha referencia se agrega como atributo de la interacción. La anotación @InternalReceptacle permite definir la implementación del CNF Security y la posterior inyección de la dependencia. La anotación @Receptacle permite definir nuevos receptáculos del componente resultado. La interacción, al igual que en AspectJ, también puede tener atributos y métodos propios. En el ejemplo se agrega el método login que es parte de la Interface ISecurityAux para ofrecer dicho servicio a los clientes del componente compuesto.

La palabra clave del lenguaje es interaction y describe el inicio de un conjunto de pointcuts y advices que permiten expresar la forma en que interactúan los CF y los CNFs. Es el equivalente al Aspecto (aspect) en AspectJ. Algunos elementos del ejemplo se entenderán mejor después de la siguiente sección.

Mediadores

El mediador, al igual que en otros modelos de componentes (EJB por ejemplo), es un componente que se antepone a los llamados del cliente sobre el CF para ejecutar la lógica adicional necesaria. El cliente final recibe una instancia del mediador y no del CF como tal (aunque él no lo sabe). El componente es generado cuando se interpreta la interacción.

El código Java de los advices forma parte de los métodos del mediador. Cuando un método del CF necesita de lógica no funcional (porque una propiedad asociada a él así lo describe) dicha lógica queda en el método equivalente en el mediador.

Page 11: Composición de Requerimientos No Funcionales

Composición de Requerimientos No Funcionales 11

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE VOL. 2 / NUM.2

El mediador puede implementar otras interfaces si la interacción así lo describe. Los métodos de las interfaces implementadas formarán parte de los servicios que ofrecerá el componente compuesto. Ver el método login de la Interface ISecurityAux del ejemplo mostrado en la sección anterior.

Existen dos tipos de mediadores: los que intervienen los eventos del ciclo de vida del componente y los que intervienen los llamados a los servicios del componente.

Un mediador a nivel de Ciclo de Vida permite resolver la instancia adecuada que se va a entregar a un cliente ayudándose de un CNF de Ciclo de Vida. Este tipo de mediador es conocido como Home.

Un mediador a nivel de servicio permite interceptar cualquier invocación a un método o servicio del componente. Esto implica que dicho mediador debe implementar la misma Interface del componente objetivo, o por lo menos, una que herede de ella. La decisión de si un método se intercepta o no, y las acciones a tomar a en caso de interceptarlo dependen de la interpretación del ISL. Este tipo de mediador es conocido como Interceptor.

Figura 8: Mediadores en Pagos Seguro

En la figura 8 se muestran los mediadores generados para el ejemplo de seguridad mostrado en la sección anterior y aplicado al componente Pagos de E-Commerce. Aparecen dos nuevas interfaces no funcionales: IPagosHome e ISecurityAux. La primera tiene los métodos que permiten controlar el ciclo de vida del nuevo componente y la segunda, que aparece como faceta y como receptáculo, es generada a partir de la interacción para permitir funcionalidades como: login de usuarios, paso de contextos de seguridad, etc.

Resumen de la solución

Para la ejecución de la propuesta se define un marco de trabajo basado en los diferentes roles que intervienen. Básicamente, se busca abstraer de la complejidad del manejo de los RNF a los desarrolladores finales, quienes pueden crear su CF sin pensar en la lógica No Funcional.

Page 12: Composición de Requerimientos No Funcionales

12 Gerson Samaniego, José Pulido

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE

Figura 9: Roles en la solución

En la figura 9, un desarrollador final de componentes crea su componente funcional sin pensar en el manejo de RNFs. Por otra parte, un desarrollador de RNFs crea los CNFs y los deja en un repositorio junto con la especificación de las propiedades y la interacción básica. Un tercer desarrollador (desarrollador de aplicaciones basadas en componentes) se encarga de integrar las soluciones de los dos primeros, aplicando interacciones básicas a componentes funcionales o creando sus propias interacciones (interacciones complejas) según las necesidades de la aplicación.

Solución en E-Commerce

Con base en la solución provista, se implementaron algunos RNF para el caso de estudio del presente artículo. Intermediario, Proveedor y Despachador son componentes funcionales orientados a servicios, y sobre ellos se aplicaron seguridad, logger y manejo de estados. Destino, Producto y Cuenta son componentes funcionales que representan entidades del negocio, y sobre ellos se aplicó persistencia. El requerimiento no funcional de transacciones no se tuvo en cuenta en ésta primera aproximación.

5 IMPLEMENTACIÓN

Las propiedades se establecen en archivos XML y se especifican mediante esquemas XSD. Por facilidad y compatibilidad, las propiedades también pueden ser especificadas con anotaciones de Java 5 [23]. Las propiedades podrían ser definidas en el lenguaje de definición de componentes (CDL).

Los mediadores son generados a partir de la interpretación de la interacción mediante plantillas de Velocity. El trabajo lo realiza un motor de interacción de forma estática, en

Page 13: Composición de Requerimientos No Funcionales

Composición de Requerimientos No Funcionales 13

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE VOL. 2 / NUM.2

el sentido de que las propiedades no pueden cambiar en tiempo de ejecución, lo que implica que tampoco los enlaces de los componentes cambien. Cuando el motor de interacción interpreta el ISL se obtiene la red de componentes. Luego, usando el CDL, se expresa la composición del nuevo componente con lógica no funcional y se pasa dicha definición al motor de composición.

6 TRABAJOS RELACIONADOS

En esta sección presentamos los principales modelos de componentes: EJB [24], CORBA CCM [18], Microsoft .NET [16] y Fractal[5]. Mostramos una breve introducción a la programación orientada a aspectos AOP[2] y comparamos estos trabajos con nuestra solución.

Los modelos de componentes comerciales como EJB[24], .NET[16], CCM[18], COM+[11] usan el concepto de contenedores de software para soportar el manejo de algunos los requerimientos no funcionales (seguridad, transacciones, persistencia y ciclo de vida).

Para que el contenedor pueda manejar los componentes, estos deben cumplir con características especiales de cada implementación perdiendo interoperabilidad de los mismos con otros modelos de componentes. Generalmente los modelos orientados a contenedor “no hacen explícito el modelo del mundo no funcional que implementan” [13] (sólo permiten interactuar con ellos de forma declarativa).

Otros modelos de componentes como fractal (modelo de componentes jerárquico) [5] definen una membrana que interactúa con las propiedades internas y el conjunto de subcomponentes que posee. El manejo de los requerimientos no funcionales está representado en la membrana que provee la capa controladora del componente. Tiene la facilidad de incluir nuevas interfaces de control para requerimientos adicionales. Pero la implementación de la membrana de control está asociada a cada componente y no puede ser definida independientemente para su reutilización en otros componentes.

En nuestra solución, los servicios no funcionales son expresados como componentes independientes del contenedor y pueden ser compuestos con CFs y CNFs.

Por otro lado, la programación orientada por aspectos (AOP)[2] busca la separación de propiedades funcionales y no funcionales que forman una aplicación. AOP disminuye la dependencia entre los componentes funcionales y no funcionales, promueve el reuso[20], facilita el desarrollo y la evolución del componente. AOP provee mecanismos de composición transparentes y flexibles (principalmente a nivel de programación). En este sentido, utilizamos el concepto de la AOP para aplicarlo a los componentes tipo caja negra, con el fin de definir en el lenguaje ISL la interacción entre los componentes funcionales y no funcionales.

Por su estrategia y madurez la AOP ha sido utilizada en aplicaciones JEE como se muestra en el artículo AspectJ2EE [25] aplicado a componentes EJB. También los encontramos en el modelo de componentes Fractal (implementaciones AOKell y FractNet [15] ) y FAC[17]. Otro ejemplo interesante presentado en [9][10] del lenguaje de dominio específico KALA para separar las preocupaciones relacionadas con los sistemas de manejo de transacciones avanzadas ATMS.

Page 14: Composición de Requerimientos No Funcionales

14 Gerson Samaniego, José Pulido

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE

En nuestro trabajo tomamos como base el lenguaje de aspectos AspectJ, para definir el lenguaje de dominio específico ISL que expresa la interacción entre componentes funcionales y no funcionales.

7 CONCLUSIONES

En este artículo, hemos propuesto la integración de algunos requerimientos no funcionales estableciendo propiedades a los componentes no funcionales (CNFs) de forma no intrusiva; mediante metadata y la utilización del lenguaje ISL para expresar la interacción entre ellos. Este enfoque, nos permite tener repositorios de componentes no funcionales reutilizables, configurables e independientes de los componentes funcionales.

Con base en la investigación, concluimos que al realizar la especificación de propiedades de los componentes independientemente a su desarrollo promovemos la reutilización, se puede agregar o quitar un CNF del modelo y se identifica claramente cada los roles en el desarrollo de los componentes.

Adicionalmente, el desarrollador de componentes funcionales por lo general, no se debe preocupar por los requerimientos no funcionales que se apliquen posteriormente a sus componentes. Hay flexibilidad de definir los servicios a los cuales se les aplica un determinado RNF mediante la especificación de propiedades y el modelo de interacción.

Por la complejidad y características especiales de los RNFs no es posible generalizar una solución que los incluya a todos. En nuestra propuesta tratamos únicamente los requerimientos no funcionales que puedan ser expresados como componentes de forma independiente al servicio funcional y que sus relaciones con el componente funcional objetivo sean claramente identificadas. Aunque la idea es que el desarrollador de los componentes funcionales no piense a la lógica no funcional, en algunos casos es necesario que sus implementaciones cumplan ciertas condiciones. Por ejemplo, para poder persistir un componente, éste debe tener métodos para recuperar y establecer los datos.

Así mismo, no todos los requerimientos no funcionales los podemos expresar de forma independiente (ejemplo persistencia y transacciones) y en otros casos se identifican conflictos o dificultades para ser modelados como componentes.

8 TRABAJO FUTURO

Con base en el trabajo expuesto en el artículo, se hace necesario identificar las interferencias que se puedan presentar en las interacciones entre los componentes que conforman una aplicación. De igual forma, es útil para el modelo incluir patrones de composición que puedan ser reutilizados con diferentes componentes.

En nuestra propuesta la configuración de propiedades asociadas a los requerimientos funcionales se hace de forma estática. Otra alternativa sería incluir las propiedades en tiempo de ejecución creando mediadores que realicen el cargue de las mismas. Adicionalmente, las propiedades podrían estar definidas en el lenguaje de definición de componentes (CDL).

Page 15: Composición de Requerimientos No Funcionales

Composición de Requerimientos No Funcionales 15

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE VOL. 2 / NUM.2

En el modelo Gaita-NF se incluyeron los requerimientos no funcionales básicos para el manejo de ciclo de vida, seguridad y persistencia. Sería importante seguir con el trabajo para incluir nuevos requerimientos no funcionales al modelo.

REFERENCIAS

[1] A. Charfi, M. Riveill, M. Blay-Fornarino, and A. Pinna-Dery, "Transparent and Dynamic Aspect Composition," Presentado en SPLAT Worshop, Bonn, Germany, March 2006.

[2] A. M. R. Quintero, “Visión General de la Programación Orientada a Aspectos,” Departamento de Lenguajes y Sistemas Informáticos, Facultad de Informática y Estadística, Universidad de Sevilla, Reporte técnico. Diciembre 2000.

[3] C. Szyperski, D. Gruntz, and S. Murer. Component Software - Beyond Object- Oriented Programming, Addison-Wesley / ACM Press, 2002. pp. 3-15.

[4] ComponentSource. What are components?. (2008, febrero). Disponible: http://www.componentsource.com/Services/WhatAreComponents.asp?bhcp=1.

[5] E. Bruneton, T. Coupaye, J. B. Stefani. (2004). Specification The Fractal Component Model. [AEn línea]. Disponible: http://fractal.objectweb.org.

[6] F. Bachmann, L. Bass, C. Buhman, D. Comella, and F. Long. (2000). Volume. II: Technical Concepts of Component-Based Software Engineering. Software Engineering Institute, Carnegie Mellon University, Pittsburgh, PA. [AEn línea]. pp. 15-20. Disponible: http://www.sei.cmu.edu/staff/kcw/00tr008.pdf

[7] F. Duclos, J. Estublier, and P. Morat. "Describing and using non functional aspects in component based applications," Presentado en International Conference on Aspect-Oriented Software Development, Enschede The Netherlands, April 2002.

[8] J. A. Montilva C., N. Arapé, and J. A. Colmenares, "Desarrollo de Software Basado en Componentes," Actas del IV Congreso de Automatización y Control (CAC’2003), Mérida, Venezuela, Noviembre, 2003.

[9] J. Fabry and N. Pessemier, "KALA: A Domain-Specific Solution to Tangled Aspect Code," Domain-Specific Aspect Languages 06 Workshop at GPCE06, Portland, Oregon, October 2006.

[10] J. Fabry and T. D’Hondt, “A Family of Domain-Specific Aspect Languages on Top of KALA,” Open and Dynamic Aspect Languages Workshop At AOSD 2006, Bonn, Germany, March 20, 2006.

[11] J. Lowy, and J. Lö WY. "COM and .NET Component Services: Migrating from COM+ to .NET," Sebastopol, CA, USA: O’Reilly & Associates, Inc., 2001.

[12] J. Villalobos, R. Casallas, K. Marcos, P. Barvo, and C. Rocha, "Gaita-s: Model specification," Universidad de los Andes, Bogotá. Documento técnico, 2005.

[13] K. Marcos B. Gaita-nf: Un Modelo de Composición de Componentes Funcionales con Servicios No Funcionales. Bogotá, 2005. Tesis (Magíster en ingeniería de

Page 16: Composición de Requerimientos No Funcionales

16 Gerson Samaniego, José Pulido

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE

sistemas). Universidad de los Andes. Facultad de Ingeniería. Departamento de Ingeniería de Sistemas.

[14] L. Fuentes, J. M. Troya y A. Vallecillo, Desarrollo de Software Basado en Componentes. Depto. Lenguajes y Ciencias de la Computación. Universidad de Málaga. Disponible: http://www.lcc.uma.es/~av/Docencia/Doctorado/tema1.pdf

[15] L. Seinturier, N. Pessemier, C. Escoffier, D. Donsez, "Towards a Reference Model for Implementing the Fractal Specifications for Java and the .NET Platform," Presentado en Fractal Workshop ECOOP, Nantes (France), 2006.

[16] Microsoft.(2008, feb.). .NET Framework. http://msdn.microsoft.com/netframework/

[17] N. Pessemier, L. Seinturier, L. Duchien, T. Coupaye. A Component-Based and Aspect-Oriented Model for Software Evolution. International Journal of Computer Applications in Technology 31, 1-2 (2008) 94-105.

[18] OMG. (2006, May.). CORBA Component Model Specification, v4.0. [AEn línea]. Disponible: http://www.omg.org/docs/formal/06-04-01.pdf

[19] P. J. Barvo. Izaza. Diseño e implementación del motor del modelo de servicios Gaita-S V0. Bogotá, 2005. Tesis (Pegrado). Universidad de los Andes. Facultad de Ingeniería. Departamento de Ingeniería de Sistemas.

[20] P. J. Clemente, J. Herández and F. Sánchez. “Extending Component Composition Using Model Driven and Aspect-Oriented Techniques,” Journal of software, vol. 3, No. 1, January. 2008.

[21] R.E. Filman and D.P. Friedman, "Aspect-Oriented Programming is Quantification and Obliviousness," Presentado en Workshop on Advanced Separation of Concerns, OOPSLA 2000, Minneapolis, Octuber 2000.

[22] Ramnivas Laddad. (2008, feb.). AspectJ language support for metadata. Disponible en http://ramnivas.com/blog/index.php?p=10.

[23] Sun Microsystems, Inc.(2004, Sep.). JSR 175: A Metadata Facility for the JavaTM Programming Language. [AEn línea]. Disponible: http://jcp.org/en/jsr/detail?id=175

[24] Sun Microsystems, Inc. (2008, March). The Enterprise JavaBeans™ (EJB). Disponible: http://java.sun.com/products/ejb/

[25] T. Cohen and J. Gil, “AspectJ2EE = AOP J2EE: Towards An Aspect Based, Programmable and Extensible Middleware Framework,” Presentado en ECOOP Object-Oriented Programming, Ed., vol. 3086, pp. 219– 243, Springer, 2004.

[26] The AspectJTM 5 Development Kit Developer's Notebook. (2008, feb.). Disponible: http://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html

[27] Universidad de los Andes. (2008, Feb.). Grupo de Investigación en Construcción de software – Gaita. Web site, http://chie.uniandes.edu.co/~gaita/doku.php

[28] WebCab Components. (2008, March). About Component Based Development. Disponible: http://webcabcomponents.com/componentization.shtml.