/* * 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; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.osoa.sca.annotations.Scope; import org.apache.tuscany.sca.guardian.exceptions.*; import org.osoa.sca.annotations.Service; @Service(GuardianGroup.class) @Scope("COMPOSITE") public class GuardianGroupImpl implements GuardianGroup { List guardianMembers; public GuardianGroupImpl() { guardianMembers = new LinkedList(); } public void addGuardianMember(GuardianMember guardianMember) { guardianMembers.add(guardianMember); guardianMember.setUniqueParticipantID(guardianMembers.size() - 1); } public void enableContext(Context context) { throw new UnsupportedOperationException("Not supported yet."); } public void removeContext() { throw new UnsupportedOperationException("Not supported yet."); } public void gthrow(GlobalException ex, List 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 //Sends a message representing the exception to the other guardian members if (participantList == null) { for (GuardianMember g : guardianMembers) { if (!g.getParticipantIdentifier().equals(ex.getSignalingParticipant())) { //g.gthrow(ex, participantList); g.gthrow(null, null); } } } else { for (GuardianMember g : guardianMembers) { if (participantList.contains(g.getCurrentContext())) { //g.gthrow(ex, participantList); g.gthrow(null, null); } } } //Check if the participants are blocked List flags = new ArrayList(guardianMembers.size()); for (int i = 0; i < guardianMembers.size(); i++) { if (guardianMembers.get(i).getService().isBlocked()) { flags.add(i, 1); } else { flags.add(i, 0); } } //Wait until all participants are blocked while (flags.contains(0)) { try { Thread.sleep(5000); } catch (InterruptedException ex1) { Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex1); } } //3)Once ALL required participants are SUSPENDED (suspended point), invoke the defined Recovery Rules for (GuardianMember g : guardianMembers) { 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); // } //HARDCODED - SERVER-BACKUP EXAMPLE //Rule 1 if (ex instanceof JoinException) { if (guardianMembers.size() > 1) { PrimaryExistsException primaryExists = new PrimaryExistsException(); primaryExists.setTargetContext(new Context("MAIN")); BackupJoinedException backupJoined = new BackupJoinedException(); backupJoined.setTargetContext(new Context("PRIMARY")); for (GuardianMember g : guardianMembers) { //let p = JoinException.signaler if (g.getParticipantIdentifier().equals(ex.getSignalingParticipant())) { g.addException(primaryExists); System.out.println("adding PrimaryExistsException to " + g.getParticipantIdentifier()); } else { g.addException(backupJoined); System.out.println("adding BackupJoinedException to " + g.getParticipantIdentifier()); } } } } //Rule 2 else if (ex instanceof PrimaryFailedException) { PrimaryFailedException primaryFailedInit = new PrimaryFailedException(); primaryFailedInit.setTargetContext(Context.INIT_CONTEXT); PrimaryFailedException primaryFailedMain = new PrimaryFailedException(); primaryFailedMain.setTargetContext(new Context("MAIN")); for (GuardianMember g : guardianMembers) { if (g.getCurrentContext().getName().equals("PRIMARY")) { System.out.println("adding PrimaryFailedException to " + g.getParticipantIdentifier()); g.addException(primaryFailedInit); } else if (g.getCurrentContext().getName().equals("BACKUP")) { System.out.println("adding PrimaryFailedException to " + g.getParticipantIdentifier()); g.addException(primaryFailedMain); } } } //Rule 3 else if (ex instanceof BackupFailedException) { BackupFailedException backupFailedPrimary = new BackupFailedException(); backupFailedPrimary.setTargetContext(new Context("PRIMARY")); BackupFailedException backupFailedInit = new BackupFailedException(); backupFailedInit.setTargetContext(Context.INIT_CONTEXT); for (GuardianMember g : guardianMembers) { if (g.getCurrentContext().getName().equals("PRIMARY")) { System.out.println("adding BackupFailedException to " + g.getParticipantIdentifier()); g.addException(backupFailedPrimary); } else if (g.getCurrentContext().getName().equals("BACKUP")) { System.out.println("adding BackupFailedException to " + g.getParticipantIdentifier()); g.addException(backupFailedInit); } } } } public boolean propagate(GlobalException ex) { throw new UnsupportedOperationException("Not supported yet."); } public void checkExceptionStatus() { throw new UnsupportedOperationException("Not supported yet."); } public boolean removeGuardianMember(GuardianMember guardianMember) { return this.guardianMembers.remove(guardianMember); } }