Matthieu Riou wrote:
What mike says. I should just add that picking the right process version
depending on what's already executing is handled by the runtime. The only
thing that it will need is to know what is the definition for all the
process versions that are still around (haven't been undeployed). You just
need to keep these artifacts around and feed them to the engine (by calling
register) as long as they're needed.

If you want, I can code the method that compiles the BPEL file if you give
me a signature that gets the file as parameter (I don't know how you would
look it up in the filesystem).

Cheers,
Matthieu



Yours optimistically,

Mike.

Matthieu,

I'd appreciate it if you could pass your eyes over my implementation of a 
ProcessConf, inline below.

There are a few questions that I have:

1) ProcessConfImpl from the ODE code has more public methods than are present in the ProcessConf interface. What are they used for - and by which code?

2) What is getDefinitionforService(...) supposed to return? The problem is over the interpretation of the name "Service" - what kind of service is this? A service from the WSDL? A service as listed in the deploy.xml file? And what definition are we talking about - the definition of the Service in the WSDL file, or the definition of the portType at which the service points?

3) What are Properties as returned by getProperties()?

I'd appreciate any assistance you can give....

Yours,  Mike.


/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.tuscany.sca.implementation.bpel.ode;

import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Collection;
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;

import javax.wsdl.Definition;
import javax.wsdl.PortType;
import javax.xml.namespace.QName;

import org.apache.ode.bpel.evt.BpelEvent.TYPE;
import org.apache.ode.bpel.iapi.Endpoint;
import org.apache.ode.bpel.iapi.ProcessConf;
import org.apache.ode.bpel.iapi.ProcessState;
import org.apache.ode.bpel.compiler.BpelC;
import org.w3c.dom.Node;

import org.apache.tuscany.sca.implementation.bpel.BPELImplementation;
import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition;
import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface;
import org.apache.tuscany.sca.assembly.Reference;
import org.apache.tuscany.sca.assembly.Service;

public class TuscanyProcessConfImpl implements ProcessConf {
        
        private BPELImplementation implementation;
        private Map<String, Endpoint> invokeEndpoints = null;
        private Map<String, Endpoint> provideEndpoints = null;
        private Map<QName, Node> properties = null;
        private ProcessState processState;
        
        private final String TUSCANY_NAMESPACE = "http://tuscany.apache.org";;
        
        /**
         * Constructor for the ProcessConf implementation
         * @param theImplementation the BPEL implementation for which this is 
the ProcessConf
         */
        public TuscanyProcessConfImpl( BPELImplementation theImplementation ) {
                this.implementation = theImplementation;
                
                processState = ProcessState.ACTIVE;
                
                // Compile the process
                compile( getBPELFile() );
        } // end TuscanyProcessConfImpl constructor

        /**
         * Returns the URI for the directory containing the BPEL process
         */
        public URI getBaseURI() {
                File theDir = getDirectory();
                return theDir.toURI();
        }

