diff --git a/.gitignore b/.gitignore index 27225ba8ea..5199c2a8d1 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ derby.log Gemfile.lock spoon *.log +.m2 +tmp/ diff --git a/README.extensions b/README.extensions new file mode 100644 index 0000000000..689ee97121 --- /dev/null +++ b/README.extensions @@ -0,0 +1,22 @@ +============================================= + Apache ODE - Extension Installation Guide +============================================= + +BPEL 2.0 introduces extensibility mechanisms, which allow you to extend +the set of activities and/or variable assignment mechanisms. +With BPEL 2.0 it is possible to extend the language by user-defined +activities and custom assignment logic. + +Since version 1.2 Apache ODE supports these extensibility mechanismns +and provides a plug-in architecture that allows for registering +third-party extensions. + +1.) Installation of extensions (WAR) + 1) Copy the extension + TBC + +2.) Installation of extensions (JBI) + TBW + +3.) Writing ODE extensions +TBW diff --git a/Rakefile b/Rakefile index fd54945fb0..e5abd4f4cd 100644 --- a/Rakefile +++ b/Rakefile @@ -316,7 +316,7 @@ define "ode" do desc "ODE BPEL Tests" define "bpel-test" do compile.with projects("bpel-api", "bpel-compiler", "bpel-dao", "bpel-runtime", - "bpel-store", "utils", "bpel-epr", "dao-hibernate", "agents", "scheduler-simple"), + "bpel-store", "utils", "bpel-epr", "dao-hibernate", "agents", "scheduler-simple", "bpel-nobj"), DERBY, JUnit.dependencies, JAVAX.persistence, OPENJPA, WSDL4J, COMMONS.httpclient, COMMONS.io, GERONIMO.transaction, GERONIMO.kernel, GERONIMO.connector, JAVAX.connector, JAVAX.ejb, JAVAX.transaction, TRANQL, "tranql:tranql-connector-derby-common:jar:1.1", SPRING_TEST, COMMONS.codec, SLF4J, LOG4J2 diff --git a/bpel-api/src/main/java/org/apache/ode/bpel/eapi/ExtensionContext.java b/bpel-api/src/main/java/org/apache/ode/bpel/eapi/ExtensionContext.java index e3cf2713b2..378edc6c93 100644 --- a/bpel-api/src/main/java/org/apache/ode/bpel/eapi/ExtensionContext.java +++ b/bpel-api/src/main/java/org/apache/ode/bpel/eapi/ExtensionContext.java @@ -14,11 +14,10 @@ */ package org.apache.ode.bpel.eapi; -import java.util.List; import java.util.Map; import org.apache.ode.bpel.common.FaultException; -import org.apache.ode.bpel.obj.OLink; +import org.apache.ode.bpel.obj.OActivity; import org.apache.ode.bpel.obj.OProcess; import org.apache.ode.bpel.obj.OScope; import org.w3c.dom.Node; @@ -41,14 +40,6 @@ public interface ExtensionContext { */ Map getVisibleVariables() throws FaultException; - /** - * Returns a list of links. - * - * @return an unmodifiable list of visible variables. - * @throws FaultException - */ - List getLinks() throws FaultException; - /** * Read the value of a BPEL variable. * @@ -95,14 +86,6 @@ public interface ExtensionContext { String readMessageProperty(OScope.Variable variable, OProcess.OProperty property) throws FaultException; - /** - * Obtain the status of a control link. - * - * @param olink link to check - * @return true if the link is active, false otherwise. - */ - boolean isLinkActive(OLink olink) throws FaultException; - /** * Reads the current process instance id. * @@ -110,4 +93,21 @@ String readMessageProperty(OScope.Variable variable, OProcess.OProperty property */ Long getProcessId(); + /** + * Returns the name of the invoking activity. + * @return activity name + */ + String getActivityName(); + + /** + * Low-level-method + */ + OActivity getOActivity(); + + //ScopeFrame getScopeFrame(); + void complete(); + + void completeWithFault(Throwable t); + + void completeWithFault(FaultException fault); } diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java index ef4a876f3b..24c72bcfa8 100644 --- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java +++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java @@ -1665,6 +1665,9 @@ private void compileExtension(Extension ext) { _declaredExtensionNS.add(ext.getNamespaceURI()); _oprocess.getDeclaredExtensions().add(oextension); + if (ext.isMustUnderstand()) { + _oprocess.getMustUnderstandExtensions().add(oextension); + } if (__log.isDebugEnabled()) __log.debug("Compiled extension " + oextension); diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensibilityQNames.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensibilityQNames.java index 8f87d571fd..4f40d8d948 100644 --- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensibilityQNames.java +++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensibilityQNames.java @@ -46,7 +46,7 @@ public abstract class ExtensibilityQNames { public static final String NS_BPEL_EXTENSIBILITY = "http://ode.apache.org/bpelExtensibility"; - public static final QName UNKNOWN_EO_FAULT_NAME = new QName(NS_BPEL_EXTENSIBILITY, "unknownExtensionOperation"); + public static final QName UNKNOWN_EA_FAULT_NAME = new QName(NS_BPEL_EXTENSIBILITY, "unknownExtensionImplementation"); public static final QName INVALID_EXTENSION_ELEMENT = new QName(NS_BPEL_EXTENSIBILITY, "invalidExtensionElement"); } diff --git a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OProcess.java b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OProcess.java index a01936f81e..bc1ebde579 100644 --- a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OProcess.java +++ b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OProcess.java @@ -1,20 +1,16 @@ /* - * 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 + * 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 + * 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. + * 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.ode.bpel.obj; @@ -51,272 +47,272 @@ /** * Compiled BPEL process representation. */ -public class OProcess extends OBase implements Serializable{ - public static final long serialVersionUID = -1L; - - /** - * Change log of class version - * initial 1 - * current 2 - * - * 1->2: - * added namespaceContext attribute - * */ - public static final int CURRENT_CLASS_VERSION = 2; - - public static int instanceCount = 0; - private static final String GUID = "guid"; - /** BPEL version. */ - private static final String VERSION = "version"; - /** Various constants that are needed at runtime. */ - private static final String CONSTANTS = "constants"; - /** Universally Unique Identifier */ - private static final String UUID = "uuid"; - /** Namespace of the process. */ - private static final String TARGETNAMESPACE = "targetNamespace"; - /** Name of the process. */ - private static final String PROCESSNAME = "processName"; - /** ProcessImpl-level scope. */ - private static final String PROCESSCOPE = "procesScope"; - /** All partner links in the process. */ - private static final String ALLPARTNERLINKS = "allPartnerLinks"; - private static final String PROPERTIES = "properties"; - /** Date process was compiled. */ - private static final String COMPILEDATE = "compileDate"; - private static final String CHILDIDCOUNTER = "_childIdCounter"; - private static final String CHILDREN = "_children"; - private static final String EXPRESSIONLANGUAGES = "expressionLanguages"; - private static final String MESSAGETYPES = "messageTypes"; - private static final String ELEMENTTYPES = "elementTypes"; - private static final String XSDTYPES = "xsdTypes"; - private static final String XSLSHEETS = "xslSheets"; - private static final String NAMESPACECONTEXT = "namespaceContext"; - - /** All declared extensions in the process. **/ - private static final String DECLAREDEXTENSIONS = "declaredExtensions"; - - /** - * This constructor should only be used by Jackson when deserialize. - */ - @JsonCreator - public OProcess() { - instanceCount ++; - setChildIdCounter(0); - } - public OProcess(String version) { - super(null); - setVersion(version); - instanceCount++; - setAllPartnerLinks(new HashSet()); - setProperties(new ArrayList()); - setChildren(new ArrayList()); - setExpressionLanguages(new HashSet()); - setMessageTypes(new HashMap()); - setElementTypes(new HashMap()); - setXsdTypes(new HashMap()); - setXslSheets(new HashMap()); - - setDeclaredExtensions(new HashSet()); - - setChildIdCounter(0); - } - - @Override - public void dehydrate() { - super.dehydrate(); - getProcesScope().dehydrate(); - getAllPartnerLinks().clear(); - for (OBase obase : getChildren()) { - obase.dehydrate(); - } - getChildren().clear(); - getMessageTypes().clear(); - getElementTypes().clear(); - getXsdTypes().clear(); - getXslSheets().clear(); - getDeclaredExtensions().clear(); - } - - @Override - public String digest() { - return getProcessName() + ";" + getProcesScope().digest(); - } - - protected void finalize() throws Throwable { - instanceCount--; - } - - @SuppressWarnings("unchecked") - @JsonIgnore - public Set getAllPartnerLinks() { - Set links = (Set) fieldContainer - .get(ALLPARTNERLINKS); - return links; - } - - public OBase getChild(final int id) { - for (int i = getChildren().size() - 1; i >= 0; i--) { - OBase child = getChildren().get(i); - if (child.getId() == id) - return child; - } - return null; - } - - @JsonIgnore - int getChildIdCounter() { - Object o = fieldContainer.get(CHILDIDCOUNTER); - return o == null ? 0 : (Integer)o; - } - - @SuppressWarnings("unchecked") - @JsonIgnore - public List getChildren() { - Object o = fieldContainer.get(CHILDREN); - return o == null ? null : (List)o; - } - - @JsonIgnore - public Date getCompileDate() { - Object o = fieldContainer.get(COMPILEDATE); - return o == null ? null : (Date)o; - } - - @JsonIgnore - public OConstants getConstants() { - Object o = fieldContainer.get(CONSTANTS); - return o == null ? null : (OConstants)o; - } - - @SuppressWarnings("rawtypes") - @ObjectDiffProperty(ignore = true) - @JsonIgnore - public List getCorrelators() { - // MOVED from ProcessSchemaGenerator - List correlators = new ArrayList(); - - for (OPartnerLink plink : getAllPartnerLinks()) { - if (plink.hasMyRole()) { - for (Iterator opI = plink.getMyRolePortType().getOperations() - .iterator(); opI.hasNext();) { - Operation op = (Operation) opI.next(); - correlators.add(plink.getName() + "." + op.getName()); - } - } - } - - return correlators; - } - - @SuppressWarnings("unchecked") - @JsonIgnore - public HashMap getElementTypes() { - return (HashMap) fieldContainer - .get(ELEMENTTYPES); - } - - @JsonIgnore - @SuppressWarnings("unchecked") - public HashSet getExpressionLanguages() { - //TODO conflicts with legacy impl of this method - return (HashSet) fieldContainer - .get(EXPRESSIONLANGUAGES); - } - - @JsonIgnore - public String getGuid() { - Object o = fieldContainer.get(GUID); - return o == null ? null : (String)o; - } - - @SuppressWarnings("unchecked") - @JsonIgnore - public HashMap getMessageTypes() { - return (HashMap) fieldContainer - .get(MESSAGETYPES); - } - - @JsonIgnore - public String getName() { - return getProcessName(); - } - - @JsonIgnore - public NSContext getNamespaceContext() { - Object o = fieldContainer.get(NAMESPACECONTEXT); - return o == null ? null : (NSContext)o; - } - - @JsonIgnore - public OPartnerLink getPartnerLink(String name) { - for (OPartnerLink partnerLink : getAllPartnerLinks()) { - if (partnerLink.getName().equals(name)) { - return partnerLink; - } - } - return null; - } - - @JsonIgnore - public OScope getProcesScope() { - Object o = fieldContainer.get(PROCESSCOPE); - return o == null ? null : (OScope)o; - } - - @JsonIgnore - public String getProcessName() { - Object o = fieldContainer.get(PROCESSNAME); - return o == null ? null : (String)o; - } - - @SuppressWarnings("unchecked") - @JsonIgnore - public List getProperties() { - Object o = fieldContainer.get(PROPERTIES); - return o == null ? null : (List)o; - } - - @ObjectDiffProperty(ignore = true) - @JsonIgnore - public QName getQName() { - return new QName(getTargetNamespace(), getProcessName()); - } - - public OScope getScope(String scopeName) { - throw new UnsupportedOperationException(); - } - - @JsonIgnore - public String getTargetNamespace() { - Object o = fieldContainer.get(TARGETNAMESPACE); - return o == null ? null : (String)o; - } - - @JsonIgnore - public String getUuid() { - Object o = fieldContainer.get(UUID); - return o == null ? null : (String)o; - } - - @JsonIgnore - public String getVersion() { - Object o = fieldContainer.get(VERSION); - return o == null ? null : (String)o; - } - - @SuppressWarnings("unchecked") - @JsonIgnore - public HashMap getXsdTypes() { - Object o = fieldContainer.get(XSDTYPES); - return o == null ? null : (HashMap)o; - } - - @SuppressWarnings("unchecked") - @JsonIgnore - public HashMap getXslSheets() { - Object o = fieldContainer.get(XSLSHEETS); - return o == null ? null : (HashMap)o; - } +public class OProcess extends OBase implements Serializable { + public static final long serialVersionUID = -1L; + + /** + * Change log of class version initial 1 current 2 + * + * 1->2: added namespaceContext attribute + */ + public static final int CURRENT_CLASS_VERSION = 2; + + public static int instanceCount = 0; + private static final String GUID = "guid"; + /** BPEL version. */ + private static final String VERSION = "version"; + /** Various constants that are needed at runtime. */ + private static final String CONSTANTS = "constants"; + /** Universally Unique Identifier */ + private static final String UUID = "uuid"; + /** Namespace of the process. */ + private static final String TARGETNAMESPACE = "targetNamespace"; + /** Name of the process. */ + private static final String PROCESSNAME = "processName"; + /** ProcessImpl-level scope. */ + private static final String PROCESSCOPE = "procesScope"; + /** All partner links in the process. */ + private static final String ALLPARTNERLINKS = "allPartnerLinks"; + private static final String PROPERTIES = "properties"; + /** Date process was compiled. */ + private static final String COMPILEDATE = "compileDate"; + private static final String CHILDIDCOUNTER = "_childIdCounter"; + private static final String CHILDREN = "_children"; + private static final String EXPRESSIONLANGUAGES = "expressionLanguages"; + private static final String MESSAGETYPES = "messageTypes"; + private static final String ELEMENTTYPES = "elementTypes"; + private static final String XSDTYPES = "xsdTypes"; + private static final String XSLSHEETS = "xslSheets"; + private static final String NAMESPACECONTEXT = "namespaceContext"; + + /** All declared extensions in the process. **/ + private static final String DECLAREDEXTENSIONS = "declaredExtensions"; + + /** All must-understand extensions in the process. **/ + private static final String MUSTUNDERSTANDEXTENSIONS = "mustUnderstandExtensions"; + + /** + * This constructor should only be used by Jackson when deserialize. + */ + @JsonCreator + public OProcess() { + instanceCount++; + setChildIdCounter(0); + } + + public OProcess(String version) { + super(null); + setVersion(version); + instanceCount++; + setAllPartnerLinks(new HashSet()); + setProperties(new ArrayList()); + setChildren(new ArrayList()); + setExpressionLanguages(new HashSet()); + setMessageTypes(new HashMap()); + setElementTypes(new HashMap()); + setXsdTypes(new HashMap()); + setXslSheets(new HashMap()); + + setDeclaredExtensions(new HashSet()); + + setMustUnderstandExtensions(new HashSet()); + + setChildIdCounter(0); + } + + @Override + public void dehydrate() { + super.dehydrate(); + getProcesScope().dehydrate(); + getAllPartnerLinks().clear(); + for (OBase obase : getChildren()) { + obase.dehydrate(); + } + getChildren().clear(); + getMessageTypes().clear(); + getElementTypes().clear(); + getXsdTypes().clear(); + getXslSheets().clear(); + getDeclaredExtensions().clear(); + getMustUnderstandExtensions().clear(); + } + + @Override + public String digest() { + return getProcessName() + ";" + getProcesScope().digest(); + } + + protected void finalize() throws Throwable { + instanceCount--; + } + + @SuppressWarnings("unchecked") + @JsonIgnore + public Set getAllPartnerLinks() { + Set links = (Set) fieldContainer.get(ALLPARTNERLINKS); + return links; + } + + public OBase getChild(final int id) { + for (int i = getChildren().size() - 1; i >= 0; i--) { + OBase child = getChildren().get(i); + if (child.getId() == id) + return child; + } + return null; + } + + @JsonIgnore + int getChildIdCounter() { + Object o = fieldContainer.get(CHILDIDCOUNTER); + return o == null ? 0 : (Integer) o; + } + + @SuppressWarnings("unchecked") + @JsonIgnore + public List getChildren() { + Object o = fieldContainer.get(CHILDREN); + return o == null ? null : (List) o; + } + + @JsonIgnore + public Date getCompileDate() { + Object o = fieldContainer.get(COMPILEDATE); + return o == null ? null : (Date) o; + } + + @JsonIgnore + public OConstants getConstants() { + Object o = fieldContainer.get(CONSTANTS); + return o == null ? null : (OConstants) o; + } + + @SuppressWarnings("rawtypes") + @ObjectDiffProperty(ignore = true) + @JsonIgnore + public List getCorrelators() { + // MOVED from ProcessSchemaGenerator + List correlators = new ArrayList(); + + for (OPartnerLink plink : getAllPartnerLinks()) { + if (plink.hasMyRole()) { + for (Iterator opI = plink.getMyRolePortType().getOperations().iterator(); opI + .hasNext();) { + Operation op = (Operation) opI.next(); + correlators.add(plink.getName() + "." + op.getName()); + } + } + } + + return correlators; + } + + @SuppressWarnings("unchecked") + @JsonIgnore + public HashMap getElementTypes() { + return (HashMap) fieldContainer.get(ELEMENTTYPES); + } + + @JsonIgnore + @SuppressWarnings("unchecked") + public HashSet getExpressionLanguages() { + // TODO conflicts with legacy impl of this method + return (HashSet) fieldContainer.get(EXPRESSIONLANGUAGES); + } + + @JsonIgnore + public String getGuid() { + Object o = fieldContainer.get(GUID); + return o == null ? null : (String) o; + } + + @SuppressWarnings("unchecked") + @JsonIgnore + public HashMap getMessageTypes() { + return (HashMap) fieldContainer.get(MESSAGETYPES); + } + + @JsonIgnore + public String getName() { + return getProcessName(); + } + + @JsonIgnore + public NSContext getNamespaceContext() { + Object o = fieldContainer.get(NAMESPACECONTEXT); + return o == null ? null : (NSContext) o; + } + + @JsonIgnore + public OPartnerLink getPartnerLink(String name) { + for (OPartnerLink partnerLink : getAllPartnerLinks()) { + if (partnerLink.getName().equals(name)) { + return partnerLink; + } + } + return null; + } + + @JsonIgnore + public OScope getProcesScope() { + Object o = fieldContainer.get(PROCESSCOPE); + return o == null ? null : (OScope) o; + } + + @JsonIgnore + public String getProcessName() { + Object o = fieldContainer.get(PROCESSNAME); + return o == null ? null : (String) o; + } + + @SuppressWarnings("unchecked") + @JsonIgnore + public List getProperties() { + Object o = fieldContainer.get(PROPERTIES); + return o == null ? null : (List) o; + } + + @ObjectDiffProperty(ignore = true) + @JsonIgnore + public QName getQName() { + return new QName(getTargetNamespace(), getProcessName()); + } + + public OScope getScope(String scopeName) { + throw new UnsupportedOperationException(); + } + + @JsonIgnore + public String getTargetNamespace() { + Object o = fieldContainer.get(TARGETNAMESPACE); + return o == null ? null : (String) o; + } + + @JsonIgnore + public String getUuid() { + Object o = fieldContainer.get(UUID); + return o == null ? null : (String) o; + } + + @JsonIgnore + public String getVersion() { + Object o = fieldContainer.get(VERSION); + return o == null ? null : (String) o; + } + + @SuppressWarnings("unchecked") + @JsonIgnore + public HashMap getXsdTypes() { + Object o = fieldContainer.get(XSDTYPES); + return o == null ? null : (HashMap) o; + } + + @SuppressWarnings("unchecked") + @JsonIgnore + public HashMap getXslSheets() { + Object o = fieldContainer.get(XSLSHEETS); + return o == null ? null : (HashMap) o; + } @SuppressWarnings("unchecked") @JsonIgnore @@ -324,235 +320,261 @@ public Set getDeclaredExtensions() { return (Set) fieldContainer.get(DECLAREDEXTENSIONS); } - public void setAllPartnerLinks(Set allPartnerLinks) { - if (getAllPartnerLinks() == null) { - fieldContainer.put(ALLPARTNERLINKS, allPartnerLinks); - } - } - - void setChildIdCounter(int childIdCounter) { - fieldContainer.put(CHILDIDCOUNTER, childIdCounter); - } - - void setChildren(List children) { - fieldContainer.put(CHILDREN, children); - } - - public void setCompileDate(Date compileDate) { - fieldContainer.put(COMPILEDATE, compileDate); - } - - public void setConstants(OConstants constants) { - fieldContainer.put(CONSTANTS, constants); - } - - public void setElementTypes(HashMap elementTypes) { - if (getElementTypes() == null) { - fieldContainer.put(ELEMENTTYPES, elementTypes); - } - } - - public void setExpressionLanguages( - HashSet expressionLanguages) { - if (getExpressionLanguages() == null) { - fieldContainer.put(EXPRESSIONLANGUAGES, expressionLanguages); - } - } - - public void setGuid(String guid) { - fieldContainer.put(GUID, guid); - } - - public void setMessageTypes(HashMap messageTypes) { - if (getMessageTypes() == null) { - fieldContainer.put(MESSAGETYPES, messageTypes); - } - } - - public void setNamespaceContext(NSContext namespaceContext) { - fieldContainer.put(NAMESPACECONTEXT, namespaceContext); - } - - public void setProcesScope(OScope procesScope) { - fieldContainer.put(PROCESSCOPE, procesScope); - } - - public void setProcessName(String processName) { - fieldContainer.put(PROCESSNAME, processName); - } - - public void setProperties(List properties) { - if (getProperties() == null) { - fieldContainer.put(PROPERTIES, properties); - } - } - - public void setTargetNamespace(String targetNamespace) { - fieldContainer.put(TARGETNAMESPACE, targetNamespace); - } - - public void setUuid(String uuid) { - fieldContainer.put(UUID, uuid); - } - - public void setVersion(String version) { - fieldContainer.put(VERSION, version); - } - - public void setXsdTypes(HashMap xsdTypes) { - if (getXsdTypes() == null) { - fieldContainer.put(XSDTYPES, xsdTypes); - } - } - - public void setXslSheets(HashMap xslSheets) { - if (getXslSheets() == null) { - fieldContainer.put(XSLSHEETS, xslSheets); - } - } - + @SuppressWarnings("unchecked") + @JsonIgnore + public Set getMustUnderstandExtensions() { + return (Set) fieldContainer.get(MUSTUNDERSTANDEXTENSIONS); + } + + @JsonIgnore + public boolean hasMustUnderstandExtension(String namespaceURI) { + boolean found = false; + + // Check if an extension implementation is registered for the given namespareURI that the + // engine must understand + Iterator iter = getMustUnderstandExtensions().iterator(); + while (!found && iter.hasNext()) { + OExtension ext = iter.next(); + if (ext.getNamespace().equals(namespaceURI)) { + found = true; + } + } + + return found; + } + + public void setAllPartnerLinks(Set allPartnerLinks) { + if (getAllPartnerLinks() == null) { + fieldContainer.put(ALLPARTNERLINKS, allPartnerLinks); + } + } + + void setChildIdCounter(int childIdCounter) { + fieldContainer.put(CHILDIDCOUNTER, childIdCounter); + } + + void setChildren(List children) { + fieldContainer.put(CHILDREN, children); + } + + public void setCompileDate(Date compileDate) { + fieldContainer.put(COMPILEDATE, compileDate); + } + + public void setConstants(OConstants constants) { + fieldContainer.put(CONSTANTS, constants); + } + + public void setElementTypes(HashMap elementTypes) { + if (getElementTypes() == null) { + fieldContainer.put(ELEMENTTYPES, elementTypes); + } + } + + public void setExpressionLanguages(HashSet expressionLanguages) { + if (getExpressionLanguages() == null) { + fieldContainer.put(EXPRESSIONLANGUAGES, expressionLanguages); + } + } + + public void setGuid(String guid) { + fieldContainer.put(GUID, guid); + } + + public void setMessageTypes(HashMap messageTypes) { + if (getMessageTypes() == null) { + fieldContainer.put(MESSAGETYPES, messageTypes); + } + } + + public void setNamespaceContext(NSContext namespaceContext) { + fieldContainer.put(NAMESPACECONTEXT, namespaceContext); + } + + public void setProcesScope(OScope procesScope) { + fieldContainer.put(PROCESSCOPE, procesScope); + } + + public void setProcessName(String processName) { + fieldContainer.put(PROCESSNAME, processName); + } + + public void setProperties(List properties) { + if (getProperties() == null) { + fieldContainer.put(PROPERTIES, properties); + } + } + + public void setTargetNamespace(String targetNamespace) { + fieldContainer.put(TARGETNAMESPACE, targetNamespace); + } + + public void setUuid(String uuid) { + fieldContainer.put(UUID, uuid); + } + + public void setVersion(String version) { + fieldContainer.put(VERSION, version); + } + + public void setXsdTypes(HashMap xsdTypes) { + if (getXsdTypes() == null) { + fieldContainer.put(XSDTYPES, xsdTypes); + } + } + + public void setXslSheets(HashMap xslSheets) { + if (getXslSheets() == null) { + fieldContainer.put(XSLSHEETS, xslSheets); + } + } + public void setDeclaredExtensions(Set extensions) { if (getDeclaredExtensions() == null) { fieldContainer.put(DECLAREDEXTENSIONS, extensions); } } - - private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{ - ois.defaultReadObject(); - fieldContainer.remove(NAMESPACECONTEXT); - } - - public static class OProperty extends OBase implements Serializable{ - public static final long serialVersionUID = -1L; - - private static final String ALIASES = "aliases"; - private static final String NAME = "name"; - - @JsonCreator - public OProperty(){} - public OProperty(OProcess process) { - super(process); - setAliases(new ArrayList()); - } - - public OPropertyAlias getAlias(OVarType messageType) { - for (OPropertyAlias aliase : getAliases()) - if (aliase.getVarType().equals(messageType)) - return aliase; - return null; - } - - @SuppressWarnings("unchecked") - @JsonIgnore - public List getAliases() { - Object o = fieldContainer.get(ALIASES); - return o == null ? null : (List)o; - } - - @JsonIgnore - public QName getName() { - Object o = fieldContainer.get(NAME); - return o == null ? null : (QName)o; - } - - public void setAliases(List aliases) { - fieldContainer.put(ALIASES, aliases); - } - - public void setName(QName name) { - fieldContainer.put(NAME, name); - } - - public String toString() { - return "{OProperty " + getName() + "}"; - } - } - - public static class OPropertyAlias extends OBase implements Serializable{ - public static final long serialVersionUID = -1L; - /** - * Change log of class version - * initial 1 - * current 2 - * - * 1->2: - * added header attribute - * */ - public static final int CURRENT_CLASS_VERSION = 2; - - private static final String VARTYPE = "varType"; - - /** For BPEL 1.1 */ - private static final String PART = "part"; - private static final String HEADER = "header"; - private static final String LOCATION = "location"; - - @JsonCreator - public OPropertyAlias(){} - - public OPropertyAlias(OProcess owner) { - super(owner); - } - - @JsonIgnore - public String getDescription() { - StringBuffer buf = new StringBuffer(getVarType().toString()); - buf.append('['); - buf.append(getPart() != null ? getPart().getName() : ""); - buf.append(getHeader() != null ? "header: " + getHeader() : ""); - if (getLocation() != null) { - buf.append("]["); - buf.append(getLocation().toString()); - } - buf.append(']'); - return buf.toString(); - } - - @JsonIgnore - public String getHeader() { - Object o = fieldContainer.get(HEADER); - return o == null ? null : (String)o; - } - - @JsonIgnore - public OExpression getLocation() { - Object o = fieldContainer.get(LOCATION); - return o == null ? null : (OExpression)o; - } - - @JsonIgnore - public Part getPart() { - Object o = fieldContainer.get(PART); - return o == null ? null : (Part)o; - } - - @JsonIgnore - public OVarType getVarType() { - Object o = fieldContainer.get(VARTYPE); - return o == null ? null : (OVarType)o; - } - - public void setHeader(String header) { - fieldContainer.put(HEADER, header); - } - - public void setLocation(OExpression location) { - fieldContainer.put(LOCATION, location); - } - - public void setPart(Part part) { - fieldContainer.put(PART, part); - } - - public void setVarType(OVarType varType) { - fieldContainer.put(VARTYPE, varType); - } - - public String toString() { - return "{OPropertyAlias " + getDescription() + "}"; - } - - } + + public void setMustUnderstandExtensions(Set extensions) { + if (getMustUnderstandExtensions() == null) { + fieldContainer.put(MUSTUNDERSTANDEXTENSIONS, extensions); + } + } + + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + ois.defaultReadObject(); + fieldContainer.remove(NAMESPACECONTEXT); + } + + public static class OProperty extends OBase implements Serializable { + public static final long serialVersionUID = -1L; + + private static final String ALIASES = "aliases"; + private static final String NAME = "name"; + + @JsonCreator + public OProperty() {} + + public OProperty(OProcess process) { + super(process); + setAliases(new ArrayList()); + } + + public OPropertyAlias getAlias(OVarType messageType) { + for (OPropertyAlias aliase : getAliases()) + if (aliase.getVarType().equals(messageType)) + return aliase; + return null; + } + + @SuppressWarnings("unchecked") + @JsonIgnore + public List getAliases() { + Object o = fieldContainer.get(ALIASES); + return o == null ? null : (List) o; + } + + @JsonIgnore + public QName getName() { + Object o = fieldContainer.get(NAME); + return o == null ? null : (QName) o; + } + + public void setAliases(List aliases) { + fieldContainer.put(ALIASES, aliases); + } + + public void setName(QName name) { + fieldContainer.put(NAME, name); + } + + public String toString() { + return "{OProperty " + getName() + "}"; + } + } + + public static class OPropertyAlias extends OBase implements Serializable { + public static final long serialVersionUID = -1L; + /** + * Change log of class version initial 1 current 2 + * + * 1->2: added header attribute + */ + public static final int CURRENT_CLASS_VERSION = 2; + + private static final String VARTYPE = "varType"; + + /** For BPEL 1.1 */ + private static final String PART = "part"; + private static final String HEADER = "header"; + private static final String LOCATION = "location"; + + @JsonCreator + public OPropertyAlias() {} + + public OPropertyAlias(OProcess owner) { + super(owner); + } + + @JsonIgnore + public String getDescription() { + StringBuffer buf = new StringBuffer(getVarType().toString()); + buf.append('['); + buf.append(getPart() != null ? getPart().getName() : ""); + buf.append(getHeader() != null ? "header: " + getHeader() : ""); + if (getLocation() != null) { + buf.append("]["); + buf.append(getLocation().toString()); + } + buf.append(']'); + return buf.toString(); + } + + @JsonIgnore + public String getHeader() { + Object o = fieldContainer.get(HEADER); + return o == null ? null : (String) o; + } + + @JsonIgnore + public OExpression getLocation() { + Object o = fieldContainer.get(LOCATION); + return o == null ? null : (OExpression) o; + } + + @JsonIgnore + public Part getPart() { + Object o = fieldContainer.get(PART); + return o == null ? null : (Part) o; + } + + @JsonIgnore + public OVarType getVarType() { + Object o = fieldContainer.get(VARTYPE); + return o == null ? null : (OVarType) o; + } + + public void setHeader(String header) { + fieldContainer.put(HEADER, header); + } + + public void setLocation(OExpression location) { + fieldContainer.put(LOCATION, location); + } + + public void setPart(Part part) { + fieldContainer.put(PART, part); + } + + public void setVarType(OVarType varType) { + fieldContainer.put(VARTYPE, varType); + } + + public String toString() { + return "{OPropertyAlias " + getDescription() + "}"; + } + + } public static class OExtension extends OBase implements Serializable { public static final long serialVersionUID = -1L; @@ -593,36 +615,36 @@ public String toString() { } } - /** - * custom deserializer of OProcess. - * @author fangzhen - * @deprecated unnecessary now - */ - public static class OProcessDeser extends StdDeserializer - implements ResolvableDeserializer { - private static final long serialVersionUID = 7750214662590623362L; - private JsonDeserializer defaultDeserializer; - - public OProcessDeser(JsonDeserializer defaultDeserializer) { - super(OProcess.class); - this.defaultDeserializer = defaultDeserializer; - } - - @Override - public OProcess deserialize(JsonParser jp, DeserializationContext ctxt) - throws IOException, JsonProcessingException { - OProcess process = (OProcess) defaultDeserializer.deserialize(jp, - ctxt); - OProcess.instanceCount++; - return process; - } - - // for some reason you have to implement ResolvableDeserializer when modifying BeanDeserializer - // otherwise deserializing throws JsonMappingException?? - @Override - public void resolve(DeserializationContext ctxt) - throws JsonMappingException { - ((ResolvableDeserializer) defaultDeserializer).resolve(ctxt); - } - } + /** + * custom deserializer of OProcess. + * + * @author fangzhen + * @deprecated unnecessary now + */ + public static class OProcessDeser extends StdDeserializer + implements ResolvableDeserializer { + private static final long serialVersionUID = 7750214662590623362L; + private JsonDeserializer defaultDeserializer; + + public OProcessDeser(JsonDeserializer defaultDeserializer) { + super(OProcess.class); + this.defaultDeserializer = defaultDeserializer; + } + + @Override + public OProcess deserialize(JsonParser jp, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + OProcess process = (OProcess) defaultDeserializer.deserialize(jp, ctxt); + OProcess.instanceCount++; + return process; + } + + // for some reason you have to implement ResolvableDeserializer when modifying + // BeanDeserializer + // otherwise deserializing throws JsonMappingException?? + @Override + public void resolve(DeserializationContext ctxt) throws JsonMappingException { + ((ResolvableDeserializer) defaultDeserializer).resolve(ctxt); + } + } } diff --git a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/migrate/OmOld2new.java b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/migrate/OmOld2new.java index d8f017e28a..0c8692d8e4 100644 --- a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/migrate/OmOld2new.java +++ b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/migrate/OmOld2new.java @@ -194,10 +194,11 @@ private Object constructNewOm(Object old, Object tn) { } } - // @hahnml: We need to add the new "declaredExtensions" field to the process for + // @hahnml: We need to add the new "declaredExtensions" and "mustUnderstandExtensions" fields to the process for // equality. if (old.getClass().getSimpleName().equals("OProcess")) { fieldMap.put("declaredExtensions", new HashSet()); + fieldMap.put("mustUnderstandExtensions", new HashSet()); } n.setClassVersion(1); diff --git a/bpel-rest-extensions/src/main/java/org/apache/ode/bpel/extension/bpel4restlight/Bpel4RestLightOperation.java b/bpel-rest-extensions/src/main/java/org/apache/ode/bpel/extension/bpel4restlight/Bpel4RestLightOperation.java index f2b80dfdc3..1f40dc2235 100644 --- a/bpel-rest-extensions/src/main/java/org/apache/ode/bpel/extension/bpel4restlight/Bpel4RestLightOperation.java +++ b/bpel-rest-extensions/src/main/java/org/apache/ode/bpel/extension/bpel4restlight/Bpel4RestLightOperation.java @@ -16,10 +16,10 @@ import org.apache.ode.bpel.common.FaultException; import org.apache.ode.bpel.eapi.ExtensionContext; -import org.apache.ode.bpel.eapi.ExtensionOperation; import org.apache.ode.bpel.extension.bpel4restlight.http.HighLevelRestApi; import org.apache.ode.bpel.extension.bpel4restlight.http.HttpMethod; import org.apache.ode.bpel.extension.bpel4restlight.http.HttpResponseMessage; +import org.apache.ode.bpel.runtime.extension.AbstractSyncExtensionOperation; import org.w3c.dom.Element; /** @@ -30,9 +30,9 @@ * @author Michael Hahn (mhahn.dev@gmail.com) * */ -public class Bpel4RestLightOperation implements ExtensionOperation { +public class Bpel4RestLightOperation extends AbstractSyncExtensionOperation { - public void run(ExtensionContext context, Element element) throws FaultException { + public void runSync(ExtensionContext context, Element element) throws FaultException { String httpMethod = element.getLocalName(); // Extract requestUri diff --git a/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java b/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java index 60f5e34965..990d79dea3 100644 --- a/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java +++ b/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java @@ -129,8 +129,6 @@ public class BpelProcess { ExpressionLanguageRuntimeRegistry _expLangRuntimeRegistry; private ReplacementMap _replacementMap; final ProcessConf _pconf; - - Set _mustUnderstandExtensions; /** {@link MessageExchangeInterceptor}s registered for this process. */ private final List _mexInterceptors = new ArrayList(); @@ -960,7 +958,6 @@ private void doDehydrate() { // } _replacementMap = null; _expLangRuntimeRegistry = null; - _mustUnderstandExtensions = null; } private void doHydrate() { @@ -1004,16 +1001,13 @@ private void doHydrate() { // Checking for registered extension bundles, throw an exception when // a "mustUnderstand" extension is not available - _mustUnderstandExtensions = new HashSet(); - for (OProcess.OExtension extension : _oprocess.getDeclaredExtensions()) { + for (OProcess.OExtension extension : _oprocess.getMustUnderstandExtensions()) { if (extension.isMustUnderstand()) { if (_engine._contexts.extensionRegistry.get(extension.getNamespace()) == null) { String msg = __msgs.msgExtensionMustUnderstandError(_pid, extension.getNamespace()); __log.error(msg); throw new BpelEngineException(msg); - } else { - _mustUnderstandExtensions.add(extension.getNamespace()); } } else { __log.warn("The process declares the extension namespace " diff --git a/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java b/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java index 5a576de4aa..9f916cc349 100644 --- a/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java +++ b/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java @@ -37,7 +37,6 @@ import org.apache.ode.bpel.common.CorrelationKeySet; import org.apache.ode.bpel.common.FaultException; import org.apache.ode.bpel.common.ProcessState; -import org.apache.ode.bpel.compiler.bom.ExtensibilityQNames; import org.apache.ode.bpel.dao.CorrelationSetDAO; import org.apache.ode.bpel.dao.CorrelatorDAO; import org.apache.ode.bpel.dao.MessageDAO; @@ -50,7 +49,6 @@ import org.apache.ode.bpel.dao.ScopeStateEnum; import org.apache.ode.bpel.dao.XmlDataDAO; import org.apache.ode.bpel.eapi.AbstractExtensionBundle; -import org.apache.ode.bpel.eapi.ExtensionContext; import org.apache.ode.bpel.eapi.ExtensionOperation; import org.apache.ode.bpel.evar.ExternalVariableModule.Value; import org.apache.ode.bpel.evar.ExternalVariableModuleException; @@ -93,7 +91,6 @@ import org.apache.ode.bpel.runtime.Selector; import org.apache.ode.bpel.runtime.VariableInstance; import org.apache.ode.bpel.runtime.channels.ActivityRecovery; -import org.apache.ode.bpel.runtime.channels.ExtensionResponse; import org.apache.ode.bpel.runtime.channels.FaultData; import org.apache.ode.bpel.runtime.channels.InvokeResponse; import org.apache.ode.bpel.runtime.channels.PickResponse; @@ -1537,56 +1534,7 @@ public void forceFlush() { _forceFlush = true; } - public void executeExtension(QName extensionId, ExtensionContext context, Element element, - ExtensionResponse extResponseChannel) throws FaultException { - __log.debug("Execute extension activity"); - final String extResponseChannelStr = ProcessUtil.exportChannel(extResponseChannel); - - ExtensionOperation ea = createExtensionActivityImplementation(extensionId); - if (ea == null) { - if (_bpelProcess._mustUnderstandExtensions.contains(extensionId.getNamespaceURI())) { - // TODO - __log.warn("Lookup of extension activity " + extensionId + " failed."); - throw new FaultException(ExtensibilityQNames.UNKNOWN_EO_FAULT_NAME, - "Lookup of extension operation " + extensionId + " failed."); - } else { - // act like - do nothing - completeExtensionExecution(extResponseChannelStr, null); - return; - } - } - - try { - // should be running in a pooled thread - ea.run(context, element); - completeExtensionExecution(extResponseChannelStr, null); - } catch (RuntimeException e) { - __log.error("Error during execution of extension activity.", e); - completeExtensionExecution(extResponseChannelStr, e); - } - } - - private void completeExtensionExecution(final String channelId, final Throwable t) { - if (t != null) { - _vpu.inject(new BpelJacobRunnable() { - private static final long serialVersionUID = -1L; - - public void run() { - importChannel(channelId, ExtensionResponse.class).onFailure(t); - } - }); - } else { - _vpu.inject(new BpelJacobRunnable() { - private static final long serialVersionUID = -1L; - - public void run() { - importChannel(channelId, ExtensionResponse.class).onCompleted(); - } - }); - } - } - - private ExtensionOperation createExtensionActivityImplementation(QName name) { + public ExtensionOperation createExtensionActivityImplementation(QName name) { if (name == null) { return null; } diff --git a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ASSIGN.java b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ASSIGN.java index 53e25befb0..3290958487 100644 --- a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ASSIGN.java +++ b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ASSIGN.java @@ -19,8 +19,6 @@ package org.apache.ode.bpel.runtime; import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; import java.net.URI; import java.util.Calendar; import java.util.Date; @@ -32,6 +30,7 @@ import org.apache.ode.bpel.common.FaultException; import org.apache.ode.bpel.compiler.bom.ExtensibilityQNames; import org.apache.ode.bpel.eapi.ExtensionContext; +import org.apache.ode.bpel.eapi.ExtensionOperation; import org.apache.ode.bpel.evar.ExternalVariableModuleException; import org.apache.ode.bpel.evt.PartnerLinkModificationEvent; import org.apache.ode.bpel.evt.ScopeEvent; @@ -51,9 +50,7 @@ import org.apache.ode.bpel.obj.OProcess.OProperty; import org.apache.ode.bpel.obj.OScope; import org.apache.ode.bpel.obj.OScope.Variable; -import org.apache.ode.bpel.runtime.channels.ExtensionResponse; import org.apache.ode.bpel.runtime.channels.FaultData; -import org.apache.ode.jacob.ReceiveProcess; import org.apache.ode.utils.DOMUtils; import org.apache.ode.utils.Namespaces; import org.apache.ode.utils.msg.MessageBundle; @@ -679,49 +676,47 @@ private Node evalQuery(Node data, OMessageVarType.Part part, private void invokeExtensionAssignOperation(OAssign.ExtensionAssignOperation eao) throws FaultException { - try { - final ExtensionContext helper = - new ExtensionContextImpl(this._scopeFrame, getBpelRuntimeContext()); - final ExtensionResponse responseChannel = newChannel(ExtensionResponse.class); - - getBpelRuntimeContext().executeExtension(eao.getExtensionName(), helper, - DOMUtils.stringToDOM(eao.getNestedElement()), responseChannel); - - object(new ReceiveProcess() { - private static final long serialVersionUID = 1467660715539203917L; - }.setChannel(responseChannel).setReceiver(new ExtensionResponse() { - private static final long serialVersionUID = 509910466826372712L; + final ExtensionContext context = + new ExtensionContextImpl(this._self, this._scopeFrame, getBpelRuntimeContext()); + final QName extensionId = eao.getExtensionName(); - public void onCompleted() { - _self.parent.completed(null, CompensationHandler.emptySet()); + try { + ExtensionOperation ea = + getBpelRuntimeContext().createExtensionActivityImplementation(extensionId); + if (ea == null) { + if (eao.getOwner().hasMustUnderstandExtension(extensionId.getNamespaceURI())) { + __log.warn("Lookup of extension activity " + extensionId + " failed."); + throw new FaultException(ExtensibilityQNames.UNKNOWN_EA_FAULT_NAME, + "Lookup of extension assign operation " + extensionId + + " failed. No implementation found."); + } else { + // act like - do nothing + context.complete(); + return; } + } - public void onFailure(Throwable t) { - StringWriter sw = new StringWriter(); - t.printStackTrace(new PrintWriter(sw)); - FaultData fault = createFault( - _self.o.getOwner().getConstants().getQnSubLanguageExecutionFault(), - _self.o, sw.getBuffer().toString()); - _self.parent.completed(fault, CompensationHandler.emptySet()); - }; - })); + ea.run(context, DOMUtils.stringToDOM(eao.getNestedElement())); } catch (FaultException fault) { __log.error("Exception while invoking extension assign operation", fault); - FaultData faultData = createFault(fault.getQName(), _self.o, fault.getMessage()); - _self.parent.completed(faultData, CompensationHandler.emptySet()); + context.completeWithFault(fault); } catch (SAXException e) { - __log.error("Exception while invoking extension assign operation", e); - FaultData faultData = createFault(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT, - _self.o, "The nested element of extension assign operation '" - + eao.getExtensionName() + "' is no valid XML."); - _self.parent.completed(faultData, CompensationHandler.emptySet()); + __log.error("Exception while invoking extension assign operation", + e); + FaultException faultData = + new FaultException(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT, + "The nested element of extension assign operation '" + + eao.getExtensionName() + "' is no valid XML.", e); + context.completeWithFault(faultData); } catch (IOException e) { - __log.error("Exception while invoking extension assign operation", e); - FaultData faultData = createFault(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT, - _self.o, "The nested element of extension assign operation '" - + eao.getExtensionName() + "' is no valid XML."); - _self.parent.completed(faultData, CompensationHandler.emptySet()); + __log.error("Exception while invoking extension assign operation", + e); + FaultException faultData = + new FaultException(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT, + "The nested element of extension assign operation '" + + eao.getExtensionName() + "' is no valid XML.", e); + context.completeWithFault(faultData); } } diff --git a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelRuntimeContext.java b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelRuntimeContext.java index 30b318a68b..82891e8ade 100644 --- a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelRuntimeContext.java +++ b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelRuntimeContext.java @@ -27,7 +27,7 @@ import org.apache.ode.bpel.common.CorrelationKey; import org.apache.ode.bpel.common.FaultException; -import org.apache.ode.bpel.eapi.ExtensionContext; +import org.apache.ode.bpel.eapi.ExtensionOperation; import org.apache.ode.bpel.evar.ExternalVariableModuleException; import org.apache.ode.bpel.evt.ProcessInstanceEvent; import org.apache.ode.bpel.iapi.ProcessConf.PartnerRoleConfig; @@ -36,7 +36,6 @@ import org.apache.ode.bpel.obj.OScope; import org.apache.ode.bpel.obj.OScope.Variable; import org.apache.ode.bpel.runtime.channels.ActivityRecovery; -import org.apache.ode.bpel.runtime.channels.ExtensionResponse; import org.apache.ode.bpel.runtime.channels.FaultData; import org.apache.ode.bpel.runtime.channels.InvokeResponse; import org.apache.ode.bpel.runtime.channels.PickResponse; @@ -314,5 +313,5 @@ public class ValueReferencePair { void checkInvokeExternalPermission(); - void executeExtension(QName extensionId, ExtensionContext context, Element element, ExtensionResponse extResponseChannel) throws FaultException; + ExtensionOperation createExtensionActivityImplementation(QName name); } diff --git a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/EXTENSIONACTIVITY.java b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/EXTENSIONACTIVITY.java index dfa577134f..3f378ba718 100644 --- a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/EXTENSIONACTIVITY.java +++ b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/EXTENSIONACTIVITY.java @@ -15,16 +15,14 @@ package org.apache.ode.bpel.runtime; import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; + +import javax.xml.namespace.QName; import org.apache.ode.bpel.common.FaultException; import org.apache.ode.bpel.compiler.bom.ExtensibilityQNames; import org.apache.ode.bpel.eapi.ExtensionContext; +import org.apache.ode.bpel.eapi.ExtensionOperation; import org.apache.ode.bpel.obj.OExtensionActivity; -import org.apache.ode.bpel.runtime.channels.ExtensionResponse; -import org.apache.ode.bpel.runtime.channels.FaultData; -import org.apache.ode.jacob.ReceiveProcess; import org.apache.ode.utils.DOMUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,56 +46,48 @@ public EXTENSIONACTIVITY(ActivityInfo self, ScopeFrame scopeFrame, LinkFrame lin } public final void run() { + final ExtensionContext context = + new ExtensionContextImpl(_self, _scopeFrame, getBpelRuntimeContext()); + final QName extensionId = _oext.getExtensionName(); try { - final ExtensionResponse responseChannel = newChannel(ExtensionResponse.class); - final ExtensionContext helper = - new ExtensionContextImpl(_scopeFrame, getBpelRuntimeContext()); - - getBpelRuntimeContext().executeExtension(_oext.getExtensionName(), helper, - DOMUtils.stringToDOM(_oext.getNestedElement()), responseChannel); - - object(new ReceiveProcess() { - private static final long serialVersionUID = 3643564901004147956L; - }.setChannel(responseChannel).setReceiver(new ExtensionResponse() { - private static final long serialVersionUID = -6977609968638662977L; - - public void onCompleted() { - _self.parent.completed(null, CompensationHandler.emptySet()); + ExtensionOperation ea = + getBpelRuntimeContext().createExtensionActivityImplementation(extensionId); + if (ea == null) { + if (_oext.getOwner().hasMustUnderstandExtension(extensionId.getNamespaceURI())) { + __log.warn("Lookup of extension activity " + extensionId + " failed."); + throw new FaultException(ExtensibilityQNames.UNKNOWN_EA_FAULT_NAME, + "Lookup of extension activity " + extensionId + + " failed. No implementation found."); + } else { + // act like - do nothing + context.complete(); + return; } + } - public void onFailure(Throwable t) { - StringWriter sw = new StringWriter(); - t.printStackTrace(new PrintWriter(sw)); - FaultData fault = createFault( - _oext.getOwner().getConstants().getQnSubLanguageExecutionFault(), _oext, - sw.getBuffer().toString()); - _self.parent.completed(fault, CompensationHandler.emptySet()); - }; - })); - + ea.run(context, DOMUtils.stringToDOM(_oext.getNestedElement())); } catch (FaultException fault) { __log.error("Exception while invoking extension activity '" + _oext.getName() + "'.", fault); - FaultData faultData = createFault(fault.getQName(), _oext, fault.getMessage()); - _self.parent.completed(faultData, CompensationHandler.emptySet()); + context.completeWithFault(fault); } catch (SAXException e) { __log.error("Exception while invoking extension activity '" + _oext.getName() + "'.", e); - FaultData faultData = - createFault(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT, _self.o, + FaultException faultData = + new FaultException(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT, "The nested element of extension activity '" + _oext.getName() + "' for extension '" + _oext.getExtensionName() - + "' is no valid XML."); - _self.parent.completed(faultData, CompensationHandler.emptySet()); + + "' is no valid XML.", e); + context.completeWithFault(faultData); } catch (IOException e) { __log.error("Exception while invoking extension activity '" + _oext.getName() + "'.", e); - FaultData faultData = - createFault(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT, _self.o, + FaultException faultData = + new FaultException(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT, "The nested element of extension activity '" + _oext.getName() + "' for extension '" + _oext.getExtensionName() - + "' is no valid XML."); - _self.parent.completed(faultData, CompensationHandler.emptySet()); + + "' is no valid XML.", e); + context.completeWithFault(faultData); } } diff --git a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ExtensionContextImpl.java b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ExtensionContextImpl.java index 9e69dc7602..6dc846c803 100644 --- a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ExtensionContextImpl.java +++ b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ExtensionContextImpl.java @@ -14,27 +14,45 @@ */ package org.apache.ode.bpel.runtime; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.xml.namespace.QName; + import org.apache.ode.bpel.common.FaultException; +import org.apache.ode.bpel.compiler.bom.Bpel20QNames; import org.apache.ode.bpel.eapi.ExtensionContext; +import org.apache.ode.bpel.evt.ScopeEvent; +import org.apache.ode.bpel.evt.VariableModificationEvent; import org.apache.ode.bpel.obj.OActivity; import org.apache.ode.bpel.obj.OLink; import org.apache.ode.bpel.obj.OProcess.OProperty; import org.apache.ode.bpel.obj.OScope; import org.apache.ode.bpel.obj.OScope.Variable; +import org.apache.ode.bpel.runtime.channels.FaultData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Node; /** * @author Tammo van Lessen (University of Stuttgart) */ public class ExtensionContextImpl implements ExtensionContext { + + private static final Logger __log = LoggerFactory.getLogger(ExtensionContextImpl.class); + private BpelRuntimeContext _context; private ScopeFrame _scopeFrame; + private ActivityInfo _activityInfo; + + private boolean hasCompleted = false; - public ExtensionContextImpl(ScopeFrame scopeFrame, BpelRuntimeContext context) { + public ExtensionContextImpl(ActivityInfo activityInfo, ScopeFrame scopeFrame, + BpelRuntimeContext context) { + _activityInfo = activityInfo; _context = context; _scopeFrame = scopeFrame; } @@ -48,6 +66,14 @@ public Long getProcessId() { return _context.getPid(); } + public String getActivityName() { + return _activityInfo.o.getName(); + } + + public OActivity getOActivity() { + return _activityInfo.o; + } + public Map getVisibleVariables() throws FaultException { Map visVars = new HashMap(); @@ -66,11 +92,6 @@ public Map getVisibleVariables() throws FaultException return visVars; } - public boolean isLinkActive(OLink olink) throws FaultException { - // TODO Auto-generated method stub - return false; - } - public String readMessageProperty(Variable variable, OProperty property) throws FaultException { VariableInstance vi = _scopeFrame.resolve(variable); return _context.readProperty(vi, property); @@ -84,6 +105,10 @@ public Node readVariable(OScope.Variable variable) throws FaultException { public void writeVariable(String variableName, Node value) throws FaultException { VariableInstance vi = _scopeFrame.resolve(getVisibleVariable(variableName)); _context.writeVariable(vi, value); + + VariableModificationEvent vme = new VariableModificationEvent(variableName); + vme.setNewValue(value); + sendEvent(vme); } public Node readVariable(String variableName) throws FaultException { @@ -99,4 +124,60 @@ public void writeVariable(Variable variable, Node value) throws FaultException { private Variable getVisibleVariable(String varName) { return _scopeFrame.oscope.getVisibleVariable(varName); } + + public BpelRuntimeContext getBpelRuntimeContext() { + return _context; + } + + public void sendEvent(ScopeEvent event) { + if (event.getLineNo() == -1 && _activityInfo.o.getDebugInfo() != null) { + event.setLineNo(_activityInfo.o.getDebugInfo().getStartLine()); + } + _scopeFrame.fillEventInfo(event); + getBpelRuntimeContext().sendEvent(event); + } + + public void complete() { + if (!hasCompleted) { + _activityInfo.parent.completed(null, CompensationHandler.emptySet()); + hasCompleted = true; + } else { + if (__log.isWarnEnabled()) { + __log.warn( + "Activity '" + _activityInfo.o.getName() + "' has already been completed."); + } + } + } + + public void completeWithFault(Throwable t) { + if (!hasCompleted) { + StringWriter sw = new StringWriter(); + t.printStackTrace(new PrintWriter(sw)); + FaultData fault = + new FaultData(new QName(Bpel20QNames.NS_WSBPEL2_0, "subLanguageExecutionFault"), + _activityInfo.o, sw.getBuffer().toString()); + _activityInfo.parent.completed(fault, CompensationHandler.emptySet()); + hasCompleted = true; + } else { + if (__log.isWarnEnabled()) { + __log.warn( + "Activity '" + _activityInfo.o.getName() + "' has already been completed."); + } + } + } + + public void completeWithFault(FaultException ex) { + if (!hasCompleted) { + FaultData fault = new FaultData(ex.getQName(), _activityInfo.o, ex.getMessage()); + _activityInfo.parent.completed(fault, CompensationHandler.emptySet()); + hasCompleted = true; + } else { + if (__log.isWarnEnabled()) { + __log.warn( + "Activity '" + _activityInfo.o.getName() + "' has already been completed."); + } + } + + } + } diff --git a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/channels/ExtensionResponse.java b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/channels/ExtensionResponse.java deleted file mode 100644 index faf4e5fefb..0000000000 --- a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/channels/ExtensionResponse.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.ode.bpel.runtime.channels; - -import org.apache.ode.jacob.Channel; - -/** - * Response channel for extension activity executions. - * - * @author Tammo van Lessen (University of Stuttgart) - */ -public interface ExtensionResponse extends Channel { - - void onCompleted(); - - void onFailure(Throwable t); - -} diff --git a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/extension/AbstractAsyncExtensionOperation.java b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/extension/AbstractAsyncExtensionOperation.java new file mode 100644 index 0000000000..21675388d9 --- /dev/null +++ b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/extension/AbstractAsyncExtensionOperation.java @@ -0,0 +1,35 @@ +/* + * 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.ode.bpel.runtime.extension; + +import org.apache.ode.bpel.common.FaultException; +import org.apache.ode.bpel.eapi.ExtensionContext; +import org.apache.ode.bpel.eapi.ExtensionOperation; + +/** + * Base class for creating new asynchronous extension implementations. + * + * @author Tammo van Lessen (University of Stuttgart) + */ +public abstract class AbstractAsyncExtensionOperation implements ExtensionOperation { + + public abstract void run(ExtensionContext context, String element) + throws FaultException; + +} \ No newline at end of file diff --git a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/extension/AbstractSyncExtensionOperation.java b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/extension/AbstractSyncExtensionOperation.java new file mode 100644 index 0000000000..3e463ad272 --- /dev/null +++ b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/extension/AbstractSyncExtensionOperation.java @@ -0,0 +1,46 @@ +/* + * 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.ode.bpel.runtime.extension; + +import org.apache.ode.bpel.common.FaultException; +import org.apache.ode.bpel.eapi.ExtensionContext; +import org.apache.ode.bpel.eapi.ExtensionOperation; +import org.w3c.dom.Element; + +/** + * Base class for creating new extension implementations. + * + * @author Tammo van Lessen (University of Stuttgart) + */ +public abstract class AbstractSyncExtensionOperation implements ExtensionOperation { + + protected abstract void runSync(ExtensionContext context, Element element) throws FaultException; + + public void run(ExtensionContext context, Element element) + throws FaultException { + try { + runSync(context, element); + context.complete(); + } catch (FaultException f) { + context.completeWithFault(f); + } catch (Exception e) { + context.completeWithFault(e); + } + } +} \ No newline at end of file diff --git a/bpel-runtime/src/test/java/org/apache/ode/bpel/runtime/CoreBpelTest.java b/bpel-runtime/src/test/java/org/apache/ode/bpel/runtime/CoreBpelTest.java index aa3a871a92..afc6d9e3a5 100644 --- a/bpel-runtime/src/test/java/org/apache/ode/bpel/runtime/CoreBpelTest.java +++ b/bpel-runtime/src/test/java/org/apache/ode/bpel/runtime/CoreBpelTest.java @@ -28,13 +28,11 @@ import javax.wsdl.Operation; import javax.xml.namespace.QName; -import junit.framework.TestCase; - import org.apache.ode.bpel.common.CorrelationKey; import org.apache.ode.bpel.common.FaultException; +import org.apache.ode.bpel.eapi.ExtensionOperation; import org.apache.ode.bpel.evar.ExternalVariableModuleException; import org.apache.ode.bpel.evt.ProcessInstanceEvent; -import org.apache.ode.bpel.eapi.ExtensionContext; import org.apache.ode.bpel.iapi.ProcessConf.PartnerRoleConfig; import org.apache.ode.bpel.obj.OCatch; import org.apache.ode.bpel.obj.OEmpty; @@ -49,7 +47,6 @@ import org.apache.ode.bpel.obj.OSequence; import org.apache.ode.bpel.obj.OThrow; import org.apache.ode.bpel.runtime.channels.ActivityRecovery; -import org.apache.ode.bpel.runtime.channels.ExtensionResponse; import org.apache.ode.bpel.runtime.channels.FaultData; import org.apache.ode.bpel.runtime.channels.InvokeResponse; import org.apache.ode.bpel.runtime.channels.PickResponse; @@ -59,6 +56,8 @@ import org.w3c.dom.Element; import org.w3c.dom.Node; +import junit.framework.TestCase; + /** * Test core BPEL processing capabilities. */ @@ -482,9 +481,8 @@ public void forceFlush() { public void checkInvokeExternalPermission() {} - public void executeExtension(QName extensionId, ExtensionContext context, Element element, - ExtensionResponse extResponseChannel) throws FaultException { + public ExtensionOperation createExtensionActivityImplementation(QName name) { // TODO Auto-generated method stub - + return null; } } diff --git a/bpel-test/src/main/java/org/apache/ode/test/MockExtensionContext.java b/bpel-test/src/main/java/org/apache/ode/test/MockExtensionContext.java new file mode 100644 index 0000000000..07b9eb8a54 --- /dev/null +++ b/bpel-test/src/main/java/org/apache/ode/test/MockExtensionContext.java @@ -0,0 +1,106 @@ +/* + * 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.ode.test; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.ode.bpel.common.FaultException; +import org.apache.ode.bpel.eapi.ExtensionContext; +import org.apache.ode.bpel.obj.OActivity; +import org.apache.ode.bpel.obj.OProcess.OProperty; +import org.apache.ode.bpel.obj.OScope.Variable; +import org.apache.ode.bpel.runtime.BpelRuntimeContext; +import org.apache.ode.utils.DOMUtils; +import org.w3c.dom.Node; + +/** + * Very simple mock implementation of the ExtensionContext interface. + * + * @author Tammo van Lessen (University of Stuttgart) + */ +public class MockExtensionContext implements ExtensionContext { + private Map variables = new HashMap(); + public boolean completed; + public boolean faulted; + + public Map getVariables() { + return variables; + } + + public Long getProcessId() { + return 0L; + } + + public Node readVariable(String variableName) throws FaultException { + System.out.println("Reading " + variableName); + return variables.get(variableName); + } + + public void writeVariable(String variableName, Node value) + throws FaultException { + variables.put(variableName, value); + System.out.println("Storing in " + variableName + ": " + DOMUtils.domToString(value)); + } + + public String getActivityName() { + return "mockActivity"; + } + + public OActivity getOActivity() { + throw new UnsupportedOperationException("This method is not available in this mock implementation."); + } + + public BpelRuntimeContext getBpelRuntimeContext() { + throw new UnsupportedOperationException("This method is not available in this mock implementation."); + } + + public Map getVisibleVariables() + throws FaultException { + throw new UnsupportedOperationException("This method is not available in this mock implementation."); + } + + public String readMessageProperty(Variable variable, OProperty property) + throws FaultException { + throw new UnsupportedOperationException("This method is not available in this mock implementation."); + } + + public Node readVariable(Variable variable) throws FaultException { + throw new UnsupportedOperationException("This method is not available in this mock implementation."); + } + + public void writeVariable(Variable variable, Node value) throws FaultException { + throw new UnsupportedOperationException("This method is not available in this mock implementation."); + } + + public void complete() { + this.completed = true; + } + + public void completeWithFault(Throwable t) { + this.completed = true; + this.faulted = true; + } + + public void completeWithFault(FaultException fault) { + this.completed = true; + this.faulted = true; + } + +} \ No newline at end of file diff --git a/bpel-test/src/test/java/org/apache/ode/test/ExtensibilityTest.java b/bpel-test/src/test/java/org/apache/ode/test/ExtensibilityTest.java new file mode 100644 index 0000000000..5fc5e9716a --- /dev/null +++ b/bpel-test/src/test/java/org/apache/ode/test/ExtensibilityTest.java @@ -0,0 +1,146 @@ +/* + * 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.ode.test; + +import org.apache.ode.bpel.common.FaultException; +import org.apache.ode.bpel.compiler.api.CompilationException; +import org.apache.ode.bpel.eapi.AbstractExtensionBundle; +import org.apache.ode.bpel.eapi.ExtensionContext; +import org.apache.ode.bpel.eapi.ExtensionOperation; +import org.apache.ode.bpel.iapi.ContextException; +import org.apache.ode.utils.DOMUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.w3c.dom.Element; + +/** + * Test ODE's extensibility + * @author Tammo van Lessen (University of Stuttgart) + */ +public class ExtensibilityTest extends BPELTestAbstract { + + private TestExtensionBundle teb; + + @Before + public void setUp() throws Exception { + super.setUp(); + teb = new TestExtensionBundle(); + //BasicConfigurator.configure(); + } + + @Test public void testExtensionActivityWOMustUnderstandWOBundle() throws Throwable { + go("/bpel/2.0/TestExtensionActivity"); + } + + @Test public void testExtensionActivityWithMustUnderstandWOBundle() throws Throwable { + Deployment deployment = new Deployment(makeDeployDir("/bpel/2.0/TestExtensionActivityMustUnderstand")); + deployment.expectedException = ContextException.class; + doDeployment(deployment); + } + + @Test public void testExtensionActivityWOMustUnderstandWithBundle() throws Throwable { + _server.registerExtensionBundle(teb); + Assert.assertFalse(teb.wasExecuted()); + go("/bpel/2.0/TestExtensionActivity"); + Assert.assertTrue(teb.wasExecuted()); + _server.unregisterExtensionBundle(teb.getNamespaceURI()); + teb.recycle(); + } + + @Test public void testExtensionActivityWithMustUnderstandWithBundle() throws Throwable { + _server.registerExtensionBundle(teb); + Assert.assertFalse(teb.wasExecuted()); + go("/bpel/2.0/TestExtensionActivityMustUnderstand"); + Assert.assertTrue("ExtensionActivity has not been executed", teb.wasExecuted()); + _server.unregisterExtensionBundle(teb.getNamespaceURI()); + teb.recycle(); + } + + @Test public void testExtensionAssignOperation() throws Throwable { + _server.registerExtensionBundle(teb); + go("/bpel/2.0/TestExtensionAssignOperation"); + _server.unregisterExtensionBundle(teb.getNamespaceURI()); + teb.recycle(); + } + + @Test public void testExtensionActivityCompilerError() throws Throwable { + _server.registerExtensionBundle(teb); + TestExtensionBundle.cmpString = "error"; + go("/bpel/2.0/TestExtensionActivity"); + Deployment deployment = new Deployment(makeDeployDir("/bpel/2.0/TestExtensionActivityMustUnderstand")); + deployment.expectedException = CompilationException.class; + doDeployment(deployment); + _server.unregisterExtensionBundle(teb.getNamespaceURI()); + teb.recycle(); + } + + private static class TestExtensionBundle extends AbstractExtensionBundle { + private static boolean wasExecuted = false; + private static String cmpString = "test"; + + public String getNamespaceURI() { + return "urn:ode:test-extension-bundle"; + } + + public void registerExtensionActivities() { + registerExtensionOperation("doIt", TestExtensionActivity.class); + registerExtensionOperation("doAssign", TestExtensionAssignOperation.class); + } + + public boolean wasExecuted() { + return wasExecuted; + } + + public void recycle() { + wasExecuted = false; + cmpString = "test"; + } + } + + public static class TestExtensionActivity implements ExtensionOperation { + private static final long serialVersionUID = 1L; + + public void run(ExtensionContext context, + Element element) throws FaultException { + TestExtensionBundle.wasExecuted = true; + context.complete(); + } + } + + public static class TestExtensionAssignOperation implements ExtensionOperation { + private static final long serialVersionUID = 1L; + + public void run(ExtensionContext context, Element element) + throws FaultException { + //Node val = context.readVariable("myVar"); + StringBuffer sb = new StringBuffer("\n"); + sb.append("Small"); + try { + context.writeVariable("tmpVar", DOMUtils.stringToDOM(sb.toString())); + } catch (Exception e) { + e.printStackTrace(); + Assert.fail(); + } finally { + context.complete(); + } + } + } + +} \ No newline at end of file diff --git a/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivity/ExtensionActivity.bpel b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivity/ExtensionActivity.bpel new file mode 100644 index 0000000000..5fec847770 --- /dev/null +++ b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivity/ExtensionActivity.bpel @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + concat($tmpVar,' World')" + + + + + + + + + + + test + + + + + + diff --git a/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivity/ExtensionActivity.wsdl b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivity/ExtensionActivity.wsdl new file mode 100644 index 0000000000..b54f59d978 --- /dev/null +++ b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivity/ExtensionActivity.wsdl @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivity/deploy.xml b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivity/deploy.xml new file mode 100644 index 0000000000..0d8dce06d8 --- /dev/null +++ b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivity/deploy.xml @@ -0,0 +1,12 @@ + + + + + true + + + + + diff --git a/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivity/test.properties b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivity/test.properties new file mode 100644 index 0000000000..a3fc416f47 --- /dev/null +++ b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivity/test.properties @@ -0,0 +1,6 @@ +namespace=http://ode/bpel/unit-test.wsdl +service=HelloService +operation=hello +request1=Hello +response1=.*Hello World.* + diff --git a/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivityMustUnderstand/ExtensionActivity.bpel b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivityMustUnderstand/ExtensionActivity.bpel new file mode 100644 index 0000000000..9998b8758a --- /dev/null +++ b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivityMustUnderstand/ExtensionActivity.bpel @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + concat($tmpVar,' World')" + + + + + + + + + diff --git a/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivityMustUnderstand/ExtensionActivity.wsdl b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivityMustUnderstand/ExtensionActivity.wsdl new file mode 100644 index 0000000000..47ecbe4cd0 --- /dev/null +++ b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivityMustUnderstand/ExtensionActivity.wsdl @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivityMustUnderstand/deploy.xml b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivityMustUnderstand/deploy.xml new file mode 100644 index 0000000000..17065ee676 --- /dev/null +++ b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivityMustUnderstand/deploy.xml @@ -0,0 +1,12 @@ + + + + + true + + + + + diff --git a/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivityMustUnderstand/test.properties b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivityMustUnderstand/test.properties new file mode 100644 index 0000000000..a3fc416f47 --- /dev/null +++ b/bpel-test/src/test/resources/bpel/2.0/TestExtensionActivityMustUnderstand/test.properties @@ -0,0 +1,6 @@ +namespace=http://ode/bpel/unit-test.wsdl +service=HelloService +operation=hello +request1=Hello +response1=.*Hello World.* + diff --git a/bpel-test/src/test/resources/bpel/2.0/TestExtensionAssignOperation/ExtensionAssign.bpel b/bpel-test/src/test/resources/bpel/2.0/TestExtensionAssignOperation/ExtensionAssign.bpel new file mode 100644 index 0000000000..a3624ba37a --- /dev/null +++ b/bpel-test/src/test/resources/bpel/2.0/TestExtensionAssignOperation/ExtensionAssign.bpel @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + concat($tmpVar,' World')" + + + + + + diff --git a/bpel-test/src/test/resources/bpel/2.0/TestExtensionAssignOperation/ExtensionAssign.wsdl b/bpel-test/src/test/resources/bpel/2.0/TestExtensionAssignOperation/ExtensionAssign.wsdl new file mode 100644 index 0000000000..5c268b8d70 --- /dev/null +++ b/bpel-test/src/test/resources/bpel/2.0/TestExtensionAssignOperation/ExtensionAssign.wsdl @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bpel-test/src/test/resources/bpel/2.0/TestExtensionAssignOperation/deploy.xml b/bpel-test/src/test/resources/bpel/2.0/TestExtensionAssignOperation/deploy.xml new file mode 100644 index 0000000000..cf13758d16 --- /dev/null +++ b/bpel-test/src/test/resources/bpel/2.0/TestExtensionAssignOperation/deploy.xml @@ -0,0 +1,12 @@ + + + + + true + + + + + diff --git a/bpel-test/src/test/resources/bpel/2.0/TestExtensionAssignOperation/test.properties b/bpel-test/src/test/resources/bpel/2.0/TestExtensionAssignOperation/test.properties new file mode 100644 index 0000000000..9dea7eb20e --- /dev/null +++ b/bpel-test/src/test/resources/bpel/2.0/TestExtensionAssignOperation/test.properties @@ -0,0 +1,6 @@ +namespace=http://ode/bpel/unit-test.wsdl +service=HelloService +operation=hello +request1=Hello +response1=.*Small World.* +