Package de.danet.an.workflow.clients.wfxml

Source Code of de.danet.an.workflow.clients.wfxml.WfXmlAuditHandler

/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2006 Danet GmbH (www.danet.de), BU BTS.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* $Id: WfXmlAuditHandler.java 2292 2007-03-01 12:33:11Z schnelle $
*
* $Log$
* Revision 1.9  2007/02/17 21:19:48  mlipp
* Workflow service caching redone.
*
* Revision 1.8  2007/02/06 08:35:34  schnelle
* Started automatic generation of wsdl description.
*
* Revision 1.7  2007/01/31 22:55:36  mlipp
* Some more refactoring and fixes of problems introduced by refactoring.
*
* Revision 1.6  2007/01/31 14:53:06  schnelle
* Small corrections wvaluating the resource reference.
*
* Revision 1.5  2007/01/31 12:24:07  drmlipp
* Design revisited.
*
* Revision 1.4  2007/01/30 21:04:17  mlipp
* Fixed package/process id retrieval.
*
* Revision 1.3  2007/01/30 13:11:37  schnelle
* Corrected check to decide the sending of a completed message.
*
* Revision 1.2  2007/01/30 11:56:14  drmlipp
* Merged Wf-XML branch.
*
* Revision 1.1.2.10  2007/01/29 15:04:20  schnelle
* Renaming of Observer to ObserverRegistry and URIDecoder to ResourceReference.
*
* Revision 1.1.2.9  2007/01/29 13:40:32  schnelle
* Storing of the sender base in the servlet context.
*
* Revision 1.1.2.8  2007/01/26 15:50:29  schnelle
* Added encoding for process id and package id.
*
* Revision 1.1.2.7  2007/01/24 14:22:39  schnelle
* Observer handler starts on servlet startup.
*
* Revision 1.1.2.6  2007/01/24 10:56:50  schnelle
* Prepared return of a result for aobservers.
*
* Revision 1.1.2.5  2007/01/16 11:05:42  schnelle
* Refactoring: Moved subscription handling methods to own class.
*
* Revision 1.1.2.4  2007/01/11 11:37:10  schnelle
* Added subscription if an oberver key is given in the creation of a process.
*
* Revision 1.1.2.3  2007/01/11 10:41:53  schnelle
* Sending notification messages to all observers.
*
* Revision 1.1.2.2  2007/01/11 10:23:52  schnelle
* Creation of StateChanged notifications.
*
* Revision 1.1.2.1  2007/01/10 13:41:28  schnelle
* Implemented subscribe.
*
*/
package de.danet.an.workflow.clients.wfxml;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.TextOutputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.TransformerException;

import org.xml.sax.SAXException;

import de.danet.an.workflow.api.EventSubscriber;
import de.danet.an.workflow.api.FactoryConfigurationError;
import de.danet.an.workflow.api.ProcessClosedAuditEvent;
import de.danet.an.workflow.api.SAXEventBuffer;
import de.danet.an.workflow.api.WorkflowService;
import de.danet.an.workflow.api.WorkflowServiceFactory;
import de.danet.an.workflow.clients.wfxml.ObserverRegistry.ObserverInfo;
import de.danet.an.workflow.omgcore.InvalidPerformerException;
import de.danet.an.workflow.omgcore.ProcessData;
import de.danet.an.workflow.omgcore.ResultNotAvailableException;
import de.danet.an.workflow.omgcore.WfAuditEvent;
import de.danet.an.workflow.omgcore.WfAuditHandler;
import de.danet.an.workflow.omgcore.WfStateAuditEvent;

/**
* This class is an event handler foe all audit events of the workflow engine.
* All events are collected and distributed to the subscribed observers.
*
* @author Dirk Schnelle
*
* TODO: Check if this is better implemented as an mbean.
* TODO: Move the functionality of message creation to the response generators.
*/
class WfXmlAuditHandler implements WfAuditHandler {
    /** Logger instance. */
    private static final org.apache.commons.logging.Log logger
        = org.apache.commons.logging.LogFactory.getLog(WfAuditHandler.class);   

    /** Formatter to produce xsd time stamps. */
    protected static DateFormat xsdDateTimeFormat
        = new SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ss");
   
    /** The workflow service. */
    private WorkflowService workflowService = null;
   
    /** the observer registry. */
    private ObserverRegistry observerRegistry;

    /**
     * Constructs a new object.
     *
     * @param wfs the workflow service
     * @param obs the observer registry.
     */
    public WfXmlAuditHandler (WorkflowService wfs, ObserverRegistry obs) {
        workflowService = wfs;
        this.observerRegistry = obs;       
    }
   
