All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.ode.bpel.engine.IMAManager Maven / Gradle / Ivy

There is a newer version: 1.3.5-wso4v18
Show newest version
/*
 * 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.engine;

import org.apache.ode.bpel.runtime.PartnerLinkInstance;
import org.apache.ode.bpel.runtime.Selector;
import org.apache.ode.utils.ObjectPrinter;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.wsdl.OperationType;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 

* This class handles behaviour of IMAs (Inbound Message Activities) as specified in WS BPEL. * This includes detecting conflictingReceive and conflictingRequest faults. *

*/ public class IMAManager implements Serializable { private static final long serialVersionUID = -5556374398943757951L; private static final Log __log = LogFactory.getLog(IMAManager.class); // holds rid for registered IMAs public final Map _byRid = new HashMap(); // holds outstanding rid that are now waiting to reply (Open IMAs) public final Map _byOrid = new HashMap(); public final Map _byChannel = new HashMap(); /** * finds conflictingReceive * * @param selectors * @return */ int findConflict(Selector selectors[]) { if (__log.isTraceEnabled()) { __log.trace(ObjectPrinter.stringifyMethodEnter("findConflict", new Object[] { "selectors", selectors })); } Set workingSet = new HashSet(_byRid.keySet()); for (int i = 0; i < selectors.length; ++i) { final RequestIdTuple rid = new RequestIdTuple(selectors[i].plinkInstance, selectors[i].opName); if (workingSet.contains(rid)) { return i; } workingSet.add(rid); } return -1; } /** * Register IMA * * @param pickResponseChannel * response channel associated with this receive/pick * @param selectors * selectors for this receive/pick */ void register(String pickResponseChannel, Selector selectors[]) { if (__log.isTraceEnabled()) { __log.trace(ObjectPrinter.stringifyMethodEnter("register", new Object[] { "pickResponseChannel", pickResponseChannel, "selectors", selectors })); } if (_byChannel.containsKey(pickResponseChannel)) { String errmsg = "INTERNAL ERROR: Duplicate ENTRY for RESPONSE CHANNEL " + pickResponseChannel; __log.fatal(errmsg); throw new IllegalArgumentException(errmsg); } Entry entry = new Entry(pickResponseChannel, selectors); for (int i = 0; i < selectors.length; ++i) { final RequestIdTuple rid = new RequestIdTuple(selectors[i].plinkInstance, selectors[i].opName); if (_byRid.containsKey(rid)) { String errmsg = "INTERNAL ERROR: Duplicate ENTRY for RID " + rid; __log.fatal(errmsg); throw new IllegalStateException(errmsg); } _byRid.put(rid, entry); } _byChannel.put(pickResponseChannel, entry); } /** * Registers Open IMA. * It doesn't open IMA for non two way operations. * * @param partnerLink * @param opName * @param mexId * @param mexRef * @return */ String processOutstandingRequest(PartnerLinkInstance partnerLink, String opName, String mexId, String mexRef) { if (__log.isTraceEnabled()) { __log.trace(ObjectPrinter.stringifyMethodEnter("process", new Object[] { "partnerLinkInstance", partnerLink, "operationName", opName, "messageExchangeId", mexId, "mexRef", mexRef })); } final OutstandingRequestIdTuple orid = new OutstandingRequestIdTuple(partnerLink, opName, mexId); if (_byOrid.containsKey(orid)) { //conflictingRequest found return mexRef; } // We convert into outstanding request only for in-out operations (pending release operation) if (partnerLink.partnerLink.getMyRoleOperation(opName).getStyle().equals(OperationType.REQUEST_RESPONSE)) { _byOrid.put(orid, mexRef); } return null; } /** * This is used to remove IMA from registered state. * * @see #register(String, Selector[]) * @param pickResponseChannel */ void cancel(String pickResponseChannel, boolean isTimer) { if (__log.isTraceEnabled()) __log.trace(ObjectPrinter.stringifyMethodEnter("cancel", new Object[] { "pickResponseChannel", pickResponseChannel })); Entry entry = _byChannel.remove(pickResponseChannel); if (entry != null) { while (_byRid.values().remove(entry)); } else if (!isTimer){ String errmsg = "INTERNAL ERROR: No ENTRY for RESPONSE CHANNEL " + pickResponseChannel; __log.fatal(errmsg); throw new IllegalArgumentException(errmsg); } } /** * Release Open IMA. * * @param plinkInstnace * partner link * @param opName * operation * @param mexId * message exchange identifier IN THE BPEL SENSE OF THE TERM (i.e. a receive/reply disambiguator). * @return message exchange identifier associated with the registration that matches the parameters */ public String release(PartnerLinkInstance plinkInstnace, String opName, String mexId) { if (__log.isTraceEnabled()) __log.trace(ObjectPrinter.stringifyMethodEnter("release", new Object[] { "plinkInstance", plinkInstnace, "opName", opName, "mexId", mexId })); final OutstandingRequestIdTuple orid = new OutstandingRequestIdTuple(plinkInstnace, opName, mexId); String mexRef = _byOrid.remove(orid); if (mexRef == null) { if (__log.isDebugEnabled()) { __log.debug("==release: ORID " + orid + " not found in " + _byOrid); } return null; } return mexRef; } public void migrateRids(Map oldRids) { for (OutstandingRequestManager.RequestIdTuple oldRid : oldRids.keySet()) { OutstandingRequestManager.Entry oldEntry = oldRids.get(oldRid); if (oldEntry.mexRef != null) { //open IMA OutstandingRequestIdTuple orid = new OutstandingRequestIdTuple(oldRid.partnerLink, oldRid.opName, oldRid.mexId); _byOrid.put(orid, oldEntry.mexRef); } else { //registered IMA RequestIdTuple rid = new RequestIdTuple(oldRid.partnerLink, oldRid.opName); Entry entry = new Entry(oldEntry.pickResponseChannel, (Selector[]) oldEntry.selectors); _byRid.put(rid, entry); _byChannel.put(entry.pickResponseChannel, entry); } } } /** * "Release" all Open IMAs * * @return a list of message exchange identifiers for message exchanges that were begun (receive/pick got a message) but not yet completed (reply not yet sent) */ public String[] releaseAll() { if (__log.isTraceEnabled()) __log.trace(ObjectPrinter.stringifyMethodEnter("releaseAll", null)); ArrayList mexRefs = new ArrayList(); while (!_byOrid.isEmpty()) { String mexRef = _byOrid.entrySet().iterator().next().getValue(); mexRefs.add(mexRef); _byOrid.values().remove(mexRef); } return mexRefs.toArray(new String[mexRefs.size()]); } public String toString() { return ObjectPrinter.toString(this, new Object[] { "byRid", _byRid, "byOrid", _byOrid, "byChannel", _byChannel }); } private class RequestIdTuple implements Serializable { private static final long serialVersionUID = -1059389611839777482L; /** On which partner link it was received. */ PartnerLinkInstance partnerLink; /** Name of the operation. */ String opName; /** Constructor. */ private RequestIdTuple(PartnerLinkInstance partnerLink, String opName) { this.partnerLink = partnerLink; this.opName = opName; } public int hashCode() { return this.partnerLink.hashCode() ^ this.opName.hashCode(); } public boolean equals(Object obj) { RequestIdTuple other = (RequestIdTuple) obj; return other.partnerLink.equals(partnerLink) && other.opName.equals(opName); } public String toString() { return ObjectPrinter.toString(this, new Object[] { "partnerLink", partnerLink, "opName", opName}); } } private class OutstandingRequestIdTuple implements Serializable { private static final long serialVersionUID = -1059389611839777482L; /** On which partner link it was received. */ PartnerLinkInstance partnerLink; /** Name of the operation. */ String opName; /** Message exchange identifier. */ String mexId; /** Constructor. */ private OutstandingRequestIdTuple(PartnerLinkInstance partnerLink, String opName, String mexId) { this.partnerLink = partnerLink; this.opName = opName; this.mexId = mexId == null ? "" : mexId; } public int hashCode() { return this.partnerLink.hashCode() ^ this.opName.hashCode() ^ this.mexId.hashCode(); } public boolean equals(Object obj) { OutstandingRequestIdTuple other = (OutstandingRequestIdTuple) obj; return other.partnerLink.equals(partnerLink) && other.opName.equals(opName) && other.mexId.equals(mexId); } public String toString() { return ObjectPrinter.toString(this, new Object[] { "partnerLink", partnerLink, "opName", opName, "mexId", mexId }); } } public class Entry implements Serializable { private static final long serialVersionUID = -583743124656582887L; final String pickResponseChannel; public Selector[] selectors; private Entry(String pickResponseChannel, Selector[] selectors) { this.pickResponseChannel = pickResponseChannel; this.selectors = selectors; } public String toString() { return ObjectPrinter.toString(this, new Object[] { "pickResponseChannel", pickResponseChannel, "selectors", selectors }); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy