diff options
Diffstat (limited to '')
9 files changed, 495 insertions, 174 deletions
diff --git a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GlobalExceptionAdapter.java b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/ConcurrentExceptionOcurrenceException.java index afbf4ee35e..30584f2d78 100644 --- a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GlobalExceptionAdapter.java +++ b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/ConcurrentExceptionOcurrenceException.java @@ -18,17 +18,21 @@ */ package org.apache.tuscany.sca.guardian; -import javax.xml.bind.annotation.adapters.XmlAdapter; +class ConcurrentExceptionOcurrenceException extends Exception { -public class GlobalExceptionAdapter extends XmlAdapter<GlobalException, GlobalExceptionInterface> { + public ConcurrentExceptionOcurrenceException() { + super(); + } + + public ConcurrentExceptionOcurrenceException(String message) { + super(message); + } - @Override - public GlobalExceptionInterface unmarshal(GlobalException v) { - return v; + public ConcurrentExceptionOcurrenceException(String message, Throwable cause) { + super(message, cause); } - @Override - public GlobalException marshal(GlobalExceptionInterface v) { - return (GlobalException) v; + public ConcurrentExceptionOcurrenceException(Throwable cause) { + super(cause); } } diff --git a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/Constants.java b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/Constants.java index 0396a65c08..9fa4db4f78 100644 --- a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/Constants.java +++ b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/Constants.java @@ -23,38 +23,59 @@ import javax.xml.namespace.QName; public interface Constants { String RECOVERY_RULES = "recovery_rules"; - QName RECOVERY_RULES_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_NS, RECOVERY_RULES); + QName RECOVERY_RULES_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, RECOVERY_RULES); String RULE = "rule"; - QName RULE_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_NS, RULE); + QName RULE_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, RULE); String NAME = "name"; - QName NAME_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_NS, NAME); + QName NAME_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, NAME); String SIGNALED_EXCEPTION = "signaled_exception"; - QName SIGNALED_EXCEPTION_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_NS, SIGNALED_EXCEPTION); + QName SIGNALED_EXCEPTION_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, SIGNALED_EXCEPTION); String PARTICIPANT = "participant"; - QName PARTICIPANT_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_NS, PARTICIPANT); + QName PARTICIPANT_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, PARTICIPANT); String MATCH = "match"; - QName MATCH_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_NS, MATCH); + QName MATCH_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, MATCH); String THROW_EXCEPTION = "throw_exception"; - QName THROW_EXCEPTION_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_NS, THROW_EXCEPTION); + QName THROW_EXCEPTION_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, THROW_EXCEPTION); String CLASS = "class"; - QName CLASS_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_NS, CLASS); + QName CLASS_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, CLASS); String TARGET_CONTEXT = "target_context"; - QName TARGET_CONTEXT_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_NS, TARGET_CONTEXT); + QName TARGET_CONTEXT_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, TARGET_CONTEXT); String MIN_PARTICIPANT_JOINED = "min_participant_joined"; - QName MIN_PARTICIPANT_JOINED_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_NS, MIN_PARTICIPANT_JOINED); + QName MIN_PARTICIPANT_JOINED_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, MIN_PARTICIPANT_JOINED); String MAX_PARTICIPANT_JOINED = "max_participant_joined"; - QName MAX_PARTICIPANT_JOINED_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_NS, MAX_PARTICIPANT_JOINED); + QName MAX_PARTICIPANT_JOINED_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, MAX_PARTICIPANT_JOINED); String AFFECTED_PARTICIPANTS = "affected_participants"; - QName AFFECTED_PARTICIPANTS_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_NS, AFFECTED_PARTICIPANTS); + QName AFFECTED_PARTICIPANTS_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, AFFECTED_PARTICIPANTS); + + String FIRST = "FIRST"; + QName FIRST_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, FIRST); + + String LAST = "LAST"; + QName LAST_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, LAST); + + String ALL = "ALL"; + QName ALL_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, ALL); + + String RESOLUTION_TREE = "resolution_tree"; + QName RESOLUTION_TREE_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, RESOLUTION_TREE); + + String RESOLUTION_TREES = "resolution_trees"; + QName RESOLUTION_TREES_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, RESOLUTION_TREES); + + String EXCEPTION_LEVEL = "exception_level"; + QName EXCEPTION_LEVEL_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, EXCEPTION_LEVEL); + + String EXCEPTION = "exception"; + QName EXCEPTION_QNAME = new QName(org.apache.tuscany.sca.assembly.xml.Constants.SCA10_TUSCANY_NS, EXCEPTION); } diff --git a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/Context.java b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/Context.java index 9385ade12a..3ac5d63a42 100644 --- a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/Context.java +++ b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/Context.java @@ -25,6 +25,8 @@ public class Context { public static Context CURRENT_CONTEXT = new Context("CURRENT_CONTEXT"); public static Context INIT_CONTEXT = new Context("INIT_CONTEXT"); + public static Context GUARDIAN_CONTEXT = new Context("GUARDIAN_CONTEXT"); + private String name; private List<Class<? extends GlobalException>> exceptionList; diff --git a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GlobalException.java b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GlobalException.java index c2e999a8ed..b880db6aa1 100644 --- a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GlobalException.java +++ b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GlobalException.java @@ -18,30 +18,33 @@ */ package org.apache.tuscany.sca.guardian; +import java.util.LinkedList; +import java.util.List; + public class GlobalException extends RuntimeException implements GlobalExceptionInterface { + private List<String> signalingParticipants; private Context signalingContext; - private Context targetContext; //Assigned by the recovery rules - private String signalingParticipant; - - public GlobalException(Context targetContext) { - this.targetContext = targetContext; - } + private Context targetContext; public GlobalException() { super(); + signalingParticipants = new LinkedList<String>(); } public GlobalException(String message) { super(message); + signalingParticipants = new LinkedList<String>(); } public GlobalException(String message, Throwable cause) { super(message, cause); + signalingParticipants = new LinkedList<String>(); } public GlobalException(Throwable cause) { super(cause); + signalingParticipants = new LinkedList<String>(); } /** @@ -72,17 +75,11 @@ public class GlobalException extends RuntimeException implements GlobalException this.targetContext = targetContext; } - /** - * @return the signalingProcess - */ - public String getSignalingParticipant() { - return signalingParticipant; + public void putSignalingParticipant(String participant) { + signalingParticipants.add(participant); } - /** - * @param signalingProcess the signalingProcess to set - */ - public void setSignalingParticipant(String signalingProcess) { - this.signalingParticipant = signalingProcess; + public List<String> getSignalingParticipants() { + return signalingParticipants; } } diff --git a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GlobalExceptionInterface.java b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GlobalExceptionInterface.java index 35e8a1d236..68a09a9bc8 100644 --- a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GlobalExceptionInterface.java +++ b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GlobalExceptionInterface.java @@ -18,6 +18,8 @@ */ package org.apache.tuscany.sca.guardian; +import java.util.List; + public interface GlobalExceptionInterface { /** @@ -43,10 +45,10 @@ public interface GlobalExceptionInterface { /** * @return the signalingProcess */ - public String getSignalingParticipant(); + public List<String> getSignalingParticipants(); /** * @param signalingProcess the signalingProcess to set */ - public void setSignalingParticipant(String signalingProcess); + public void putSignalingParticipant(String participant); } diff --git a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GuardianGroupImpl.java b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GuardianGroupImpl.java index 1168f7406c..c8964f2b98 100644 --- a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GuardianGroupImpl.java +++ b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GuardianGroupImpl.java @@ -18,15 +18,22 @@ */ package org.apache.tuscany.sca.guardian; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.policy.resolutiontrees.ResolutionTreesPolicyProcessor; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.lang.annotation.Annotation; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; +import org.apache.axiom.om.OMAttribute; +import org.apache.axiom.om.OMElement; import org.apache.axis2.jaxws.message.util.ResettableReader; import org.osoa.sca.annotations.Property; import org.osoa.sca.annotations.Scope; @@ -37,9 +44,10 @@ import org.osoa.sca.annotations.Service; public class GuardianGroupImpl implements GuardianGroup { private List<GuardianMember> guardianList; - private ResettableReader reader; + private ResettableReader recoveryRulesReader; private InnerGuardianGroupThread innerThread; private List<GlobalExceptionInterface> concurrentExList; + private Map<String, OMElement> resolutionTreeElements; public GuardianGroupImpl() { guardianList = new LinkedList<GuardianMember>(); @@ -52,7 +60,26 @@ public class GuardianGroupImpl implements GuardianGroup { try { FileInputStream fileInputStream = new FileInputStream(recoveryRules); XMLStreamReader xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(fileInputStream); - reader = new ResettableReader(xmlReader); + recoveryRulesReader = new ResettableReader(xmlReader); + } catch (XMLStreamException ex) { + Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex); + } catch (FileNotFoundException ex) { + Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex); + } + } + + @Property(name = "resolution_tree", required = false) + public void setResolutionTree(String resolutionTree) { + + try { + FileInputStream fileInputStream = new FileInputStream(resolutionTree); + XMLStreamReader resolutionTreeReader = XMLInputFactory.newInstance().createXMLStreamReader(fileInputStream); + + ResolutionTreesPolicyProcessor processor = new ResolutionTreesPolicyProcessor(null, null); + resolutionTreeElements = processor.read(resolutionTreeReader).getResolutionTreeElements(); + + } catch (ContributionReadException ex) { + Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex); } catch (XMLStreamException ex) { Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex); } catch (FileNotFoundException ex) { @@ -76,40 +103,26 @@ public class GuardianGroupImpl implements GuardianGroup { public synchronized void gthrow(GlobalExceptionInterface ex, List<String> participantList) { - //1)Ivoked by a GuardianMember instance through the gthrow method - //2)Notify all participants about the exception (FIFO atomic broadcast model) - it will cause the suspension of all participants - // 2.1)Invoke the gthrow of the guardian members associated with the participants on participantList - concurrentExList.add(ex); //Sends a message representing the exception to the other guardian members SuspendException suspendEx = new SuspendException(); + suspendEx.putSignalingParticipant(ex.getSignalingParticipants().get(0)); + if (participantList == null) { for (GuardianMember g : guardianList) { g.gthrow(suspendEx, null); } } else { for (GuardianMember g : guardianList) { - if (participantList.contains(g.getParticipantIdentifier())) { + if (participantList.contains(g.getParticipantIdentifier()) || + g.getParticipantIdentifier().equals(ex.getSignalingParticipants().get(0))) { g.gthrow(suspendEx, null); - //g.gthrow(suspendEx,null); -> g is the signler } } } -// //3)Once ALL required participants are SUSPENDED (suspended point), invoke the defined Recovery Rules -// for (GuardianMember g : guardianList) { -// g.addException(new SuspendException()); -// } - // 3.1) recovery_rules < signaled exceptions + context information of all participant > target context + exception to raise - - //Simpleste Recovery Rule: broadcast the exception for all participants - FIXME: hardcoded -// for (GuardianMemberImpl g : guardianMembers) { -// ex.setTargetContext(Context.CURRENT_CONTEXT); -// g.addException(ex); -// } - - if (!innerThread.isRunning) { + if (!innerThread.isRunning()) { innerThread.setGlobalException(ex); new Thread(innerThread).start(); } @@ -145,10 +158,27 @@ public class GuardianGroupImpl implements GuardianGroup { } public void run() { + isRunning = true; + if (ex != null) { - isRunning = true; - applyRecoveryRules(ex); + //Time window of 10 seconds just for tests + try { + Thread.sleep(10000); + } catch (InterruptedException ex1) { + Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex1); + } + + try { + applyRecoveryRules(ex); + } catch (ConcurrentExceptionOcurrenceException ce) { + applyConcurrentRecoveryRules(); + } + + //Clear the concurrent exception list + concurrentExList.clear(); + + //Set up the participant state to NORMAL for (GuardianMember gm : guardianList) { if (gm.getParticipantState() == SUSPENDED_PARTICIPANT_STATE) { gm.setParticipantState(NORMAL_PARTICIPANT_STATE); @@ -162,20 +192,20 @@ public class GuardianGroupImpl implements GuardianGroup { return isRunning; } - private void applyRecoveryRules(GlobalExceptionInterface ex) { - reader.reset(); + private void applyRecoveryRules(GlobalExceptionInterface ex) throws ConcurrentExceptionOcurrenceException { + recoveryRulesReader.reset(); ruleTag(ex); } - private void ruleTag(GlobalExceptionInterface ex) { + private void ruleTag(GlobalExceptionInterface ex) throws ConcurrentExceptionOcurrenceException { try { - while (reader.hasNext()) { - reader.next(); + while (recoveryRulesReader.hasNext()) { + recoveryRulesReader.next(); //<rule name="" signaled_exception=""> - if (reader.isStartElement() && reader.getLocalName().equals("rule")) { - for (int i = 0; i < reader.getAttributeCount(); i++) { + if (recoveryRulesReader.isStartElement() && recoveryRulesReader.getLocalName().equals(Constants.RULE)) { + for (int i = 0; i < recoveryRulesReader.getAttributeCount(); i++) { //ex == signaled_exception - if (reader.getAttributeLocalName(i).equals("signaled_exception") && ex.getClass().getName().equals(reader.getAttributeValue(i))) { + if (recoveryRulesReader.getAttributeLocalName(i).equals(Constants.SIGNALED_EXCEPTION) && ex.getClass().getName().equals(recoveryRulesReader.getAttributeValue(i))) { participantExceptionTag(ex); break; } @@ -187,17 +217,23 @@ public class GuardianGroupImpl implements GuardianGroup { } } - private void participantExceptionTag(GlobalExceptionInterface ex) { + private void participantExceptionTag(GlobalExceptionInterface ex) throws ConcurrentExceptionOcurrenceException { List<GuardianMember> gmList; try { - while (reader.hasNext() && !(reader.isEndElement() && reader.getLocalName().equals("rule"))) { - reader.next(); + while (recoveryRulesReader.hasNext() && !(recoveryRulesReader.isEndElement() && recoveryRulesReader.getLocalName().equals(Constants.RULE))) { + recoveryRulesReader.next(); //<participant match="<REG_EXP> | SIGNALER"> - if (reader.isStartElement() && reader.getLocalName().equals("participant")) { - String participantMatch = reader.getAttributeValue(0).trim(); + if (recoveryRulesReader.isStartElement() && recoveryRulesReader.getLocalName().equals(Constants.PARTICIPANT)) { + String participantMatch = recoveryRulesReader.getAttributeValue(0).trim(); gmList = getMatchingParticipants(participantMatch, ex); + //TESTING-------------------------------------------- + for (GuardianMember gm : gmList) { + System.out.println(gm.getParticipantIdentifier()); + } + //--------------------------------------------------- + if (!gmList.isEmpty()) { throwExceptionTag(gmList, ex); } @@ -208,7 +244,7 @@ public class GuardianGroupImpl implements GuardianGroup { } } - private void throwExceptionTag(List<GuardianMember> gmList, GlobalExceptionInterface ex) { + private void throwExceptionTag(List<GuardianMember> gmList, GlobalExceptionInterface ex) throws ConcurrentExceptionOcurrenceException { String exceptionClassName; String targetContextName; @@ -217,29 +253,29 @@ public class GuardianGroupImpl implements GuardianGroup { try { - while (reader.hasNext() && !(reader.isEndElement() && reader.getLocalName().equals("participant"))) { - reader.next(); + while (recoveryRulesReader.hasNext() && !(recoveryRulesReader.isEndElement() && recoveryRulesReader.getLocalName().equals(Constants.PARTICIPANT))) { + recoveryRulesReader.next(); //<throw_exception class="<Exception>" target_context="<Context>"/> - if (reader.isStartElement() && reader.getLocalName().equals("throw_exception")) { + if (recoveryRulesReader.isStartElement() && recoveryRulesReader.getLocalName().equals(Constants.THROW_EXCEPTION)) { exceptionClassName = null; targetContextName = null; min_participant_joined = null; max_participant_joined = null; - for (int j = 0; j < reader.getAttributeCount(); j++) { - if (reader.getAttributeLocalName(j).equals("class")) { + for (int j = 0; j < recoveryRulesReader.getAttributeCount(); j++) { + if (recoveryRulesReader.getAttributeLocalName(j).equals(Constants.CLASS)) { //class value - exceptionClassName = reader.getAttributeValue(j); - } else if (reader.getAttributeLocalName(j).equals("target_context")) { + exceptionClassName = recoveryRulesReader.getAttributeValue(j); + } else if (recoveryRulesReader.getAttributeLocalName(j).equals(Constants.TARGET_CONTEXT)) { //target_context value - targetContextName = reader.getAttributeValue(j); - } else if (reader.getAttributeLocalName(j).equals("min_participant_joined")) { + targetContextName = recoveryRulesReader.getAttributeValue(j); + } else if (recoveryRulesReader.getAttributeLocalName(j).equals(Constants.MIN_PARTICIPANT_JOINED)) { //min_participant_joined value - min_participant_joined = Integer.parseInt(reader.getAttributeValue(j)); + min_participant_joined = Integer.parseInt(recoveryRulesReader.getAttributeValue(j)); } else { //max_participant_joined value - max_participant_joined = Integer.parseInt(reader.getAttributeValue(j)); + max_participant_joined = Integer.parseInt(recoveryRulesReader.getAttributeValue(j)); } } @@ -282,28 +318,22 @@ public class GuardianGroupImpl implements GuardianGroup { newException.setTargetContext(targetContext); newException.setSignalingContext(ex.getSignalingContext()); - newException.setSignalingParticipant(ex.getSignalingParticipant()); - -// //Time window of 10 seconds -// try { -// Thread.sleep(10000); -// } catch (InterruptedException ex1) { -// Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex1); -// } -// //Check concurrent exception existence -// if (concurrentExList.size() != 1) { -// applyConcurrentRecoveryRules(concurrentExList); -// } + newException.putSignalingParticipant(ex.getSignalingParticipants().toString()); + + //Check concurrent exception existence + if (concurrentExList.size() > 1) { + throw new ConcurrentExceptionOcurrenceException(concurrentExList.toString()); + } //Add the exception to the participants matched if (index != -1) { gmList.get(index).addException(newException); } else if (affectedParticipants != null && affectedParticipants.length() != 0) { - if (affectedParticipants.toUpperCase().equals("FIRST")) { + if (affectedParticipants.toUpperCase().equals(Constants.FIRST)) { gmList.get(0).addException(newException); - } else if (affectedParticipants.toUpperCase().equals("LAST")) { + } else if (affectedParticipants.toUpperCase().equals(Constants.LAST)) { gmList.get(gmList.size() - 1).addException(newException); - } else if (affectedParticipants.toUpperCase().equals("ALL")) { + } else if (affectedParticipants.toUpperCase().equals(Constants.ALL)) { for (GuardianMember gm : gmList) { gm.addException(newException); } @@ -329,11 +359,11 @@ public class GuardianGroupImpl implements GuardianGroup { private String affectedParticipantsTag() { String affectedParticipants = null; try { - while (reader.hasNext() && !(reader.isEndElement() && reader.getLocalName().equals("throw_exception"))) { - reader.next(); + while (recoveryRulesReader.hasNext() && !(recoveryRulesReader.isEndElement() && recoveryRulesReader.getLocalName().equals(Constants.THROW_EXCEPTION))) { + recoveryRulesReader.next(); //<affected_participants> - if (reader.isStartElement() && reader.getLocalName().equals("affected_participants")) { - affectedParticipants = reader.getElementText(); + if (recoveryRulesReader.isStartElement() && recoveryRulesReader.getLocalName().equals(Constants.AFFECTED_PARTICIPANTS)) { + affectedParticipants = recoveryRulesReader.getElementText(); } } } catch (XMLStreamException ex) { @@ -343,43 +373,289 @@ public class GuardianGroupImpl implements GuardianGroup { return affectedParticipants; } - private void applyConcurrentRecoveryRules(List<GlobalExceptionInterface> exceptionList) { - System.out.println("CONCURRENT RECOVERY RULES!"); - System.out.println("exceptions: "+exceptionList); - exceptionList.clear(); + private void applyConcurrentRecoveryRules() { + + boolean concurrentExOcurrence = false; + List<GlobalExceptionInterface> copyConcurrentExList; + GlobalExceptionInterface resolvedEx; + + do { + System.out.println("Concurrent exceptions: " + concurrentExList); + + copyConcurrentExList = new LinkedList(concurrentExList); + + resolvedEx = checkExceptionResolutionTrees(copyConcurrentExList, resolutionTreeElements.values().iterator()); + + concurrentExList.clear(); + + System.out.println("Resolved Exception: " + resolvedEx); + if (resolvedEx != null) { + System.out.println("List of participants: " + resolvedEx.getSignalingParticipants()); + } + + try { + //Process the exception list sequentially + if (resolvedEx == null) { + for (GlobalExceptionInterface ex : copyConcurrentExList) { + applyRecoveryRules(ex); + } + } else { + applyRecoveryRules(resolvedEx); + } + + } catch (ConcurrentExceptionOcurrenceException exc) { + concurrentExOcurrence = true; + break; + } + } while (concurrentExOcurrence); + } + + //FIXME: Need to check the exception level + private GlobalExceptionInterface checkExceptionResolutionTrees(List<GlobalExceptionInterface> exceptionList, Iterator resolutionTreesElements) { + + OMElement tree; + String exceptionLevel = null; + GlobalExceptionInterface resolvedEx = null; + + while (resolutionTreesElements.hasNext()) { + tree = (OMElement) resolutionTreesElements.next(); + exceptionLevel = tree.getAttributeValue(Constants.EXCEPTION_LEVEL_QNAME); + + resolvedEx = checkExceptionResolutionTree(exceptionList, tree.getChildElements(), new WrapperInteger(exceptionList.size())); + + if (resolvedEx != null) { + break; + } + } + + return resolvedEx; + } + + //Search for the root of the smallest subtree that contains all the concurrently signaled exceptions. If not found, return null. + //FIXME: Check for equal exception classes on the tree + //FIXME: Implement the Lowest common ancestor algorithm + private GlobalExceptionInterface checkExceptionResolutionTree(List<GlobalExceptionInterface> exceptionList, Iterator elements, WrapperInteger currentListSize) { + + OMElement el; + OMAttribute at; + String exClass = null; + GlobalExceptionInterface resolvedEx = null; + boolean isLeaf = false; + + while (elements.hasNext()) { + el = (OMElement) elements.next(); + + //<exception class=""> + if (el.getLocalName().equals(Constants.EXCEPTION)) { + + Iterator it = el.getAllAttributes(); + while (it.hasNext()) { + at = (OMAttribute) it.next(); + if (at.getLocalName().equals(Constants.CLASS)) { + exClass = at.getAttributeValue(); + } + } + + try { + for (GlobalExceptionInterface ex : exceptionList) { + if (Class.forName(exClass).equals(ex.getClass())) { + currentListSize.decrement(); + break; + } + } + + } catch (ClassNotFoundException ex1) { + Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex1); + } + + Iterator children = el.getChildElements(); + if (children.hasNext()) { + resolvedEx = checkExceptionResolutionTree(exceptionList, children, currentListSize); + } else { + isLeaf = true; + } + } + } + + if (resolvedEx == null && currentListSize.getValue() == 0 && !isLeaf) { + Class exceptionClass; + + try { + exceptionClass = Class.forName(exClass); + resolvedEx = (GlobalException) exceptionClass.newInstance(); + + for (GlobalExceptionInterface ex : exceptionList) { + resolvedEx.putSignalingParticipant(ex.getSignalingParticipants().get(0)); + } + + } catch (InstantiationException ex) { + Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex); + } catch (ClassNotFoundException ex) { + Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex); + } + } + return resolvedEx; } private List<GuardianMember> getMatchingParticipants(String regularExpression, GlobalExceptionInterface signaledException) { List<GuardianMember> matchingParticipants = new LinkedList(); + String[] splitByComma = regularExpression.split(","); - if (regularExpression.toUpperCase().equals("SIGNALER")) { - for (GuardianMember gm : guardianList) { - if (gm.getParticipantIdentifier().equals(signaledException.getSignalingParticipant())) { - matchingParticipants.add(gm); + //Invalid regular expression + if (splitByComma.length > 2) { + throw new InvalidRegularExpression("The comma ',' operator can only be applied for two expressions"); + } + + //There is no comma on the regular expression + if (splitByComma.length == 1) { + + if (regularExpression.toUpperCase().equals("SIGNALER")) { + for (GuardianMember gm : guardianList) { + if (signaledException.getSignalingParticipants().contains(gm.getParticipantIdentifier())) { + matchingParticipants.add(gm); + } + + /*//All concurrent signaler were found + if (matchingParticipants.size() == signaledException.getSignalingParticipants().size()) { break; + }*/ + } + } else if (regularExpression.toUpperCase().equals("!SIGNALER")) { + for (GuardianMember gm : guardianList) { + if (!signaledException.getSignalingParticipants().contains(gm.getParticipantIdentifier())) { + //if (!gm.getParticipantIdentifier().equals(signaledException.getSignalingParticipant())) { + matchingParticipants.add(gm); + } + } + + } else { + //Create an java regular expression + String re = createJavaRegularExpression(regularExpression); + + for (GuardianMember gm : guardianList) { + if (gm.getParticipantIdentifier().matches(re)) { + matchingParticipants.add(gm); + } } } - } else if (regularExpression.toUpperCase().equals("!SIGNALER")) { - for (GuardianMember gm : guardianList) { - if (!gm.getParticipantIdentifier().equals(signaledException.getSignalingParticipant())) { - matchingParticipants.add(gm); + + } //There is comma on the regular expression + else { + + String element; + int index = -1; + for (int i = 0; i < splitByComma.length; i++) { + element = splitByComma[i].toUpperCase(); + if (element.equals("SIGNALER") || element.equals("!SIGNALER")) { + if (index == -1) { + index = i; + } else { + index = -1; + } } } - } else { - //Create an java regular expression - String re = createJavaRegularExpression(regularExpression); + //Invalid expression + if (index == -1) { + throw new InvalidRegularExpression("The comma ',' requires a SIGNALER or !SIGNALER element in one side of the expression"); + } + + String re = createJavaRegularExpression(splitByComma[1 - index]); for (GuardianMember gm : guardianList) { + + //Test if the participant matches with the regular expression if (gm.getParticipantIdentifier().matches(re)) { - matchingParticipants.add(gm); + + //Test if the participant is Signaler + if (splitByComma[index].toUpperCase().equals("SIGNALER")) { + + if (signaledException.getSignalingParticipants().contains(gm.getParticipantIdentifier())) { + matchingParticipants.add(gm); + } + + /*//All concurrent signaler were found + if (matchingParticipants.size() == signaledException.getSignalingParticipants().size()) { + break; + }*/ + +// //ConcurrentGlobalException: there are more than one signaler +// if (signaledException instanceof ConcurrentGlobalException) { +// List<String> signalingPartcipants = ((ConcurrentGlobalException) signaledException).getSignalingParticipants(); +// +// if (signalingPartcipants.contains(gm.getParticipantIdentifier())) { +// matchingParticipants.add(gm); +// count++; +// } +// +// //All concurrent signaler were found +// if (count == signalingPartcipants.size()) { +// break; +// } +// +// } else if (gm.getParticipantIdentifier().equals(signaledException.getSignalingParticipant())) { +// matchingParticipants.add(gm); +// break; +// } + } //Test if the participant is not Signaler + else { + if (!signaledException.getSignalingParticipants().contains(gm.getParticipantIdentifier())) { + matchingParticipants.add(gm); + } + +// //ConcurrentGlobalException: there are more than one signaler +// if (signaledException instanceof ConcurrentGlobalException) { +// List<String> signalingPartcipants = ((ConcurrentGlobalException) signaledException).getSignalingParticipants(); +// +// if (!(signalingPartcipants.contains(gm.getParticipantIdentifier()))) { +// matchingParticipants.add(gm); +// } +// +// } else if (!gm.getParticipantIdentifier().equals(signaledException.getSignalingParticipant())) { +// matchingParticipants.add(gm); +// } + } } } + } return matchingParticipants; } +// private List<GuardianMember> getMatchingParticipantsOriginal(String regularExpression, GlobalExceptionInterface signaledException) { +// List<GuardianMember> matchingParticipants = new LinkedList(); +// +// if (regularExpression.toUpperCase().equals("SIGNALER")) { +// for (GuardianMember gm : guardianList) { +// if (gm.getParticipantIdentifier().equals(signaledException.getSignalingParticipant())) { +// matchingParticipants.add(gm); +// break; +// } +// } +// } else if (regularExpression.toUpperCase().equals("!SIGNALER")) { +// for (GuardianMember gm : guardianList) { +// if (!gm.getParticipantIdentifier().equals(signaledException.getSignalingParticipant())) { +// matchingParticipants.add(gm); +// } +// } +// +// } else { +// //Create an java regular expression +// String re = createJavaRegularExpression(regularExpression); +// +// for (GuardianMember gm : guardianList) { +// if (gm.getParticipantIdentifier().matches(re)) { +// matchingParticipants.add(gm); +// } +// } +// } +// +// return matchingParticipants; +// } + /* Valid expressions: *, <Context>.*, <Context>, *.<Context>, *.<Context>.*, * *.<Context>.*.<Context>.*, <REG_EXP> || <REG_EXP> * @@ -390,34 +666,34 @@ public class GuardianGroupImpl implements GuardianGroup { private String createJavaRegularExpression(String regularExpression) throws InvalidRegularExpression { StringBuffer re = new StringBuffer(); - String[] splitedByBar = regularExpression.split("\\|\\|"); - String[] splitedByPeriod; + String[] splitByBar = regularExpression.split("\\|\\|"); + String[] splitByPeriod; - for (int i = 0; i < splitedByBar.length; i++) { + for (int i = 0; i < splitByBar.length; i++) { - splitedByPeriod = splitedByBar[i].split("\\."); + splitByPeriod = splitByBar[i].split("\\."); if (i > 0) { re.append("|"); } re.append("^"); - for (int j = 0; j < splitedByPeriod.length; j++) { + for (int j = 0; j < splitByPeriod.length; j++) { //* - if (splitedByPeriod[j].equals("*")) { + if (splitByPeriod[j].equals("*")) { //Validate the regular expression - if (j + 1 != splitedByPeriod.length && splitedByPeriod[j + 1].equals("*")) { + if (j + 1 != splitByPeriod.length && splitByPeriod[j + 1].equals("*")) { throw new InvalidRegularExpression(); } //* - if (splitedByPeriod.length == 1) { + if (splitByPeriod.length == 1) { re.append("(\\w+)"); } //*.<CONTEXT> - if (j == 0 && splitedByPeriod.length != 1) { + if (j == 0 && splitByPeriod.length != 1) { re.append("(\\w+\\"); re.append(".)*"); } //<CONTEXT>.* @@ -434,15 +710,15 @@ public class GuardianGroupImpl implements GuardianGroup { // } //<CONTEXT> || <CONTEXT>.<CONTEXT>.<CONTEXT> || *.<CONTEXT> - if (splitedByPeriod.length == 1) { + if (splitByPeriod.length == 1) { re.append("(\\w+\\"); re.append(".)*"); } if (j == 0 || j - 1 == 0) { - re.append("(" + splitedByPeriod[j] + ")"); + re.append("(" + splitByPeriod[j] + ")"); } else { - re.append("(\\." + splitedByPeriod[j] + ")"); + re.append("(\\." + splitByPeriod[j] + ")"); } } } @@ -451,4 +727,45 @@ public class GuardianGroupImpl implements GuardianGroup { return re.toString(); } } + + private class WrapperInteger { + + private int value; + + public WrapperInteger() { + } + + public WrapperInteger(int value) { + this.value = value; + } + + public void setValue(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } + + public int increment() { + return ++value; + } + + public int increment(int amount) { + return value += amount; + } + + public int decrement() { + return --value; + } + + public int decrement(int amount) { + return value -= value; + } + + @Override + public String toString() { + return Integer.toString(value); + } + } } diff --git a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GuardianMemberImpl.java b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GuardianMemberImpl.java index ec6ecb609c..893d5fcb1b 100644 --- a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GuardianMemberImpl.java +++ b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GuardianMemberImpl.java @@ -41,12 +41,15 @@ public class GuardianMemberImpl implements GuardianMember { @Reference(name = "guardian_group", required = true) public GuardianGroup guardianGroup; private int id; + //FIXME: Review the usage of this variable + private boolean exceptionThrown; public GuardianMemberImpl() { contextList = new Stack<Context>(); contextList.add(Context.INIT_CONTEXT); exceptionQueue = new LinkedList<GlobalException>(); participantState = GuardianGroup.NORMAL_PARTICIPANT_STATE; + exceptionThrown = false; } @Init @@ -82,7 +85,7 @@ public class GuardianMemberImpl implements GuardianMember { if (contextList.size() == 2) { JoinException ex = new JoinException(); ex.setSignalingContext(context); - ex.setSignalingParticipant(getParticipantIdentifier()); + ex.putSignalingParticipant(getParticipantIdentifier()); gthrow(ex, null); } @@ -94,7 +97,6 @@ public class GuardianMemberImpl implements GuardianMember { } } - //Adapt to allow a regular expression //If participantList is null then signal to ALL participants public void gthrow(GlobalExceptionInterface ex, List<String> participantList) { //1)Block the participant until raise an exception @@ -102,28 +104,16 @@ public class GuardianMemberImpl implements GuardianMember { if (!(ex instanceof SuspendException)) { //Set the exception's parameters ex.setSignalingContext(getCurrentContext()); - ex.setSignalingParticipant(getParticipantIdentifier()); + ex.putSignalingParticipant(getParticipantIdentifier()); guardianGroup.gthrow(ex, participantList); + exceptionThrown = true; } else { /*if (service instanceof BlockingInterface && !service.isBlocked()) { - service.block(); + service.block(); }*/ - participantState = GuardianGroup.SUSPENDED_PARTICIPANT_STATE; + setParticipantState(GuardianGroup.SUSPENDED_PARTICIPANT_STATE); } - - //*Is here the best place to receive such kind of msg? - // - //2B)When receive exception_msg from GuardianGroup do - // if participant is not suspended then suspend it - // if participant supports interrupts then - // interrupt it, add SuspendException in the exception_queue, and invoke checkExceptionStatus - // else invoke checkExceptionStatus periodically - // - //4)Once ALL required participants are SUSPENDED (suspended point), invoke the defined Recovery Rules - // 4.1) recovery_rules < signaled exceptions + context_list of all participant > target context + exception to raise - // 4.2) raise the resolved exception in each participant -> it goes to the exception_queue - } public boolean propagate(GlobalExceptionInterface ex) { @@ -132,19 +122,18 @@ public class GuardianMemberImpl implements GuardianMember { } public void checkExceptionStatus() throws GlobalException { - //1)Chek the exception queue - // 1.1) if exception_queue is empty then return - // else if first element on the exception_queue is SuspendException then - // the method blocks until the next exception is received. The method raises the first non-SuspendException in the queue //Blocks until the state be diferent the SUSPENDED_STATE - while (participantState == GuardianGroup.SUSPENDED_PARTICIPANT_STATE) { + while (participantState == GuardianGroup.SUSPENDED_PARTICIPANT_STATE && exceptionThrown) { + System.out.println(getParticipantIdentifier() + ": I am blocked!"); try { - Thread.sleep(5000); + Thread.sleep(5000); } catch (InterruptedException ex) { Logger.getLogger(GuardianMemberImpl.class.getName()).log(Level.SEVERE, null, ex); } } + exceptionThrown = false; + System.out.println(getParticipantIdentifier() + ": I am not blocked!"); GlobalException exc; @@ -170,7 +159,6 @@ public class GuardianMemberImpl implements GuardianMember { public String getParticipantIdentifier() { //1) Return the participant identifier -> context list dot separated StringBuffer participantIdentifier = new StringBuffer(); - //id.append(this.id + "." + Context.INIT_CONTEXT.getName()); participantIdentifier.append(this.id); for (int i = 0; i < contextList.size(); i++) { participantIdentifier.append("." + contextList.get(i).getName()); diff --git a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GuardianPrimitives.java b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GuardianPrimitives.java index 3d441a6c0c..9ddd22a2fd 100644 --- a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GuardianPrimitives.java +++ b/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GuardianPrimitives.java @@ -19,8 +19,6 @@ package org.apache.tuscany.sca.guardian; import java.util.List; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.osoa.sca.annotations.Remotable; //@Remotable public interface GuardianPrimitives { @@ -31,10 +29,10 @@ public interface GuardianPrimitives { public void removeContext(); //Methods to control the signaling of exceptions - public void gthrow(@XmlJavaTypeAdapter(GlobalExceptionAdapter.class) GlobalExceptionInterface ex, List<String> participantList); + public void gthrow(GlobalExceptionInterface ex, List<String> participantList); - public boolean propagate(@XmlJavaTypeAdapter(GlobalExceptionAdapter.class) GlobalExceptionInterface ex); + public boolean propagate(GlobalExceptionInterface ex); //Method to check pending global exceptions - public void checkExceptionStatus(); + public void checkExceptionStatus() throws GlobalException; } diff --git a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GuardianMemberAdapter.java b/sandbox/dougsleite/guardian-model/src/test/java/org/apache/tuscany/sca/guardian/itests/primaryBackup/common/PrimaryBackupFailedTogetherException.java index b6cbfe8ec6..d2ce160bd7 100644 --- a/sandbox/dougsleite/guardian-model/src/main/java/org/apache/tuscany/sca/guardian/GuardianMemberAdapter.java +++ b/sandbox/dougsleite/guardian-model/src/test/java/org/apache/tuscany/sca/guardian/itests/primaryBackup/common/PrimaryBackupFailedTogetherException.java @@ -16,19 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.tuscany.sca.guardian; -import javax.xml.bind.annotation.adapters.XmlAdapter; +package org.apache.tuscany.sca.guardian.itests.primaryBackup.common; -public class GuardianMemberAdapter extends XmlAdapter<GuardianMemberImpl, GuardianMember> { +import org.apache.tuscany.sca.guardian.GlobalException; - @Override - public GuardianMember unmarshal(GuardianMemberImpl v) throws Exception { - return v; - } +public class PrimaryBackupFailedTogetherException extends GlobalException { - @Override - public GuardianMemberImpl marshal(GuardianMember v) throws Exception { - return (GuardianMemberImpl) v; - } } |