    /* (non-Javadoc)
     * @see de.danet.an.workflow.omgcore.WfAuditHandler#receiveEvent(de.danet.an.workflow.omgcore.WfAuditEvent)
     */
    public void receiveEvent(WfAuditEvent event)
        throws InvalidPerformerException,
            RemoteException {
        String type = event.eventType();
        if (!type.equals(WfAuditEvent.PROCESS_STATE_CHANGED)) {
            return;
        }
       
        WfStateAuditEvent stateEvent = (WfStateAuditEvent) event;
       
        String mgrName = stateEvent.processMgrName();
        String[] ids = mgrName.split("/");
        String packageId = ids[0];
        String processId = ids[1];
        String processKey = stateEvent.processKey();

        Collection observers;
        try {
            observers = observerRegistry.getObservers(packageId, processId, processKey);
        } catch (SQLException sqle) {
            logger.warn("error retrieving observer list", sqle);
            return;
        }

        for (Iterator iterator=observers.iterator(); iterator.hasNext();) {
            ObserverInfo observerInfo = (ObserverInfo)iterator.next();
            ResourceReference resRef = new ResourceReference
                (observerInfo.getSenderBase(),
                 packageId, processId, event.processKey());
            InstanceResponseGenerator irg = new InstanceResponseGenerator
                (observerRegistry, workflowService, resRef);
            try {
                sendStateChanged
                    (observerInfo.getObserverKey(), irg, stateEvent);
                if (stateEvent instanceof ProcessClosedAuditEvent) {
                    ProcessData result
                            = ((ProcessClosedAuditEvent)stateEvent).result();
                    sendCompleted (observerInfo.getObserverKey(), irg, result);
                }
            } catch (IllegalStateException e) {
                logger.warn ("Problem sending event to "
                        + observerInfo.getObserverKey() + ": "
                        + e.getMessage(), e);
                try {
                    observerRegistry.unsubscribe(observerInfo.getObserverKey());
                } catch (SQLException ee) {
                    logger.warn("error removing observer", ee);
                    return;
                }
            }
        }
       
        // Do some cleanup if the process is no more available.
        if (stateEvent.newState().startsWith("closed")) {
            try {
                observerRegistry.unsubscribe(packageId, processId, processKey);
            } catch (SQLException e) {
                logger.warn("error unsubscribing observer", e);
                return;
            }
        }
    }

    /**
     * Sends a {@link Consts.STATE_CHANGE_REQUEST} message to all observers.
     * @param observers observers.
     * @param newState new state.
     * @param oldState old state.
     */
    private void sendStateChanged
        (String observer, InstanceResponseGenerator irg,
         WfStateAuditEvent event) {
        String newState = StateMapper.omg2asapState(event.newState());
        String oldState = StateMapper.omg2asapState(event.oldState());
        try {
            SOAPMessage message
                = irg.createStateChangedMessage (observer, newState, oldState);
            call(message, observer);
        } catch (MalformedURLException e) {
            throw (IllegalStateException)
                (new IllegalStateException (e.getMessage()).initCause(e));
        } catch (SOAPException e) {
            throw (IllegalStateException)
                (new IllegalStateException (e.getMessage()).initCause(e));
        }
    }

    /**
     * Sends a {@link Consts.STATE_CHANGE_REQUEST} message to all observers.
     * @param obs observer persistence.
     * @param observers observers.
     * @param result result of the process.
     * @throws SAXException
     * @throws TransformerException
     * @throws ResultNotAvailableException
     * @throws RemoteException
     */
    private void sendCompleted(String observer, InstanceResponseGenerator irg,
            ProcessData result) throws RemoteException {
        try {
            SOAPMessage message = irg.createCompletedMessage(observer, result);
            call(message, observer);
        } catch (MalformedURLException e) {
            throw (IllegalStateException)
                (new IllegalStateException (e.getMessage()).initCause(e));
        } catch (SOAPException e) {
            throw (IllegalStateException)
                (new IllegalStateException (e.getMessage()).initCause(e));
        }
    }

    /**
     * Calls the default endpoint with the given message.
     * @param request the SOAP request.
     * @return SOAP response.
     * @throws SOAPException
     * @throws MalformedURLException
     */
    private void call(SOAPMessage message, String observer)
        throws SOAPException, MalformedURLException {
        SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
        SOAPConnection connection = factory.createConnection();
       
        URL endpoint = new URL(observer);
        connection.call(message, endpoint);
    }

}
TOP

Related Classes of de.danet.an.workflow.clients.wfxml.WfXmlAuditHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.