how to implement a distributed commonj work manager es

26
Cómo Implementar un WorkManager Distribuido de CommonJ En este artículo te mostraré como implementar una versión distribuida de la especificación CommonJ WorkManager usando Terracotta para Spring . Este artículo es una variación de un artículo escrito por TheServerSide.com titulado Distributed Computing Made Easy, un artículo que puede ser encontrado Aquí . ¿Qué es WorkManager CommonJ? CommonJ es una especificación conjunta de BEA y IBM que proporciona un estándar para ejecutar tareas concurrentes en un entorno JEE. Por ejemplo tiene soporte para el patrón Master/Worker en su API WorkManager. De la documentación de BEA sobre la especificación: “El Work Manager proporciona una API simple para ejecución concurrente de elementos de trabajo soportada por el servidor de la aplicación. This enables J2EE-based applications (including Servlets and EJBs) to schedule work items for concurrent execution, which will provide greater throughput and increased response time. After an application submits work items to a Work Manager for concurrent execution, the application can gather the results. The Work Manager provides common “join” operations, such as waiting for any or all work items to complete. The Work Manager for Application Servers specification provides an application-server-supported alternative to using lower-level threading APIs, which are inappropriate for use in managed environments such as Servlets and EJBs, as well as being too difficult to use for most applications." What we are going to do is to first implement a the specification as a regular single node multi-threaded application, based on the Master/Worker pattern. We are also going to use the Spring Framework and implement the Master, Worker and Shared Queue entities as three different Spring beans; MyWorkManager, Worker and WorkQueue.

Upload: abmel-salim-lopessier

Post on 27-Apr-2015

122 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: How to Implement a Distributed CommonJ Work Manager ES

Cómo Implementar un WorkManager Distribuido de CommonJ

En este artículo te mostraré como implementar una versión distribuida de la especificación CommonJ WorkManager usando Terracotta para Spring. Este artículo es una variación de un artículo escrito por TheServerSide.com titulado Distributed Computing Made Easy, un artículo que puede ser encontrado Aquí.

¿Qué es WorkManager CommonJ?

CommonJ es una especificación conjunta de BEA y IBM que proporciona un estándar para ejecutar tareas concurrentes en un entorno JEE. Por ejemplo tiene soporte para el patrón Master/Worker en su API WorkManager.

De la documentación de BEA sobre la especificación:

“El Work Manager proporciona una API simple para ejecución concurrente de elementos de trabajo soportada por el servidor de la aplicación. This enables J2EE-based applications (including Servlets and EJBs) to schedule work items for concurrent execution, which will provide greater throughput and increased response time. After an application submits work items to a Work Manager for concurrent execution, the application can gather the results. The Work Manager provides common “join” operations, such as waiting for any or all work items to complete. The Work Manager for Application Servers specification provides an application-server-supported alternative to using lower-level threading APIs, which are inappropriate for use in managed environments such as Servlets and EJBs, as well as being too difficult to use for most applications."

What we are going to do is to first implement a the specification as a regular single node multi-threaded application, based on the Master/Worker pattern. We are also going to use the Spring Framework and implement the Master, Worker and Shared Queue entities as three different Spring beans; MyWorkManager, Worker and WorkQueue.

We will then use Terracotta for Spring* to transparently and declaratively, turn this implementation into a multi-node, distributed WorkManager.

Master (WorkManager)

MyWorkManager bean implements the CommonJ WorkManager interface which has the API that the user uses to schedule Work and wait for all Work to be completed. The MyWorkManager bean does not have any state, and can therefore be configured as a Prototype in the Spring bean config XML file.

Here is how we could implement the work manager bean:

public class MyWorkManager implements WorkManager {    

  

  // The Work Queue bean, is injected by Spring   

  private final WorkQueue m_queue;   

  

  public MyWorkManager(WorkQueue queue) {   

Page 2: How to Implement a Distributed CommonJ Work Manager ES

    m_queue = queue;   

  }   

  

  public WorkItem schedule(final Work work) throws WorkException {   

    WorkItem workItem = new MyWorkItem(work, null);   

    m_queue.addWork(workItem);   

    return workItem;   

  }   

  

  public WorkItem schedule(Work work, WorkListener listener)  hrows WorkException {

    WorkItem workItem = new MyWorkItem(work, listener);   

    m_queue.addWork(workItem); // adds work to the shared queue   

    return workItem;   

  }   

  

  public boolean waitForAll(Collection workItems, long timeout) {   

    long start = System.currentTimeMillis();   

    do {   

      boolean isAllCompleted = true;   

      for (Iterator it = workItems.iterator();    

        it.hasNext() && isAllCompleted;) {   

        int status = ((WorkItem) it.next()).getStatus();   

        isAllCompleted = status == WorkEvent.WORK_COMPLETED ||    

             status == WorkEvent.WORK_REJECTED;   

      }   

      if (isAllCompleted) { return true; }   

      if (timeout == IMMEDIATE) { return false; }   

      if (timeout == INDEFINITE) { continue; }   

    } while ((System.currentTimeMillis() - start) < timeout);   

    return false;   

  }   

  

