diff options
author | dougsleite <dougsleite@13f79535-47bb-0310-9956-ffa450edef68> | 2009-08-06 14:24:58 +0000 |
---|---|---|
committer | dougsleite <dougsleite@13f79535-47bb-0310-9956-ffa450edef68> | 2009-08-06 14:24:58 +0000 |
commit | c179c8909e852ecb68bc37b59374931eab333cdf (patch) | |
tree | b69fdc1e72ea9dfa56d06c4d772886295cdf4ad1 | |
parent | 6fab0ae9e1d940fbe610db8ca20c3b4b5ca4fe28 (diff) |
- Modifying the guardian-model to deal with concurrent exceptions;
- The policy-resolutiontrees module is used to process the resolution tree - the lowest common ancestor is the resolved exception for a set of concurrent exceptions;
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@801656 13f79535-47bb-0310-9956-ffa450edef68
17 files changed, 822 insertions, 359 deletions
diff --git a/sandbox/dougsleite/guardian-model/pom.xml b/sandbox/dougsleite/guardian-model/pom.xml index 66f2bdbf32..1a6ddf3fd7 100644 --- a/sandbox/dougsleite/guardian-model/pom.xml +++ b/sandbox/dougsleite/guardian-model/pom.xml @@ -1,118 +1,100 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * 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. ---><project> - <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>org.apache.tuscany.sca</groupId> - <artifactId>tuscany-sca</artifactId> - <version>1.6-SNAPSHOT</version> - <relativePath>../../pom.xml</relativePath> - </parent> - <artifactId>tuscany-guardian-model</artifactId> - <name>Guardian Model</name> - - <repositories> - <repository> - <id>apache.incubator</id> - <url>http://people.apache.org/repo/m2-incubating-repository</url> - </repository> - </repositories> - - <version>1.6-SNAPSHOT</version> - - <dependencies> - <dependency> - <groupId>org.apache.tuscany.sca</groupId> - <artifactId>tuscany-node-impl</artifactId> - <version>1.6-SNAPSHOT</version> - </dependency> - - <dependency> - <groupId>org.apache.tuscany.sca</groupId> - <artifactId>tuscany-host-embedded</artifactId> - <version>1.6-SNAPSHOT</version> - </dependency> - - <dependency> - <groupId>org.apache.tuscany.sca</groupId> - <artifactId>tuscany-implementation-java-runtime</artifactId> - <version>1.6-SNAPSHOT</version> - <scope>runtime</scope> - </dependency> - - <dependency> - <groupId>org.apache.tuscany.sca</groupId> - <artifactId>tuscany-binding-ws-axis2</artifactId> - <version>1.6-SNAPSHOT</version> - <scope>compile</scope> - </dependency> - - <dependency> - <groupId>org.apache.tuscany.sca</groupId> - <artifactId>tuscany-host-tomcat</artifactId> - <version>1.6-SNAPSHOT</version> - <scope>runtime</scope> - </dependency> - - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <version>4.5</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>org.apache.axis2</groupId> - <artifactId>axis2-jaxws</artifactId> - <version>1.4.1</version> - </dependency> - - <dependency> - <groupId>org.apache.axis2</groupId> - <artifactId>axis2</artifactId> - <version>1.2</version> - <type>pom</type> - </dependency> - <dependency> - <groupId>org.apache.tuscany.sca</groupId> - <artifactId>tuscany-policy-recoveryrules</artifactId> - <version>1.6-SNAPSHOT</version> - </dependency> - </dependencies> - - <build> - <plugins> - <plugin> - <groupId>org.apache.felix</groupId> - <artifactId>maven-bundle-plugin</artifactId> - - <configuration> - <instructions> - <Bundle-Version>${tuscany.version}</Bundle-Version> - <Bundle-SymbolicName>org.apache.tuscany.sca.guardian</Bundle-SymbolicName> - <Bundle-Description>${pom.name}</Bundle-Description> - <Export-Package>org.apache.tuscany.sca.guardian*</Export-Package> - </instructions> - </configuration> - </plugin> - </plugins> - </build> - -</project> - +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<project xmlns:pom="http://maven.apache.org/POM/4.0.0">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-modules</artifactId>
+ <version>1.6-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-guardian</artifactId>
+ <name>Apache Tuscany SCA Guardian Model</name>
+
+ <repositories>
+ <repository>
+ <id>apache.incubator</id>
+ <url>http://people.apache.org/repo/m2-snapshot-repository</url>
+ </repository>
+ </repositories>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-host-embedded</artifactId>
+ <version>1.6-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-data-api</artifactId>
+ <version>1.6-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-implementation-java-runtime</artifactId>
+ <version>1.6-SNAPSHOT</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-jaxws</artifactId>
+ <version>1.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2</artifactId>
+ <version>1.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-policy-resolutiontrees</artifactId>
+ <version>1.6-SNAPSHOT</version>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+
+ <configuration>
+ <instructions>
+ <Bundle-Version>${tuscany.version}</Bundle-Version>
+ <Bundle-SymbolicName>org.apache.tuscany.sca.guardian</Bundle-SymbolicName>
+ <Bundle-Description>${pom.name}</Bundle-Description>
+ <Export-Package>org.apache.tuscany.sca.guardian*</Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
+
+
+
diff --git a/sandbox/dougsleite/guardian-model/sequenceDiagram-externalException.jpg b/sandbox/dougsleite/guardian-model/sequenceDiagram-externalException.jpg Binary files differnew file mode 100644 index 0000000000..60060ca0e2 --- /dev/null +++ b/sandbox/dougsleite/guardian-model/sequenceDiagram-externalException.jpg 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/resources/definitions.xml b/sandbox/dougsleite/guardian-model/src/main/resources/definitions.xml deleted file mode 100644 index c08d08cdfa..0000000000 --- a/sandbox/dougsleite/guardian-model/src/main/resources/definitions.xml +++ /dev/null @@ -1,66 +0,0 @@ -<?xml version="1.0" encoding="ASCII"?> -<!-- - * 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. ---> -<sca:definitions xmlns="http://www.osoa.org/xmlns/sca/1.0" - targetNamespace="http://primarybackup" - xmlns:sca="http://www.osoa.org/xmlns/sca/1.0" - > - - <sca:policySet name="recoveryRulesPolicy" - provides="recoveryRules" - appliesTo="sca:implementation.java"> - - <recovery_rules> - - <rule name="Rule1" signaled_exception="org.apache.tuscany.sca.guardian.JoinException"> - - <participant match="SIGNALER"> - <throw_exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.PrimaryExistsException" target_context="MAIN" min_participant_joined="2"/> - </participant> - - <participant match="!SIGNALER"> - <throw_exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.BackupJoinedException" target_context="PRIMARY" min_participant_joined="2"/> - </participant> - </rule> - - <rule name="Rule2" signaled_exception="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.PrimaryFailedException"> - - <participant match="*.PRIMARY"> - <throw_exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.PrimaryFailedException" target_context="INIT_CONTEXT"/> - </participant> - - <participant match="*.BACKUP"> - <throw_exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.PrimaryFailedException" target_context="MAIN"/> - </participant> - </rule> - - <rule name="Rule3" signaled_exception="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.BackupFailedException"> - - <participant match="*.PRIMARY"> - <throw_exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.BackupFailedException" target_context="PRIMARY"/> - </participant> - - <participant match="*.BACKUP"> - <throw_exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.BackupFailedException" target_context="INIT_CONTEXT"/> - </participant> - </rule> - - </recovery_rules> - </sca:policySet> -</sca:definitions>
\ No newline at end of file diff --git a/sandbox/dougsleite/guardian-model/src/main/resources/primaryNbackups-concurrent.composite b/sandbox/dougsleite/guardian-model/src/main/resources/primaryNbackups-concurrent.composite new file mode 100644 index 0000000000..7cd28ff085 --- /dev/null +++ b/sandbox/dougsleite/guardian-model/src/main/resources/primaryNbackups-concurrent.composite @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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 (thea + * "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. +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:t="http://tuscany.apache.org/xmlns/sca/1.0" + targetNamespace="http://serverbackup" + name="serverbackup"> + + <component name="Participant1"> + <implementation.java class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.NodeImpl"/> + <reference name="guardian_member" target="GuardianMember1"/> + <reference name="nodes" target="Participant2 Participant3 Participant4"/> + </component> + + <component name="Participant2"> + <implementation.java class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.NodeImpl"/> + <reference name="guardian_member" target="GuardianMember2"/> + <reference name="nodes" target="Participant1 Participant3 Participant4"/> + </component> + + <component name="Participant3"> + <implementation.java class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.NodeImpl"/> + <reference name="guardian_member" target="GuardianMember3"/> + <reference name="nodes" target="Participant1 Participant2 Participant4"/> + </component> + + <component name="Participant4"> + <implementation.java class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.NodeImpl"/> + <reference name="guardian_member" target="GuardianMember4"/> + <reference name="nodes" target="Participant1 Participant2 Participant3"/> + </component> + + <component name="GuardianMember1"> + <implementation.java class="org.apache.tuscany.sca.guardian.GuardianMemberImpl"/> + <reference name="guardian_group" target="GuardianGroup"/> + </component> + + <component name="GuardianMember2"> + <implementation.java class="org.apache.tuscany.sca.guardian.GuardianMemberImpl"/> + <reference name="guardian_group" target="GuardianGroup"/> + </component> + + <component name="GuardianMember3"> + <implementation.java class="org.apache.tuscany.sca.guardian.GuardianMemberImpl"/> + <reference name="guardian_group" target="GuardianGroup"/> + </component> + + <component name="GuardianMember4"> + <implementation.java class="org.apache.tuscany.sca.guardian.GuardianMemberImpl"/> + <reference name="guardian_group" target="GuardianGroup"/> + </component> + + <component name="GuardianGroup"> + <implementation.java class="org.apache.tuscany.sca.guardian.GuardianGroupImpl"/> + <property name="recovery_rules">src/main/resources/recoveryrules_nbackpus_concurrent.xml</property> + <property name="resolution_tree">src/main/resources/resolutionTree.xml</property> + </component> + +</composite> diff --git a/sandbox/dougsleite/guardian-model/src/main/resources/recoveryrules_nbackpus_concurrent.xml b/sandbox/dougsleite/guardian-model/src/main/resources/recoveryrules_nbackpus_concurrent.xml new file mode 100644 index 0000000000..65c509751c --- /dev/null +++ b/sandbox/dougsleite/guardian-model/src/main/resources/recoveryrules_nbackpus_concurrent.xml @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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 (thea + * "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. +--> + +<recovery_rules> + + <!-- A new participant joins in the group --> + <rule name="Rule1" signaled_exception="org.apache.tuscany.sca.guardian.JoinException"> + + <participant match="*.PRIMARY"> + <throw_exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.BackupJoinedException" target_context="PRIMARY"/> + </participant> + + <participant match="SIGNALER"> + <throw_exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.PrimaryExistsException" target_context="MAIN" min_participant_joined="2"/> + </participant> + </rule> + + <!-- The Primary fails --> + <rule name="Rule2" signaled_exception="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.PrimaryFailedException"> + + <participant match="*.PRIMARY"> + <throw_exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.PrimaryFailedException" target_context="INIT_CONTEXT"/> + </participant> + + <participant match="*.BACKUP"> + <throw_exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.PrimaryFailedException" target_context="MAIN"> + <affected_participants>FIRST</affected_participants> + </throw_exception> + </participant> + </rule> + + <!-- The Backup fails --> + <rule name="Rule3" signaled_exception="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.BackupFailedException"> + + <participant match="*.PRIMARY"> + <throw_exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.BackupFailedException" target_context="PRIMARY"/> + </participant> + + <participant match="SIGNALER"> + <throw_exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.BackupFailedException" target_context="INIT_CONTEXT"/> + </participant> + </rule> + + <!-- The Primary and Backup fail together --> + <rule name="Rule4" signaled_exception="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.PrimaryBackupFailedTogetherException"> + + <participant match="*.PRIMARY"> + <throw_exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.PrimaryFailedException" target_context="INIT_CONTEXT"/> + </participant> + + <!-- Backup signaler --> + <participant match="*.BACKUP,SIGNALER"> + <throw_exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.BackupFailedException" target_context="INIT_CONTEXT"/> + </participant> + + <!-- Excluding the backup signaler --> + <participant match="*.BACKUP,!SIGNALER"> + <throw_exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.PrimaryFailedException" target_context="MAIN"> + <affected_participants>FIRST</affected_participants> + </throw_exception> + </participant> + + </rule> + +</recovery_rules> diff --git a/sandbox/dougsleite/guardian-model/src/main/resources/resolutionTree.xml b/sandbox/dougsleite/guardian-model/src/main/resources/resolutionTree.xml new file mode 100644 index 0000000000..34c2fec0bf --- /dev/null +++ b/sandbox/dougsleite/guardian-model/src/main/resources/resolutionTree.xml @@ -0,0 +1,8 @@ +<resolution_trees> + <resolution_tree exception_level="1"> + <exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.PrimaryBackupFailedTogetherException"> + <exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.PrimaryFailedException"/> + <exception class="org.apache.tuscany.sca.guardian.itests.primaryBackup.common.BackupFailedException"/> + </exception> + </resolution_tree> +</resolution_trees> diff --git a/sandbox/dougsleite/guardian-model/src/test/java/org/apache/tuscany/sca/guardian/itests/concurrentexceptions/Launch.java b/sandbox/dougsleite/guardian-model/src/test/java/org/apache/tuscany/sca/guardian/itests/concurrentexceptions/Launch.java new file mode 100644 index 0000000000..ff9a0e0b4b --- /dev/null +++ b/sandbox/dougsleite/guardian-model/src/test/java/org/apache/tuscany/sca/guardian/itests/concurrentexceptions/Launch.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.guardian.itests.concurrentexceptions; + +import java.io.IOException; +import org.apache.tuscany.sca.guardian.itests.primaryBackup.common.Node; +import org.apache.tuscany.sca.guardian.itests.primaryBackup.common.TestInterface; +import org.apache.tuscany.sca.host.embedded.SCADomain; + +public class Launch { + + public static void main(String... args) throws IOException { + SCADomain scaDomain = SCADomain.newInstance("primaryNbackups-concurrent.composite"); + + System.out.println("Starting participat1..."); + Node c = scaDomain.getService(Node.class, "Participant1"); + c.execute(); + + System.in.read(); + + System.out.println("Starting participant2..."); + Node c2 = scaDomain.getService(Node.class, "Participant2"); + c2.execute(); + + System.in.read(); + + System.out.println("Starting participant3..."); + Node c3 = scaDomain.getService(Node.class, "Participant3"); + c3.execute(); + + System.in.read(); + + System.out.println("Forcing exception ocurrence at participant1..."); + TestInterface t = scaDomain.getService(TestInterface.class, "Participant1"); + t.forcePrimaryServiceFailureException(); + + System.out.println("Forcing exception ocurrence at participant2..."); + TestInterface t2 = scaDomain.getService(TestInterface.class, "Participant2"); + t2.forceApplyUpdateFailureException(); + + System.in.read(); + + scaDomain.close(); + } +} 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; - } } diff --git a/sandbox/dougsleite/guardian-model/src/test/java/org/apache/tuscany/sca/guardian/itests/primaryBackup/common/PrimaryFailedException.java b/sandbox/dougsleite/guardian-model/src/test/java/org/apache/tuscany/sca/guardian/itests/primaryBackup/common/PrimaryFailedException.java index 086e255e94..00f2f84c00 100644 --- a/sandbox/dougsleite/guardian-model/src/test/java/org/apache/tuscany/sca/guardian/itests/primaryBackup/common/PrimaryFailedException.java +++ b/sandbox/dougsleite/guardian-model/src/test/java/org/apache/tuscany/sca/guardian/itests/primaryBackup/common/PrimaryFailedException.java @@ -18,7 +18,7 @@ */ package org.apache.tuscany.sca.guardian.itests.primaryBackup.common; -import org.apache.tuscany.sca.guardian.*; +import org.apache.tuscany.sca.guardian.GlobalException; public class PrimaryFailedException extends GlobalException { } |