        /**
         * Returns a String containing the (local) name of the file containing 
the BPEL process
         */
        public String getBpelDocument() {
                URL processURL = 
implementation.getProcessDefinition().getLocation();
                try {
                    return getRelativePath( getDirectory(), new File( 
processURL.toURI() ));
                } catch (Exception e) {
                        System.out.println( "Unable to resolve relative path of BPEL 
process" + processURL );
                        return null;
                } // end try
        } // end getBpelDocument

        /**
         * Returns an InputStream containing the Compiled BPEL Process (CBP)
         */
        public InputStream getCBPInputStream() {
                // Find the CBP file - it has the same name as the BPEL process 
and lives in the same
                // directory as the process file
                String cbpFileName = 
implementation.getProcessDefinition().getName().getLocalPart() + ".cbp";
                File cbpFile = new File( getDirectory(), cbpFileName );
                if( cbpFile.exists() ) {
                        // Create an InputStream from the cbp file...
                        try {
                            return new FileInputStream( cbpFile );
                        } catch ( Exception e ) {
                                System.out.println("Unable to open the cbp file for 
BPEL process: " +
                                                
implementation.getProcessDefinition().getName());
                        } // end try
                } else {
                        // Cannot find the cbp file
                        System.out.println("Cannot find the cbp file for process: 
" +
                                        
implementation.getProcessDefinition().getName());
                } // end if
                // TODO - need better exception handling if we can't open the 
cbp file for any reason
                return null;
        } // end getCBPInputStream
        
        /**
         * Return the WSDL Definition for a given PortType
         * @param portTypeName - the QName of the PortType
         */
        public Definition getDefinitionForPortType( QName portTypeName ) {
                // Find the named PortType in the list of WSDL interfaces 
associated with this BPEL Process
                Collection<WSDLInterface> theInterfaces = 
implementation.getProcessDefinition().getInterfaces();
                for( WSDLInterface wsdlInterface : theInterfaces ) {
                        if ( wsdlInterface.getPortType().getQName().equals( 
portTypeName ) ) {
                                // Extract and return the Definition associated 
with the WSDLDefinition...
                                return 
wsdlInterface.getWsdlDefinition().getDefinition();
                        } // end if
                } // end for
                return null;
        }

        /**
         * Returns a WSDL Definition for a given Service QName
         *
         * 22/05/2008 - it is very unclear what this service QName is really 
meant to be.
         * From the handling of the deploy.xml file by the current ODE code, it 
seems that the key link
         * is from the Service QName to the PartnerLink name (done in the 
deploy.xml file).
         *
         * The curious part about this is that the QName for the service is 
ONLY defined in deploy.xml file
         * and does not appear to relate to anything else, except for the QName 
of the PartnerLink
         *
         * The PartnerLink name is the same as the name of the SCA service (or 
reference) which in turn points
         * at the PartnerLinkType which in turn points at an (WSDL) interface 
definition.
         */
        public Definition getDefinitionForService(QName serviceQName ) {
                System.out.println("getDefinitionforService called for service: 
" + serviceQName );
                // TODO Auto-generated method stub
                return null;
        }

        /**
         * Returns the date of deployment of the process
         * - for SCA returns the current time
         */
        public Date getDeployDate() {
                return new Date();
        }

        /**
         * Returns userid of deployer
         * - always "SCA Tuscany" for Tuscany...
         */
        public String getDeployer() {
                return "SCA Tuscany";
        }

        /**
         * Returns a list of the files in the directory containing the BPEL 
Process
         */
        public List<File> getFiles() {
                File theDir = getDirectory();
                List<File> theFiles = Arrays.asList( (File[]) 
theDir.listFiles() );
                // TODO recurse into subdirectories
                return theFiles;
        }

        /**
         * Returns a Map containing all the "invoke endpoints" - for which read "SCA 
references"
         * The map is keyed by partnerLink name and holds Endpoint objects
         *
         * TODO deal with service callbacks on bidirectional services
         */
        public Map<String, Endpoint> getInvokeEndpoints() {
                if( invokeEndpoints == null ) {
                        Map<String, Endpoint> invokeEndpoints = new 
HashMap<String, Endpoint>();
                        // Get a collection of the references
                        List<Reference> theReferences = 
implementation.getReferences();
                        // Create an endpoint for each reference, using the reference 
name as the "service"
                        // name, combined with http://tuscany.apache.org to 
make a QName
                        for( Reference reference : theReferences ) {
                                invokeEndpoints.put( reference.getName(),
                                                new Endpoint( new QName( 
TUSCANY_NAMESPACE, reference.getName() ), "ReferencePort"));
                        } // end for
                } // end if
                return invokeEndpoints;
        } // end getInvokeEndpoints

        /**
         * Returns the name of the directory containing the BPEL files
         */
        public String getPackage() {
                File theDir = getDirectory();
                return theDir.getName();
        } // end getPackage

        /**
         * Return the BPEL Process ID - which is the same as the Process QName
         */
        public QName getProcessId() {
                return getType();
        } // end getProcessID

        /**
         * TODO - What are properties?
         */
        public Map<QName, Node> getProperties() {
                if ( properties == null ) {
                        properties = new HashMap<QName, Node>();
                } // end if
                return properties;
        } // end getProperties

        /**
         * Returns a Map containing all the "provide endpoints" - for which read 
"SCA services"
         * The map is keyed by partnerLink name and holds Endpoint objects
         *
         * TODO deal with reference callbacks on bidirectional references
         */
        public Map<String, Endpoint> getProvideEndpoints() {
                if( provideEndpoints == null ) {
                        provideEndpoints = new HashMap<String, Endpoint>();
                        // Get a collection of the references
                        List<Service> theServices = 
implementation.getServices();
                        // Create an endpoint for each reference, using the reference 
name as the "service"
                        // name, combined with http://tuscany.apache.org to 
make a QName
                        for( Service service : theServices ) {
                                provideEndpoints.put( service.getName(),
                                                new Endpoint( new QName( 
TUSCANY_NAMESPACE, service.getName() ), "ServicePort"));
                        } // end for
                } // end if
                return provideEndpoints;
        } // end getProvideEndpoints

        /**
         * Return the process state
         */
        public ProcessState getState() {
                return processState;
        }

        /**
         * Returns the QName of the BPEL process
         */
        public QName getType() {
                return implementation.getProcess();
        }

        /**
         * Gets the process Version number
         * - current code does not have versions for BPEL prcesses
         */
        public long getVersion() {
                return 0;
        }

        /**
         * Returns true if the supplied event type is enabled for any of the 
scopes in the provided
         * List
         * @param scopeNames - list of BPEL process Scope names
         * @param type - the event type
         */
        public boolean isEventEnabled(List<String> scopeNames, TYPE type) {
                // TODO - this will need an analysis of the content of the BPEL 
process
                // TODO Auto-generated method stub
                return false;
        }

        /**
         * Returns whether the process is persisted in the store
         *
         * Returns true for SCA configuration as the BPEL process is in the 
Domain config
         */
        public boolean isTransient() {
                return true;
        } // end isTransient
        
        /**
         * Compiles a BPEL process file into a compiled form CBP file in the 
main directory
         * (ie same directory as the BPEL process file)
         * @param bpelFile - the BPEL process file
         */
        private void compile( File bpelFile ) {
                // Set up the compiler
                BpelC compiler = BpelC.newBpelCompiler();
                // Provide a null set of initial properties for now
                Map<QName, Node> processProps = new HashMap<QName, Node>();
                Map<String, Object> compileProps = new HashMap<String, 
Object>();
        compileProps.put( BpelC.PROCESS_CUSTOM_PROPERTIES, processProps );
                compiler.setCompileProperties( compileProps );
        compiler.setBaseDirectory( getDirectory() );

        // Run the compiler and generate the CBP file into the given directory
        try {
            compiler.compile( bpelFile );
        } catch (IOException e) {
            System.out.println("Compile error in " + bpelFile + e);
            // TODO - need better exception handling here
        } // end try
    } // end compile
        
        /**
         * Gets the directory containing the BPEL process
         * @return
         */
        private File getDirectory() {
                File theDir = getBPELFile().getParentFile();
                return theDir;
        } // end getDirectory
        
        /**
         * Gets the File containing the BPEL process definition
         * @return - the File object containing the BPEL process
         */
        private File getBPELFile() {
                File theProcess = new File( 
implementation.getProcessDefinition().getURI() );
                return theProcess;
        } // end getBPELFile
        
        /**
         * Gets the relative path of a file against a directory in its hierarchy
         * @param base - the base directory
         * @param path - the file
         * @return
         * @throws IOException
         */
    private String getRelativePath(File base, File path) throws IOException {
        String basePath = base.getCanonicalPath();
        String filePath = path.getCanonicalPath();
if (!filePath.startsWith(basePath)) throw new IOException("Invalid relative path: base="+base+" path="+path);
        String relative = filePath.substring(basePath.length());
        if (relative.startsWith(File.separator)) relative = 
relative.substring(1);
        return relative;
    } // end getRelativePath

} // end class TuscanyProcessConfImpl


Reply via email to