  public Collection waitForAny(Collection workItems, long timeout) {   

    long start = System.currentTimeMillis();   

    do {   

      synchronized (this) {   

        Collection completed = new ArrayList();   

        for (Iterator it = workItems.iterator(); it.hasNext();) {   

          WorkItem workItem = (WorkItem) it.next();   

          if (workItem.getStatus() == WorkEvent.WORK_COMPLETED ||    

              workItem.getStatus() == WorkEvent.WORK_REJECTED) {   

            completed.add(workItem);   

          }   

        }   

        if (!completed.isEmpty()) { return completed; }   

      }   

      if (timeout == IMMEDIATE) { return Collections.EMPTY_LIST; }   

      if (timeout == INDEFINITE) { continue; }   

    } while ((System.currentTimeMillis() - start) < timeout);   

    return Collections.EMPTY_LIST;   

Page 3: How to Implement a Distributed CommonJ Work Manager ES

  }   

}  

Shared Queue

The MyWorkManager bean schedules work by adding work to the WorkQueue bean, which is a simple wrapper around a java.util.concurrent.BlockingQueue queue. The WorkQueue bean is the bean that has state, since it holds the queue with all the pending Work. We need to have a single instance of this queue that can be available to all workers, and we therefore define it as Singleton in the bean config XML file.

The work queue can be implemented like this:

<BR>   public class WorkQueue {<BR>      private final BlockingQueue m_workQueue;<P></P>    public WorkQueue() {    m_workQueue = new LinkedBlockingQueue();    }   

public WorkQueue(int capacity) {    m_workQueue = new LinkedBlockingQueue(capacity);    }   

public MyWorkItem getWork() throws WorkException {    try {    return (MyWorkItem) m_workQueue.take(); // blocks if empty    } catch (InterruptedException e) {    throw new WorkException(e);    }    }   

public void addWork(WorkItem workItem) throws WorkException {    try {    m_workQueue.put(workItem);    } catch (InterruptedException e) {    WorkRejectedException we = new WorkRejectedException(e.getMessage()); ((MyWorkItem)workItem).setStatus(WorkEvent.WORK_REJECTED, we);    throw we;    }    }   <P>}<BR>   

</P>  

Worker

Finally, we have the Worker bean. This bean uses a thread pool to spawn up N number of worker threads that continuously grabs and executes Work from the WorkQueue. During the processing of the Work, its status flag is maintained (can be one of either Accepted, Started, Completed or Rejected), this is needed in order for the MyWorkManager bean to be able to continuously monitor the status of the Work it has scheduled. The Worker bean does not have any shared state and is configured as a Prototype in the bean config XML file.

Page 4: How to Implement a Distributed CommonJ Work Manager ES

This is what a worker bean implementation can look like. As you can see we choose to make use of the Executor thread pool implementation in the java.util.concurrent package:

public class Worker {        private transient final WorkQueue  m_queue;      private transient final ExecutorService m_threadPool =          Executors.newCachedThreadPool();      private volatile boolean m_isRunning  = true;        public Worker(WorkQueue queue) {        m_queue = queue;      }        public void start() throws WorkException {        while (m_isRunning) {            final MyWorkItem workItem = m_queue.getWork();          m_threadPool.execute(new Runnable() {            public void run() {              try {                Work work = workItem.getResult();                workItem.setStatus(WorkEvent.WORK_STARTED, null);                work.run();                workItem.setStatus(WorkEvent.WORK_COMPLETED, null);              } catch (Throwable e) {                workItem.setStatus(WorkEvent.WORK_REJECTED,        new WorkRejectedException(e.getMessage()));             }           });         }       }     }   

}  

Assembly

These three beans can now be wired up by the Spring bean config file:

&lt;beans&gt;     &lt;!-- workManager is prototype - not shared --&gt;     &lt;bean id="workManager"          class="com.jonasboner.commonj.workmanager.MyWorkManager"                singleton="false"&gt;       &lt;constructor-arg ref="queue"/&gt;     &lt;/bean&gt;             &lt;!-- worker is prototype - not shared --&gt;     &lt;bean id="worker"            class="com.jonasboner.commonj.workmanager.Worker"            singleton="false"&gt;       &lt;constructor-arg ref="queue"/&gt;     &lt;/bean&gt;       &lt;!-- the work queue is singleton - can be made shared by Terracotta --&gt;   &lt;bean id="queue"            class="com.jonasboner.commonj.workmanager.WorkQueue"/&gt;     &lt;/beans&gt;  

We now have a fully functional local, multi-threaded, implementation of the CommonJ WorkManager specification.

Page 5: How to Implement a Distributed CommonJ Work Manager ES

Making the WorkManager distributed

Now comes the hard part right? Well…no.

It turns out that in order to turn this implementation into a distributed WorkManager, all we have to do is to create a Terracotta configuration file in which we declare the Spring beans that we want to share across the cluster:

...   &lt;spring&gt;     &lt;jee-application name="webAppName"&gt;       &lt;application-contexts&gt;         &lt;application-context&gt;           &lt;paths&gt;             &lt;path&gt;*/work-manager.xml&lt;/path&gt;           &lt;/paths&gt;           &lt;beans&gt;             &lt;bean name="queue"/&gt;           &lt;/beans&gt;         &lt;/application-context&gt;       &lt;/application-contexts&gt;     &lt;/jee-application&gt;   &lt;/spring&gt;   ...  

Done!

Now we have a fully distributed, multi-JVM CommonJ WorkManager.

Client usage

Using the distributed work manager is now simply a matter of getting the bean from the application context and invoke schedule(..):

ApplicationContext ctx =        new ClassPathXmlApplicationContext("*/work-manager.xml");     // get the work manager from the application context   WorkManager workManager = (WorkManager) ctx.getBean("workManager");     Set pendingWork = new HashSet();   for (int i = 0; i < nrOfWork; i++) {       // schedule work     WorkItem workItem = workManager.schedule(new Work() {         public void run() {           ... // do work         }     });                        // collect the pending work     pendingWork.add(workItem);   }     // wait for all work to be completed   

workManager.waitForAll(pendingWork, WorkManager.INDEFINITE);  

Page 6: How to Implement a Distributed CommonJ Work Manager ES

To start up a Worker you simply have to get the Worker bean from the application context and invoke start():

<BR>   ApplicationContext ctx = <BR>       new ClassPathXmlApplicationContext(“*/work-manager.xml”);<P></P>   <P>// get the worker from the application context<BR>   Worker worker = (Worker) ctx.getBean(“worker”);</P>   <P>// starting worker<BR>   worker.start();<BR>   </P>  

The usage of the distributed version would roughly be to start up one WorkManager bean and N number of Worker beans, each one on a different JVM.

That is all there is to it. Now we have a simple, distributed, reliable, high-performant and scalable CommonJ WorkManager ready for use.

Enjoy.

RC 1 of Terracotta for Spring was released some days ago (9/12/2006) and is free for production use for up to two nodes.

Reactions

Java Champion Subscribe: Atom Feed Email: [email protected] Work: scalablesolutions.se Product: akka.io Hacking: github.com/jboner Tweeting: twitter.com/jboner

Upcoming Talks

2.09.11: Reaktor conference - Helsinki, Finland 29.09.11: GOTO - Amsterdam, Netherlands 17.11.11: Devoxx - Antwerp, Belgium 1.12.11: YOW! - Melbourne, Australia 5.12.11: YOW! - Brisbane, Australia

Gestores de trabajo

Un gestor de trabajo es una agrupación de hebras creada para las aplicaciones J2EE que utilizan beans asíncronos.

Page 7: How to Implement a Distributed CommonJ Work Manager ES

Con la consola administrativa, el administrador puede configurar el número que desee de gestores de trabajos. El administrador especifica las propiedades del gestor de trabajos, incluida la política de herencia de contexto J2EE de los beans asíncronos que utilizan el gestor de trabajo. El administrador enlaza cada uno de los gestores de trabajos con una ubicación exclusiva en JNDI (Java Naming and Directory Interface). Puede utilizar los objetos de gestor de trabajo en cualquiera de las interfaces siguientes:

Beans asíncronos Gestor de trabajo CommonJ (si desea más información, consulte el apartado de gestor de trabajo

CommonJ en este artículo).El tipo de interfaz seleccionado se resuelve durante la búsqueda JNDI. El tipo de interfaz es el valor que especifica en ResourceRef, en lugar del tipo de interfaz especificado en el objeto de configuración. Por ejemplo, puede tener una ResourceRef para cada interfaz por objeto de configuración, y cada búsqueda de ResourceRef devuelve ese tipo apropiado de instancia.

Los gestores de trabajo proporcionan un modelo de programación para las aplicaciones J2EE 1.4. Si desea más información, consulte el apartado sobre el modelo de programación en este artículo.

Cuando graba un componente Web o EJB que utiliza beans asíncronos, el desarrollador debería incluir una referencia de recursos en cada componente que necesite acceso a un gestor de trabajos. Si desea más información sobre las referencias de recursos, consulte el artículo Referencias. El componente consulta un gestor de trabajos utilizando un nombre lógico en el componente, espacio de nombres java:comp, del mismo modo que consulta un origen de datos, un enterprise bean o una fábrica de conexiones.

El desplegador enlaza los gestores de trabajos físicos con los gestores de trabajos lógicos cuando se despliega la aplicación.

Por ejemplo, si un desarrollador necesita tres agrupaciones de hebras para particionar el trabajo en los niveles bronce, plata y oro, el desarrollador graba el componente para que elija una agrupación lógica a partir de un atributo del perfil de la aplicación cliente. El desplegador tiene flexibilidad para decidir cómo desea correlacionar esta petición para tres agrupaciones de hebras. El desplegador puede decidir utilizar una sola agrupación de hebras en una máquina pequeña. En este caso, el desplegador enlaza las tres referencias de recursos con la misma instancia de gestor de trabajos (esto es, el mismo nombre JNDI). Una máquina más potente permite tres agrupaciones de hebras, por lo que el desplegador enlaza cada referencia de recursos con un gestor de trabajo diferente. Los gestores de trabajo se pueden compartir entre varias aplicaciones J2EE instaladas en el mismo servidor.

Un desarrollador de aplicaciones puede utilizar tantos gestores de trabajo lógicos como sea necesario. El desplegador elige si desea correlacionar uno o varios gestores de trabajo físicos con el gestor de trabajo lógico definido en la aplicación.

Todos los componentes J2EE que necesiten compartir objetos de ámbito asíncrono deben utilizar el mismo gestor de trabajo. Estos objetos de ámbito tienen afinidad con un único gestor de trabajo. Una aplicación que utilice ámbitos asíncronos debe verificar que todos los componentes que utilicen objetos de ámbito utilizan el mismo gestor de trabajo.

Cuando se definen varios gestores de trabajo, las agrupaciones de hebras subyacentes se crean en una JVM (Java Virtual Machine) sólo si una aplicación dentro de esa JVM busca el gestor de trabajo. Por ejemplo, puede que haya definidas diez agrupaciones de hebras (gestores de trabajo), pero en realidad no se crea ninguna hasta que la aplicación las busca.

Nota: los beans asíncronos no dan soporte al envío de trabajo a las JVM remotas.

Gestor de trabajo CommonJ

El gestor de trabajo CommonJ es parecido al gestor de trabajo. La diferencia entre los dos estriba en que el gestor de trabajo CommonJ contiene un subconjunto de los métodos de gestor de trabajo de los beans asíncronos. Aunque el gestor de trabajo CommonJ funciona en un entorno J2EE 1.4, la interfaz no devuelve una instancia nueva para cada búsqueda de denominación JNDI, puesto que esta especificación no está incluida en la especificación J2EE.

Page 8: How to Implement a Distributed CommonJ Work Manager ES

Inicio remoto de trabajo. La función opcional de especificación de trabajo CommonJ para trabajar de forma remota no recibe soporte. Aunque una unidad de trabajo implemente la interfaz java.io.Serializable, la unidad de trabajo no se ejecuta de forma remota.

Cómo buscar un gestor de trabajo Una aplicación puede buscar un gestor de trabajo de la siguiente manera. En este ejemplo, el componente contiene una referencia de recursos llamada wm/myWorkManager, que se ha enlazado con un gestor de trabajo físico cuando se desplegó el componente:InitialContext ic = new InitialContext(); WorkManager wm = (WorkManager)ic.lookup("java:comp/env/wm/myWorkManager");

Contextos J2EE de herencia Los beans asíncronos pueden heredar los siguientes contextos.

Contexto de internacionalización

Cuando se selecciona esta opción y se habilita el servicio de internacionalización, y el contexto de internacionalización que existe en la hebra de planificación está disponible en la hebra de destino.

Área de trabajo

Cuando se selecciona esta opción, el contexto del área de trabajo de cada partición de área de trabajo que existe en la hebra de planificación está disponible en la hebra de destino.

Perfil de aplicación (en desuso)

El contexto del perfil de aplicación no está soportado y no está disponible para las aplicaciones J2EE 1.4. Para aplicaciones J2EE 1.3, cuando se selecciona esta opción, se habilita el servicio de perfil de aplicaciones y se selecciona la propiedad de servicio de perfil de aplicaciones modalidad de compatibilidad de 5.x. La tarea de perfil de aplicaciones asociada con la hebra de planificación está disponible en la hebra de destino para aplicaciones J2EE 1.3. En el caso de aplicaciones J2EE 1.4, la tarea de perfil de aplicaciones es una propiedad de su unidad de trabajo asociada en lugar de una hebra. Esta opción no afecta al comportamiento de la tarea en aplicaciones J2EE 1.4. El trabajo planificado que se ejecuta en una aplicación J2EE 1.4 no recibe la tarea de perfilado de aplicaciones de la hebra de planificación.

Seguridad

El bean asíncrono se puede ejecutar de forma asíncrona o como el cliente autenticado en la hebra que lo ha creado. Este comportamiento es de gran utilidad, ya que el bean asíncrono puede hacer sólo lo que haga el emisor. Esta acción es más útil que un mecanismo RUN_AS, por ejemplo, que impide este tipo de comportamiento. Cuando se selecciona la opción Seguridad, el sujeto JAAS que existe en la hebra de planificación está disponible en la hebra de destino. Si no se selecciona, la hebra se ejecuta de forma anónima.

Metadatos del componente

Los metadatos del componente son sólo relevantes cuando el bean asíncrono es un objeto Java simple. Si el bean es un componente J2EE, por ejemplo, un enterprise bean, los metadatos del componente se activan.

Los contextos que se pueden heredar dependen del gestor de trabajo utilizado por la aplicación que crea el bean asíncrono. Con la consola administrativa, el administrador define la política de contexto adhesivo de un gestor de trabajo seleccionando los servidos en los que estará disponible el gestor de trabajo.

Modelo de programación Los gestores de trabajo dan soporte a los modelos de programación siguientes. Especificación CommonJ. El modelo de programación CommonJ de Application Server versión 6.0

utiliza el gestor de trabajo y el gestor de temporizadores para gestionar hebras y temporizadores de forma asíncrona en el entorno J2EE 1.4.

Extensiones de especificación CommonJ y beans asíncronos. Las interfaces actuales de beans asíncronos EventSource, ámbitos asíncronos, monitores de subsistemas y J2EEContext son parte de la extensión CommonJ.

Page 9: How to Implement a Distributed CommonJ Work Manager ES

La tabla siguiente describe el método de correlación entre las API de CommonJ y beans asíncronos. Puede cambiar las interfaces actuales de beans asíncronos para utilizar la interfaz CommonJ, al tiempo que conserva las mismas funciones.

Paquete de CommonJ

API Paquete de beans asíncronos

API

Gestor de trabajo   Gestor de trabajo  

Beans asíncronos Campo - IMMEDIATE (largo)

  Campo - IMMEDIATE (int)

  Campo - INDEFINITE   Campo - INDEFINITE

  schedule(Work) throws WorkException, IllegalArgumentException

  startWork(Work) throws WorkException, IllegalArgumentException

  schedule(Work, WorkListener) throws WorkException, IllegalArgumentException

Nota: Configure la propiedad de tiempo de espera del gestor de trabajo en el valor que ha especificado previamente en timeout_ms en

startWork. El valor por omisión del tiempo de espera es INDEFINITE.

  startWork(Work, timeout_ms, WorkListener) throws WorkException, IllegalArgumentException

  waitForAll(workItems, timeout_ms)

  join(workItems, JOIN_AND, timeout_ms)

  waitForAny(workItems, timeout_ms)

  join(workItems, JOIN_OR, timeout_ms)

WorkItem   WorkItem  

  getResult   getResult

  getStatus   getStatus

WorkListener   WorkListener  

Page 10: How to Implement a Distributed CommonJ Work Manager ES

  workAccepted(WorkEvent)

  workAccepted(WorkEvent)

  workCompleted(WorkEvent)

  workCompleted(WorkEvent)

  workRejected(WorkEvent)

  workRejected(WorkEvent)

  workStarted(WorkEvent)

  workStarted(WorkEvent)

WorkEvent   WorkEvent  

  Campo - WORK_ACCEPTED

  Campo - WORK_ACCEPTED

  Campo - WORK_COMPLETED

  Campo - WORK_COMPLETED

  Campo - WORK_REJECTED

  Campo - WORK_REJECTED

  Campo - WORK_STARTED

  Campo - WORK_STARTED

  getException   getException

  getType   getType

  getWorkItem().getResult()

Nota: Esta API sólo es válida una vez completado el trabajo.

  getWork

Work (extends Runnable) Work (Extends Runnable)

  isDaemon   *

  release   release

RemoteWorkItem No en este release. Utilice el gestor de trabajo distribuido en Extended Deployment o release futuro

NA  

TimerManager   AlarmManager  

Page 11: How to Implement a Distributed CommonJ Work Manager ES

  resume   *

  schedule(Listener, Date)

  create(Listener, context, time) ** es necesario convertir los parámetros

  schedule(Listener, Date, period)

   

  schedule(Listener, delay, period)

   

  scheduleAtFixedRate(Listener, Date, period)

   

  scheduleAtFixedRate(Listener, delay, period)

   

  stop    

  suspend    

Timer   Alarm  

  cancel   cancel

  getPeriod    

  getTimerListener   getAlarmListener

  scheduledExecutionTime

   

TimerListener   AlarmListener  

  timerExpired(timer)   fired(alarm)

StopTimerListener   No se aplica  

  timerStop(timer)    

CancelTimerListener

  No se aplica  

  timerCancel(timer)    

WorkException (Extends Exception) WorkException (Extends WsException)

Page 12: How to Implement a Distributed CommonJ Work Manager ES

WorkCompletedException

(Extends WorkException)

WorkCompletedException

(Extends WorkException)

WorkRejectedException

(Extends WorkException)

WorkRejectedException

(Extends WorkException)

Si desea más información sobre las API del gestor de trabajo, consulte el Javadoc.

Ejemplo

Tabla 1. Buscar gestor de trabajo

Beans asíncronos CommonJ

InitialContext ctx = new InitialContext();com.ibm.websphere.asynchbeans.WorkManager wm =(com.ibm.websphere.asynchbeans.WorkManager)

ctx.lookup(“java:comp/env/wm/MyWorkMgr”);

InitialContext ctx = new InitialContext();commonj.work.WorkManager wm = (commonj.work.WorkManager)

ctx.lookup(“java:comp/env/wm/MyWorkMgr”);

Tabla 2. Crear el trabajo mediante MyWork

Beans asíncronos CommonJ

public class MyWork implements com.ibm.websphere.asynchbeans.Work {public void release() {

...... } public void run() {

System.out.println(“Running.....”); }

public class MyWork implements commonj.work.Work{

public boolean isDaemon() {

return false; } public void release () { ..... } public void run () {

System.out.println(“Running.....”); }

Tabla 3. Enviar el trabajo

Beans asíncronos CommonJ

MyWork work1 = new MyWork(new URI =“http://www.example./com/1”);

MyWork work2 = new MyWork(new URI =“http://www.example./com/2”);

WorkItem item1;WorkItem item2;Item1=wm.startWork(work1);Item2=wm.startWork(work2);

MyWork work1 = new MyWork(new URI = “http://www.example./com/1”);

MyWork work2 = new MyWork(new URI =“http://www.example./com/2”);

WorkItem item1;WorkItem item2;Item1=wm.schedule(work1 );Item2=wm.schedule(work2);

Page 13: How to Implement a Distributed CommonJ Work Manager ES

// caso 1: bloquear hasta que se hayan completado todos los elementos

ArrayList col1 = new ArrayList();

Col1.add(item1);Col1.add(item2);wm.join(col1,

WorkManager.JOIN_AND, (long)WorkManager.IMMEDIATE);

// una vez completados los trabajos

System.out.println(“work1 data=”+work1.getData());

System.out.println(“work2 data=”+work2.getData());

// caso 2: esperar a que se completen todos los elementos

Boolean ret = wm.join(col1, WorkManager.JOIN_OR, 1000);

// caso 1: bloquear hasta que se hayan completado todos los elementos

Collection col1 = new ArrayList();

col1.add(item1);col1.add(item2);wm.waitForAll(col1,

WorkManager.IMMEDIATE);// una vez completados los

trabajosSystem.out.println(“work1

data=”+work1.getData());System.out.println(“work2

data=”+work2.getData());

// caso 2: esperar a que se completen todos los elementos

Collection finished = wm.waitForAny(col1, 1000);

// comprobar el estado de workItems

if (finished != null) { Iterator I =

finished.iterator(); if (i.hasNext()) { WorkItem wi =

(WorkItem) i.next(); if (wi.equals(item1))

{

System.out.println(“work1 = work1.getData());

} else if (wi.equals(item2)) {

System.out.println(“work1 =

work1.getData()); } }}

Tabla 4. Crear un gestor de temporizadores

Beans asíncronos CommonJ

InitialContext ctx = new InitialContext();

com.ibm.websphere.asynchbeans.WorkManager wm =

(com.ibm.websphere.asynchbeans.WorkManager)

ctx.lookup(“java:comp/env/wm/MyWorkMgr”);

InitialContext ctx = new InitialContext();

Commonj.timers.TimerManager tm = (commonj.timers.TimerManager) ctx.lookup(“java:comp/env/tm/MyTimerManager”);

Page 14: How to Implement a Distributed CommonJ Work Manager ES

AsynchScope ascope;Try { Ascope =

wm.createAsynchScope(“ABScope”);} Catch

(DuplicateKeyException ex){ Ascope =

wm.findAsynchScope(“ABScope”); ex.printStackTrace();}

// obtener un AlarmManager AlarmManager aMgr=

ascope.getAlarmManager();

Tabla 5. Activar el temporizador

Beans asíncronos CommonJ

// crear una alarmaABAlarmListener

listener = new ABAlarmListener();

Alarm am = aMgr.create(listener, “SomeContext”, 1000*60);

// crear un temporizadorTimerListener listener =

new StockQuoteTimerListener(“qqq”, “[email protected]”);

Timer timer = tm.schedule(listener, 1000*60);

// Retardo fijo: programar temporizador para que caduque

// a los 60 segundos a partir de entonces y repetir cada hora

// en lo sucesivo. Timer timer =

tm.schedule(listener, 1000*60, 1000*30);

// Retardo fijo: programar temporizador para que caduque

// a los 60 segundos a partir de entonces y repetir cada hora

// en lo sucesivoTimer timer =

tm.scheduleAtFixedRate(listener, 1000*60, 1000*30);

Usuarios y privilegios en Oracle

1. Crear Usuarios y asignar privilegios en Oracle

El siguiente es un resumen de algunas consideraciones al momento de crear un usuario o cuenta en Oracle, y los privilegios y roles que le podemos asignar.

El nombre de usuario no debe superar 30 caracteres, no debe tener caracteres especiales y debe iniciar con una letra.

Page 15: How to Implement a Distributed CommonJ Work Manager ES

Un método de autentificación. El mas común es una clave o password, pero Oracle 10g soporta otros métodos (como biometric, certificado y autentificación por medio de token).

Un Tablespace default, el cual es donde el usuario va a poder crear sus objetos por defecto, sin embargo, esto no significa que pueda crear objetos, o que tenga una cuota de espacio. Estos permisos se asignan de forma separada, salvo si utiliza el privilegio RESOURCE el que asigna una quota unlimited, incluso en el Tablespace SYSTEM!  Sin embargo si esto ocurre, ud. puede posteriormente mover los objetos creados en  el SYSTEM a otro Tablespace.

Un Tablespace temporal, donde el usuario crea sus objetos temporales y hace los sort u ordenamientos.

Un perfil o profile de usuario, que son las restricciones que puede tener su cuenta (opcional).

Por ejemplo, conectado como el usuario SYS, creamos un usuario y su clave asi:

SQL> CREATE USER ahernandez IDENTIFIED BY ahz         DEFAULT TABLESPACE users;

Si no se indica un Tablespace, por defecto el usuario toma el que está definido en la BD (generalmente el SYSTEM). Para modificar el Tablespace default de un usuario se hace de la siguiente manera:

SQL> ALTER USER jperez DEFAULT TABLESPACE datos;

También podemos asignar a los usuarios un Tablespace temporal donde se almacenan operaciones de ordenamiento. Estas incluyen las cláusulas ORDER BY, GROUP BY, SELECT DISTINCT, MERGE JOIN, o CREATE INDEX (también es utilizado cuando se crean Tablas temporales).

SQL> CREATE USER jperez IDENTIFIED BY jpzDEFAULT TABLESPACE usersTEMPORARY TABLESPACE temp;

Adicionalmente,  a cada usuario se puede asignar a un profile o perfil, que tiene dos propósitos principalmente:

Limita el uso de recursos,  lo que es recomendable, por ejemplo en ambientes de Desarrollo

Garantiza y refuerza reglas de Seguridad a nivel de cuentas

Ejemplos, cuando se crea el usuario o asignar un perfil existente:

SQL> CREATE USER jperez IDENTIFIED BY jpzDEFAULT TABLESPACE usersTEMPORARY TABLESPACE tempPROFILE resource_profile;

SQL> ALTER USER jperezPROFILE perfil_desa;

Page 16: How to Implement a Distributed CommonJ Work Manager ES

2. Eliminar un Usuario de la Base de Datos

Para eliminar un usuario de la BD se hace uso de la clausula DROP USER y opcionalmente se puede utilizar CASCADE, para decirle que también elimine todos los objetos creados por ese usuario.

SQL> DROP USER jperez CASCADE;

3. Modificar cuentas de Usuarios

Para modificar un usuario creado, por ejemplo cambiar su clave, tenemos la sintáxis:

SQL> ALTER USER NOMBRE_USUARIO IDENTIFIED BY CLAVE_ACCESO[DEFAULT TABLESPACE ESPACIO_TABLA][TEMPORARY TABLESPACE ESPACIO_TABLA][QUOTA {ENTERO {K | M } | UNLIMITED } ON ESPACIO_TABLA[PROFILE PERFIL];

4. Privilegios de Sistema y de Objetos

En Oracle existen dos tipos de privilegios de usuario.

4.1 System: Que permite al usuario hacer ciertas tareas sobre la BD, como por ejemplo crear un Tablespace. Estos permisos son otorgados por el administrador o por alguien que haya recibido el permiso para administrar ese tipo de privilegio. Existen como 100 tipos distintos de privilegios de este tipo.

En general los permisos de sistema, permiten ejecutar comandos del tipo DDL (Data definition Language), como CREATE, ALTER y DROP o del tipo DML (Data Manipulation Language). Oracle 10g tiene mas de 170 privilegios de sistema los cuales pueden ser vistos consultando la vista: SYSTEM_PRIVILEGE_MAP

Entre todos los privilegios de sistema que existen, hay dos que son los importantes: SYSDBA y SYSOPER. Estos son dados a otros usuarios que serán administradores de base de datos.

Para otorgar varios permisos a la vez, se hace de la siguiente manera:

SQL> GRANT CREATE USER, ALTER USER, DROP USER TO ahernandez;

4.2 Object: Este tipo de permiso le permite al usuario realizar ciertas acciones en objetos de la BD, como una Tabla, Vista, un Procedure o Función, etc.  Si a un usuario no se le dan estos permisos sólo puede acceder a sus propios objetos (véase USER_OBJECTS). Este tipo de permisos los da el owner o dueño del objeto, el administrador o alguien que haya recibido este permiso explícitamente (con Grant Option).

Por ejemplo, para otorgar permisos a una tabla Ventas para un usuario particular:

SQL> GRANT SELECT,INSERT,UPDATE, ON analista.venta TO jperez;

Page 17: How to Implement a Distributed CommonJ Work Manager ES

Adicionalmente, podemos restringir los DML a una columna de la tabla mencionada. Si quisieramos que este usuario pueda dar permisos sobre la tabla Factura a otros usuarios, utilizamos la cláusula WITH GRANT OPTION. Ejemplo:

SQL> GRANT SELECT,INSERT,UPDATE,DELETE ON venta TO mgarcia WITH GRANT OPTION;

5. Asignar cuotas a Usuarios

Por defecto ningun usuario tiene cuota en los Tablespaces y se tienen tres opciones para poder proveer a un usuario de una quota:5.1Sin limite, que permite al usuario usar todo el espacio disponible de un Tablespace.5.2 Por medio de un valor, que puede ser en kilobytes o megabytes que el usuario puede usar. Este valor puede ser mayor o nenor que el tamaño del Tablespace asignado a él.5.3 Por medio del privilegio UNLIMITED TABLESPACE, se tiene prioridad sobre cualquier cuota dada en un Tablespace por lo que tienen disponibilidad de todo el espacio incluyendo en SYSTEM y SYSAUX.

No se recomienda dar cuotas a los usuarios en los Tablespaces SYSTEM y SYSAUX, pues tipicamente sólo los usuarios SYS y SYSTEM pueden crear objetos en éstos. Tampoco dar cuotas en los Tablespaces Temporal o del tipo Undo.

6. Roles

Finalmente los Roles, que son simplemente un conjunto de privilegios que se pueden otorgar a un usuario o a otro Rol. De esa forma se simplifica el trabajo del DBA en esta tarea.

Por default cuando creamos un usuario desde el Enterprise Manager se le asigna el permiso de connect, lo que permite al usuario conectarse a la BD y crear sus propios objetos en su propio esquema. De otra manera, debemos asignarlos en forma manual.

Para crear un Rol y asignarlo a un usuario se hace de la siguiente manera:

SQL> CREATE ROLE appl_dba;

Opcionalmente, se puede asignar una clave al Rol:

SQL> SET ROLE appl_dba IDENTIFIED BY app_pwd;

Para asignar este Rol a un usuario:

SQL> GRANT appl_dba TO jperez;

Otro uso común de los roles es asignarles privilegios a nivel de Objetos, por ejemplo en una Tabla de Facturas en donde sólo queremos que se puedan hacer Querys e Inserts:

SQL> CREATE ROLE consulta;

SQL> GRANT SELECT,INSERT on analista.factura TO consulta;

Page 18: How to Implement a Distributed CommonJ Work Manager ES

Y finalmente asignamos ese rol con este “perfil” a distintos usuarios finales:

SQL> GRANT consulta TO ahernandez;

Nota: Existen algunos roles predefinidos, tales como:CONNECT, CREATE SESSION, CREATE TABLE, CREATE VIEW, CREATE SYNONYM, CREATE SEQUENCE, CREATE DATABASE LINK, CREATE CLUSTER,ALTER SESSION, RESOURCE, CREATE PROCEDURE, CREATE SEQUENCE, CREATE TRIGGER, CREATE TYPE, CREATE CLUSTER, CREATE INDEXTYPE, CREATE OPERATOR SCHEDULER, CREATE ANY JOB, CREATE JOB, EXECUTE ANY CLASS, EXECUTE ANY PROGRAM,MANAGE SCHEDULER, etc.DBA: Tiene la mayoría de los privilegios, no es recomendable asignarlo a usuarios que no son administradores.SELECT_CATALOG_ROLE: No tiene privilegios de sistema, pero tiene cerca de 1600 privilegios de objeto.

Para consultar los roles definidos y los privilegios otorgados a través de ellos, utilize las vistas:

SQL> select * from DBA_ROLES;SQL> select * from DBA_ROLE_PRIVS order by GRANTEE;

Cómo crear un nuevo esquema en Oracle paso a pasoSubmitted by cfb on 22 October, 2006 - 21:44

Bases de datos Administración Bases de datos Oracle create DBA esquema owner tablespace usuario

Versión para impresión

Vamos a ver en tres sencillos pasos cómo crear un nuevo esquema-usuario de Oracle. Para poder realizar estos pasos es necesario iniciar la sesión en la base de datos con un usuario con permisos de administración, lo más sencillo es utilizar directamente el usuario SYSTEM:

Page 19: How to Implement a Distributed CommonJ Work Manager ES

Creación de un tablespace para datos y otro para índices. Estos tablespaces son la ubicación donde se almacenarán los objetos del esquema que vamos a crear.

Tablespace para datos, con tamaño inicial de 1024 Mb, y auto extensible

CREATE TABLESPACE "APPDAT" LOGGING DATAFILE '/export/home/oracle/oradata/datafiles/APPDAT.dbf' SIZE 1024M EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO

Tablespace para índices, con tamaño inicial de 512 Mb, y auto extensible

CREATE TABLESPACE "APPIDX" LOGGING DATAFILE '/export/home/oracle/oradata/datafiles/APPIDX.dbf' SIZE 512M EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO

La creación de estos tablespaces no es obligatoria, pero sí recomendable, así cada usuario de la BD tendrá su propio espacio de datos.

Creación del usuario que va a trabajar sobre estos tablespaces, y que será el propietario de los objetos que se se creen en ellos

CREATE USER "APP" PROFILE "DEFAULT" IDENTIFIED BY "APPPWD"DEFAULT TABLESPACE "APPDAT" TEMPORARY TABLESPACE "TEMP" ACCOUNT UNLOCK;

Si no se especifica un tablespace, la BD le asignará el tablespace USERS, que es el tablespace que se utiliza por defecto para los nuevos usuarios. Se puede apreciar también que no hay ninguna referencia al tablespace de índices APPIDX que hemos creado. Si queremos mantener datos e índices separados habrá que acordarse de especificar este tablespace en las sentencias de creación de índices de este usuario, si no se hace éstos se crearán en APPDAT:

CREATE INDEX mi_indice ON mi_tabla(mi_campo) TABLESPACE APPIDX;

Sólo falta asignarle los permisos necesarios para trabajar. Si se le asignan los roles 'Connect' y 'Resource' ya tiene los permisos mínimos, podrá conectarse y poder realizar las operaciones más habituales de consulta, modificación y creación de objetos en su propio esquema.

GRANT "CONNECT" TO "APP";GRANT "RESOURCE" TO "APP";

Completamos la asignación de permisos con privilegios específicos sobre objetos para asegurarnos de que el usuario pueda realizar todas las operaciones que creamos necesarias

GRANT ALTER ANY INDEX TO "APP";GRANT ALTER ANY SEQUENCE TO "APP";GRANT ALTER ANY TABLE TO "APP";GRANT ALTER ANY TRIGGER TO "APP";

Page 20: How to Implement a Distributed CommonJ Work Manager ES

GRANT CREATE ANY INDEX TO "APP";GRANT CREATE ANY SEQUENCE TO "APP";GRANT CREATE ANY SYNONYM TO "APP";GRANT CREATE ANY TABLE TO "APP";GRANT CREATE ANY TRIGGER TO "APP";GRANT CREATE ANY VIEW TO "APP";GRANT CREATE PROCEDURE TO "APP";GRANT CREATE PUBLIC SYNONYM TO "APP";GRANT CREATE TRIGGER TO "APP";GRANT CREATE VIEW TO "APP";GRANT DELETE ANY TABLE TO "APP";GRANT DROP ANY INDEX TO "APP";GRANT DROP ANY SEQUENCE TO "APP";GRANT DROP ANY TABLE TO "APP";GRANT DROP ANY TRIGGER TO "APP";GRANT DROP ANY VIEW TO "APP";GRANT INSERT ANY TABLE TO "APP";GRANT QUERY REWRITE TO "APP";GRANT SELECT ANY TABLE TO "APP";GRANT UNLIMITED TABLESPACE TO "APP";

Ahora el usuario ya puede conectarse y comenzar a trabajar sobre su esquema