diff options
Diffstat (limited to 'sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl')
6 files changed, 1064 insertions, 0 deletions
diff --git a/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImpl.java b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImpl.java new file mode 100644 index 0000000000..5a243560e3 --- /dev/null +++ b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImpl.java @@ -0,0 +1,644 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.guardian.impl; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +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.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.implementation.guardian.common.InvalidRegularExpressionException; +import org.apache.tuscany.sca.implementation.guardian.GuardianGroup; +import org.apache.tuscany.sca.implementation.guardian.GuardianMember; +import org.apache.tuscany.sca.implementation.guardian.common.ConcurrentExceptionOcurrenceException; +import org.apache.tuscany.sca.implementation.guardian.common.Constants; +import org.apache.tuscany.sca.implementation.guardian.common.Context; +import org.apache.tuscany.sca.implementation.guardian.common.GlobalException; +import org.apache.tuscany.sca.implementation.guardian.common.GlobalExceptionInterface; +import org.apache.tuscany.sca.implementation.guardian.common.InvalidNodeException; +import org.apache.tuscany.sca.implementation.guardian.common.ResolutionTreeUtils; +import org.apache.tuscany.sca.implementation.guardian.common.SuspendException; +import org.apache.tuscany.sca.implementation.guardian.xml.RecoveryRulesProcessor; +import org.apache.tuscany.sca.implementation.guardian.xml.ResolutionTreesProcessor; + +public class GuardianGroupImpl implements GuardianGroup { + + private List<GuardianMember> guardianList; + private InnerGuardianGroupThread innerThread; + private List<GlobalExceptionInterface> concurrentExList; + private Map<String, OMElement> resolutionTreeElements; + private ResolutionTreeUtils resolutionTreeUtils; + private Map<String, OMElement> ruleElements; + + public GuardianGroupImpl(String recoveryRules, String resolutionTrees) { + guardianList = new LinkedList<GuardianMember>(); + concurrentExList = new LinkedList<GlobalExceptionInterface>(); + innerThread = new InnerGuardianGroupThread(); + resolutionTreeUtils = new ResolutionTreeUtils(); + + setRecoveryRules(recoveryRules); + setResolutionTree(resolutionTrees); + } + + private void setRecoveryRules(String recoveryRules) { + try { + FileInputStream fileInputStream = new FileInputStream(recoveryRules); + XMLStreamReader xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(fileInputStream); + + RecoveryRulesProcessor processor = new RecoveryRulesProcessor(); + ruleElements = processor.read(xmlReader).getRuleElements(); + + } 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) { + Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex); + } + } + + private void setResolutionTree(String resolutionTree) { + + try { + FileInputStream fileInputStream = new FileInputStream(resolutionTree); + XMLStreamReader resolutionTreeReader = XMLInputFactory.newInstance().createXMLStreamReader(fileInputStream); + + ResolutionTreesProcessor processor = new ResolutionTreesProcessor(); + 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) { + Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex); + } + } + + public void addGuardianMember(GuardianMember guardianMember) { + guardianList.add(guardianMember); + guardianMember.setUniqueParticipantID(guardianList.size() - 1); + } + + public boolean removeGuardianMember(GuardianMember guardianMember) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void enableContext(Context context) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void removeContext() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public synchronized void gthrow(GlobalExceptionInterface ex, List<String> 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()) || + g.getParticipantIdentifier().equals(ex.getSignalingParticipants().get(0))) { + g.gthrow(suspendEx, null); + } + } + } + + if (!innerThread.isRunning()) { + innerThread.setGlobalException(ex); + new Thread(innerThread).start(); + } + + } + + public boolean propagate(GlobalExceptionInterface ex) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void checkExceptionStatus() { + throw new UnsupportedOperationException("Not supported yet."); + } + + private class InnerGuardianGroupThread implements Runnable { + + private boolean isRunning; + private GlobalExceptionInterface ex = null; + + public InnerGuardianGroupThread() { + isRunning = false; + } + + public void setGlobalException(GlobalExceptionInterface ex) { + this.ex = ex; + } + + public GlobalExceptionInterface getGlobalException() { + return ex; + } + + public void run() { + isRunning = true; + + if (ex != null) { + + //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); + } + } + } + isRunning = false; + } + + public boolean isRunning() { + return isRunning; + } + + private void applyRecoveryRules(GlobalExceptionInterface ex) throws ConcurrentExceptionOcurrenceException { + ruleTag(ex, ruleElements.values().iterator()); + } + + private void ruleTag(GlobalExceptionInterface ex, Iterator<OMElement> ruleElements) throws ConcurrentExceptionOcurrenceException { + String signaledException; + String exceptionName; + + OMElement rule; + while (ruleElements.hasNext()) { + + rule = ruleElements.next(); + signaledException = getAttributeValue(rule, Constants.SIGNALED_EXCEPTION); + exceptionName = ex.getClass().getName(); + + if (signaledException.equals(exceptionName)) { + participantExceptionTag(ex, rule.getChildElements()); + break; + } + } + } + + private void participantExceptionTag(GlobalExceptionInterface ex, Iterator<OMElement> participantElements) throws ConcurrentExceptionOcurrenceException { + String matchParticipant; + List<GuardianMember> gmList; + + OMElement participant; + while (participantElements.hasNext()) { + participant = participantElements.next(); + + matchParticipant = getAttributeValue(participant, Constants.MATCH); + gmList = getMatchingParticipants(matchParticipant, ex); + + if (!gmList.isEmpty()) { + throwExceptionTag(gmList, ex, participant.getChildElements()); + } + } + } + + private void throwExceptionTag(List<GuardianMember> gmList, GlobalExceptionInterface ex, Iterator<OMElement> throwExceptionElements) throws ConcurrentExceptionOcurrenceException { + String className; + String targetContextName; + Integer minParticipantJoined; + Integer maxParticipantJoined; + + OMElement throwException; + while (throwExceptionElements.hasNext()) { + + throwException = throwExceptionElements.next(); + + className = getAttributeValue(throwException, Constants.CLASS); + targetContextName = getAttributeValue(throwException, Constants.TARGET_CONTEXT); + + try { + minParticipantJoined = Integer.parseInt(getAttributeValue(throwException, Constants.MIN_PARTICIPANT_JOINED)); + } catch (NumberFormatException nex) { + minParticipantJoined = null; + } + + try { + maxParticipantJoined = Integer.parseInt(getAttributeValue(throwException, Constants.MAX_PARTICIPANT_JOINED)); + } catch (NumberFormatException nexc) { + maxParticipantJoined = null; + } + + //Test the min and max joined participants condition + if (minParticipantJoined != null && maxParticipantJoined != null) { + if (!(guardianList.size() >= minParticipantJoined && guardianList.size() < maxParticipantJoined)) { + break; + } + } else if (minParticipantJoined != null) { + if (!(guardianList.size() >= minParticipantJoined)) { + break; + } + } else if (minParticipantJoined != null) { + if (!(guardianList.size() >= minParticipantJoined)) { + break; + } + } + + //<affected_participants> + String affectedParticipants = affectedParticipantsTag(throwException.getChildElements()); + int index = -1; + + //Verify if the parameter is an index + try { + index = Integer.parseInt(affectedParticipants); + } catch (NumberFormatException nexc) { + index = -1; + } + + //Create the new exception instance + Class exceptionClass; + try { + exceptionClass = Class.forName(className); + + Context targetContext; + if (targetContextName.toUpperCase().equals(Context.CURRENT_CONTEXT.getName().toUpperCase())) { + targetContext = Context.CURRENT_CONTEXT; + } else if (targetContextName.toUpperCase().equals(Context.INIT_CONTEXT.getName().toUpperCase())) { + targetContext = Context.INIT_CONTEXT; + } else { + targetContext = new Context(targetContextName); + } + GlobalException newException = (GlobalException) exceptionClass.newInstance(); + + newException.setTargetContext(targetContext); + newException.setSignalingContext(ex.getSignalingContext()); + 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(Constants.FIRST)) { + gmList.get(0).addException(newException); + } else if (affectedParticipants.toUpperCase().equals(Constants.LAST)) { + gmList.get(gmList.size() - 1).addException(newException); + } else if (affectedParticipants.toUpperCase().equals(Constants.ALL)) { + for (GuardianMember gm : gmList) { + gm.addException(newException); + } + } + } else { + for (GuardianMember gm : gmList) { + gm.addException(newException); + } + } + + } catch (InstantiationException ex1) { + Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex1); + } catch (IllegalAccessException ex1) { + Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex1); + } catch (ClassNotFoundException ex1) { + Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex1); + } + } + } + + private String affectedParticipantsTag(Iterator<OMElement> affectedParticipantElements) { + + String affectedParticipantValue = null; + + OMElement affectedParticipant; + while (affectedParticipantElements.hasNext()) { + + affectedParticipant = affectedParticipantElements.next(); + affectedParticipantValue = affectedParticipant.getText(); + } + + if (affectedParticipantValue != null && affectedParticipantValue.length() == 0) { + affectedParticipantValue = null; + } + + return affectedParticipantValue; + } + + private String getAttributeValue(OMElement element, String attributeName) { + OMAttribute at; + Iterator it = element.getAllAttributes(); + + while (it.hasNext()) { + at = (OMAttribute) it.next(); + if (at.getLocalName().equals(attributeName)) { + return at.getAttributeValue(); + } + } + + return null; + } + + 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; + OMElement root; + String exceptionLevel = null; + GlobalExceptionInterface resolvedEx = null; + + while (resolutionTreesElements.hasNext()) { + tree = (OMElement) resolutionTreesElements.next(); + exceptionLevel = tree.getAttributeValue(Constants.EXCEPTION_LEVEL_QNAME); + + root = (OMElement) tree.getChildElements().next(); + resolvedEx = checkExceptionResolutionTree(exceptionList, root); + + 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. + private GlobalExceptionInterface checkExceptionResolutionTree(List<GlobalExceptionInterface> exceptionList, OMElement rootTree) { + + resolutionTreeUtils.setRoot(rootTree); + String ex1, ex2; + GlobalExceptionInterface resolvedEx = null; + + ex1 = exceptionList.get(0).getClass().getName(); + for (int i = 1; i < exceptionList.size(); i++) { + ex2 = exceptionList.get(i).getClass().getName(); + + try { + ex1 = resolutionTreeUtils.getLowestCommonAncestor(ex1, ex2); + } catch (InvalidNodeException invalidNodeException) { + ex1 = null; + break; + } + } + + if (ex1 != null) { + Class exceptionClass; + + try { + exceptionClass = Class.forName(ex1); + 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; + + } else { + return null; + } + } + + private List<GuardianMember> getMatchingParticipants(String regularExpression, GlobalExceptionInterface signaledException) { + List<GuardianMember> matchingParticipants = new LinkedList(); + String[] splitByComma = regularExpression.split(","); + + //Invalid regular expression + if (splitByComma.length > 2) { + throw new InvalidRegularExpressionException("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); + } + } + } else if (regularExpression.toUpperCase().equals("!SIGNALER")) { + for (GuardianMember gm : guardianList) { + if (!signaledException.getSignalingParticipants().contains(gm.getParticipantIdentifier())) { + 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); + } + } + } + + } //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; + } + } + } + + //Invalid expression + if (index == -1) { + throw new InvalidRegularExpressionException("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)) { + + //Test if the participant is Signaler + if (splitByComma[index].toUpperCase().equals("SIGNALER")) { + + if (signaledException.getSignalingParticipants().contains(gm.getParticipantIdentifier())) { + matchingParticipants.add(gm); + } + } //Test if the participant is not Signaler + else { + if (!signaledException.getSignalingParticipants().contains(gm.getParticipantIdentifier())) { + matchingParticipants.add(gm); + } + } + } + } + + } + + return matchingParticipants; + } + + /* Valid expressions: *, <Context>.*, <Context>, *.<Context>, *.<Context>.*, + * *.<Context>.*.<Context>.*, <REG_EXP> || <REG_EXP> + * + * Invalid expressions: *.*, **, + * + * Not supported yet: !<Context>, !<Context> || <Context>, !(<Context> || <Context>) + */ + private String createJavaRegularExpression(String regularExpression) throws InvalidRegularExpressionException { + StringBuffer re = new StringBuffer(); + + String[] splitByBar = regularExpression.split("\\|\\|"); + String[] splitByPeriod; + + for (int i = 0; i < splitByBar.length; i++) { + + splitByPeriod = splitByBar[i].split("\\."); + + if (i > 0) { + re.append("|"); + } + + re.append("^"); + for (int j = 0; j < splitByPeriod.length; j++) { + + //* + if (splitByPeriod[j].equals("*")) { + + //Validate the regular expression + if (j + 1 != splitByPeriod.length && splitByPeriod[j + 1].equals("*")) { + throw new InvalidRegularExpressionException(); + } + + //* + if (splitByPeriod.length == 1) { + re.append("(\\w+)"); + } //*.<CONTEXT> + + if (j == 0 && splitByPeriod.length != 1) { + re.append("(\\w+\\"); + re.append(".)*"); + } //<CONTEXT>.* + else { + re.append("(\\"); + re.append(".\\w+)*"); + } + } //<CONTEXT> + else { + +// //Validate the regular expression +// if (splitedByPeriod[j].matches("^(\\*)*$")) { +// throw new RuntimeException("Invalid name for a context"); +// } + + //<CONTEXT> || <CONTEXT>.<CONTEXT>.<CONTEXT> || *.<CONTEXT> + if (splitByPeriod.length == 1) { + re.append("(\\w+\\"); + re.append(".)*"); + } + + if (j == 0 || j - 1 == 0) { + re.append("(" + splitByPeriod[j] + ")"); + } else { + re.append("(\\." + splitByPeriod[j] + ")"); + } + } + } + re.append("$"); + } + return re.toString(); + } + } +} diff --git a/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImplementationFactoryImpl.java b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImplementationFactoryImpl.java new file mode 100644 index 0000000000..cf6b3245ce --- /dev/null +++ b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImplementationFactoryImpl.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.guardian.impl; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.implementation.guardian.GuardianGroupImplementation; +import org.apache.tuscany.sca.implementation.guardian.GuardianGroupImplementationFactory; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; + +public class GuardianGroupImplementationFactoryImpl implements GuardianGroupImplementationFactory { + + private AssemblyFactory assemblyFactory; + private JavaInterfaceFactory javaFactory; + + public GuardianGroupImplementationFactoryImpl(AssemblyFactory assemblyFactory, JavaInterfaceFactory javaFactory) { + this.assemblyFactory = assemblyFactory; + this.javaFactory = javaFactory; + } + + public GuardianGroupImplementation createGuardianGroupImplementation() { + return new GuardianGroupImplementationImpl(assemblyFactory, javaFactory); + } + +// public GuardianGroupImplementation createGuardianGroupImplementation() { +// return new GuardianGroupImplementationImpl(); +// } +} diff --git a/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImplementationImpl.java b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImplementationImpl.java new file mode 100644 index 0000000000..7520846d55 --- /dev/null +++ b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImplementationImpl.java @@ -0,0 +1,134 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.guardian.impl; + +import org.apache.tuscany.sca.implementation.guardian.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.apache.axiom.om.OMElement; +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.ConstrainingType; +import org.apache.tuscany.sca.assembly.Property; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.assembly.Service; +import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; + +public class GuardianGroupImplementationImpl implements GuardianGroupImplementation { + + private AssemblyFactory assemblyFactory; + private JavaInterfaceFactory javaFactory; + private List<Service> services = new ArrayList<Service>(); + private OMElement guardianProperties; + + public GuardianGroupImplementationImpl(AssemblyFactory assemblyFactory, + JavaInterfaceFactory javaFactory) { + + this.assemblyFactory = assemblyFactory; + this.javaFactory = javaFactory; + this.guardianProperties = null; + } + + private void introspectServices(AssemblyFactory assemblyFactory, JavaInterfaceFactory javaFactory) { + + Service guardianService = assemblyFactory.createService(); + + guardianService.setName("GuardianGroup"); + + JavaInterface guardianInterface; + + try { + guardianInterface = javaFactory.createJavaInterface(GuardianGroup.class); + } catch (InvalidInterfaceException ex) { + throw new IllegalArgumentException(ex); + } + + JavaInterfaceContract guardianInterfaceContract = javaFactory.createJavaInterfaceContract(); + + guardianInterfaceContract.setInterface(guardianInterface); + + guardianService.setInterfaceContract(guardianInterfaceContract); + + services.add(guardianService); + } + + public void setGuardianProperties(OMElement guardianProperties) { + this.guardianProperties = guardianProperties; + } + + public OMElement getGuardianProperties() { + return this.guardianProperties; + } + + @Override + public String getURI() { + // The Guardian Model implementation does not have a URI + return null; + } + + @Override + public void setURI(String arg0) { + // The Guardian Model implementation does not have a URI + } + + @Override + public List<Service> getServices() { + if (services == null || services.size() == 0) { + introspectServices(assemblyFactory, javaFactory); + } + return services; + } + + @Override + public List<Reference> getReferences() { + // The Guardian Model implementation does not support references + return Collections.emptyList(); + } + + @Override + public List<Property> getProperties() { + // The sample DATA implementation does not support properties + return Collections.emptyList(); + } + + @Override + public ConstrainingType getConstrainingType() { + // The Guardian Model implementation does not support constrainingTypes + return null; + } + + @Override + public void setConstrainingType(ConstrainingType arg0) { + // The Guardian Model implementation does not support constrainingTypes + } + + @Override + public boolean isUnresolved() { + // The Guardian Model implementation is always resolved + return false; + } + + @Override + public void setUnresolved(boolean arg0) { + // The Guardian Model implementation is always resolved + } +} diff --git a/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianMemberImpl.java b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianMemberImpl.java new file mode 100644 index 0000000000..80b9321e79 --- /dev/null +++ b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianMemberImpl.java @@ -0,0 +1,177 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.guardian.impl; + +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.Stack; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.apache.tuscany.sca.implementation.guardian.common.GlobalExceptionInterface; +import org.apache.tuscany.sca.implementation.guardian.GuardianGroup; +import org.apache.tuscany.sca.implementation.guardian.GuardianMember; +import org.apache.tuscany.sca.implementation.guardian.common.Context; +import org.apache.tuscany.sca.implementation.guardian.common.GlobalException; +import org.apache.tuscany.sca.implementation.guardian.common.JoinException; +import org.apache.tuscany.sca.implementation.guardian.common.SuspendException; +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +@Service(GuardianMember.class) +@Scope("COMPOSITE") +public class GuardianMemberImpl implements GuardianMember { + + private int participantState; + private Stack<Context> contextList; + + private Queue<GlobalException> exceptionQueue; + @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 + public void init() { + guardianGroup.addGuardianMember(this); + } + + @Destroy + public void destroy() { + guardianGroup.removeGuardianMember(this); + } + + public void addException(GlobalException ex) { + exceptionQueue.add(ex); + } + + public Context getCurrentContext() { + return contextList.peek(); + } + + + public void enableContext(Context context) { + //Update the context list with the related set of exceptions + contextList.push(context); + + if (contextList.size() == 2) { + JoinException ex = new JoinException(); + ex.setSignalingContext(context); + ex.putSignalingParticipant(getParticipantIdentifier()); + gthrow(ex, null); + } + + } + + public void removeContext() { + if (!contextList.isEmpty()) { + contextList.pop(); + } + } + + //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 + + if (!(ex instanceof SuspendException)) { + //Set the exception's parameters + ex.setSignalingContext(getCurrentContext()); + ex.putSignalingParticipant(getParticipantIdentifier()); + + guardianGroup.gthrow(ex, participantList); + exceptionThrown = true; + } else { + setParticipantState(GuardianGroup.SUSPENDED_PARTICIPANT_STATE); + } + } + + public boolean propagate(GlobalExceptionInterface ex) { + //1)Compares the current context with the exception's target context + return !getCurrentContext().equals(ex.getTargetContext()); + } + + public void checkExceptionStatus() throws GlobalException { + + //Blocks until the state be diferent the SUSPENDED_STATE + while (participantState == GuardianGroup.SUSPENDED_PARTICIPANT_STATE && exceptionThrown) { + System.out.println(getParticipantIdentifier() + ": I am blocked!"); + try { + 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; + + if ((exc = exceptionQueue.peek()) == null) { + System.out.println(getParticipantIdentifier() + "#No exception on exception queue"); + return; + } + + //Check if ex.targetContext() matches the participant id + //Eg. ex.targetContext(): Main and participant id: Init.Main.Backup -> should thrown the exception + //Test if the exception should be thrown in the target context + for (Context c : contextList) { + if (exc.getTargetContext().equals(c) && (c.equals(Context.INIT_CONTEXT) || c.getExceptionList().contains(exc.getClass()))) { + System.out.println(getParticipantIdentifier() + "#Returning an exception"); + exceptionQueue.poll(); + throw exc; + } + } + + return; + } + + public String getParticipantIdentifier() { + //1) Return the participant identifier -> context list dot separated + StringBuffer participantIdentifier = new StringBuffer(); + participantIdentifier.append(this.id); + for (int i = 0; i < contextList.size(); i++) { + participantIdentifier.append("." + contextList.get(i).getName()); + } + return participantIdentifier.toString(); + } + + public void setUniqueParticipantID(int id) { + this.id = id; + } + + public int getParticipantState() { + return participantState; + } + + public void setParticipantState(int state) { + this.participantState = state; + } +} diff --git a/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/RecoveryRulesImpl.java b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/RecoveryRulesImpl.java new file mode 100644 index 0000000000..e2fc2f8048 --- /dev/null +++ b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/RecoveryRulesImpl.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.guardian.impl; + +import org.apache.tuscany.sca.implementation.guardian.RecoveryRules; +import java.util.Hashtable; +import java.util.Map; +import org.apache.axiom.om.OMElement; + +public class RecoveryRulesImpl implements RecoveryRules { + + private Map<String, OMElement> ruleElements = new Hashtable<String, OMElement>(); + + public Map<String, OMElement> getRuleElements() { + return ruleElements; + } +} diff --git a/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/ResolutionTreesImpl.java b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/ResolutionTreesImpl.java new file mode 100644 index 0000000000..669f06b1ef --- /dev/null +++ b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/ResolutionTreesImpl.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.guardian.impl; + +import java.util.Hashtable; +import java.util.Map; +import org.apache.axiom.om.OMElement; +import org.apache.tuscany.sca.implementation.guardian.ResolutionTrees; + +public class ResolutionTreesImpl implements ResolutionTrees { + + private Map<String, OMElement> resolutionTreeElements = new Hashtable<String, OMElement>(); + + public Map<String, OMElement> getResolutionTreeElements() { + return resolutionTreeElements; + } +} |