Jump to: navigation, search

Samples for AIL-Based Application

File bc.properties

 PrimaryHost1 = bsgen803julien
 PrimaryPort1 = 2020
 BackupHost1 = bsgen803julien
 BackupPort1 = 2030
 ApplicationName1 = AIL_Client
 PlaceName1 = Place_5320
 UserName = SIP_5320
 UserPass = 
 PrimaryHost2 = Suite80GAJulien
 PrimaryPort2 = 2020
 BackupHost2 = Suite80GAJulien
 BackupPort2 = 2022
 ApplicationName2 = AIL_Client
 PlaceName2 = Place_5320

File BusinessContinuity.java

 package com.genesyslab.ail.applicationblocks.businesscontinuity;
 import java.io.*;
 import java.util.*;
 import com.genesyslab.ail.*;
 import com.genesyslab.ail.event.*;
 import org.apache.log4j.*;
 public class BusinessContinuity {
   Logger mLogger;
   Properties mProperties;
   HashMap mSite1;
   HashMap mSite2;
   AilLoader mAL;
   AilFactory mAF;
   boolean mSwitchingOver;
   boolean mSwitchoverScheduled;
   int mSwitchoverDelay = 30;
   boolean mFirstConnection = true;
   ServiceListener mServiceListener;
   Place mPlace;
   Person mAgent;
   Dn mDN;
   DnListener mDnListener;
   int mCurrentSite = 1;
   Timer mTimer = new Timer();
   static BusinessContinuity mBC;
   public static void main(String[] s) {
       mBC = new BusinessContinuity();
   }
   public BusinessContinuity() {
       
       mLogger = org.apache.log4j.LogManager.getLoggerRepository().getLogger("BC");
       // This sample stores data in a property file as an example
       mProperties = new Properties();
       try {
           mProperties.load(new FileInputStream("bc.properties"));
       }
       catch (Exception e) {
           mLogger.error("Did not find bc.properties");
           System.exit(0);
       }
       // Connection parameters read in the file for site 1
       mSite1 = new HashMap();
       mSite1.put("PrimaryHost", mProperties.getProperty("PrimaryHost1"));
       mSite1.put("PrimaryPort", new Integer(mProperties.getProperty("PrimaryPort1")));
       mSite1.put("BackupHost", mProperties.getProperty("BackupHost1"));
       mSite1.put("BackupPort", new Integer(mProperties.getProperty("BackupPort1")));
       mSite1.put("ApplicationName", mProperties.getProperty("ApplicationName1"));
       mSite1.put("ApplicationType", AilLoader.ApplicationType.CLIENT);
       mSite1.put("UserName", mProperties.getProperty("UserName"));
       mSite1.put("UserPass", "");
       mSite1.put("PlaceName", mProperties.getProperty("PlaceName1"));
       // Connection parameters read in the file for site 2
       mSite2 = new HashMap();
       mSite2.put("PrimaryHost", mProperties.getProperty("PrimaryHost2"));
       mSite2.put("PrimaryPort", new Integer(mProperties.getProperty("PrimaryPort2")));
       mSite2.put("BackupHost", mProperties.getProperty("BackupHost2"));
       mSite2.put("BackupPort", new Integer(mProperties.getProperty("BackupPort2")));
       mSite2.put("ApplicationName", mProperties.getProperty("ApplicationName2"));
       mSite2.put("ApplicationType", AilLoader.ApplicationType.CLIENT);
       mSite2.put("UserName", mProperties.getProperty("UserName"));
       mSite2.put("UserPass", "");
       mSite2.put("PlaceName", mProperties.getProperty("PlaceName2"));
       // Initiate a logger for traces
       mLogger = org.apache.log4j.LogManager.getLoggerRepository().getLogger("BC");
       // Try and connect to the first site.
       mCurrentSite = 1;
       connect(mSite1);
   }
   private void connect(Map site) {
       try {
           mLogger.info("Connecting to " + site.get("PrimaryHost"));
           // Builds an AILLoader
           mAL = new AilLoader((String) site.get("PrimaryHost"), ((Integer) site.get("PrimaryPort")).intValue(),
                               (String) site.get("BackupHost"), ((Integer) site.get("BackupPort")).intValue(),
                               (String) site.get("UserName"), (String) site.get("UserPass"),
                               (String) site.get("ApplicationName"), (AilLoader.ApplicationType) site.get("ApplicationType"),
                               15,  // This is the general  timeout for AIl requests
                               10); // This is the delay AIL waits when trying again to connect to a server
           // Starts AIL
           mAF = mAL.getAilFactory();
           // At this point, mAF is null if the config server could not be reached for instance
           if (mAF == null) {
               mLogger.error(mAL.getInitException());
               switchover();
           }
           // The serviceListener will listen and react on services status change
           mServiceListener = new ServiceListener() {
                   public void serviceStatusChanged(ServiceStatus.Type type, String name, ServiceStatus.Status status) {
                       try {
                           if (status.toInt() == ServiceStatus.Status.OFF_) {
                               switch (type.toInt()) {
                               case ServiceStatus.Type.TELEPHONY_:
                               case ServiceStatus.Type.CONFIG_:
                               case ServiceStatus.Type.STAT_:
                                   scheduleSwitchover();
                                   break;
                               }
                           }
                       }
                       catch (Throwable t) {
                           mLogger.error("While processing serviceStatusChanged, ", t);
                       }
                   }
               };
           // Listen to three types of services
           mAF.addServiceListener(ServiceStatus.Type.CONFIG, mServiceListener);
           mAF.addServiceListener(ServiceStatus.Type.STAT, mServiceListener);
           mAF.addServiceListener(ServiceStatus.Type.TELEPHONY, mServiceListener);
           // In this sample, the UserName UserPassword and PlaceName are stores in the properties file.
           // You probably want to read them from a login banner.
           mPlace = mAF.getPlace((String) mProperties.getProperty("PlaceName" + mCurrentSite));
           mLogger.info("Place is " + mPlace);
           mAgent = mAF.getPerson((String) mProperties.getProperty("UserName"));
           Map annex = mAgent.getAnnex();
           try {
               Map section = (Map) annex.get("agent-desktop");
               if (mFirstConnection) {
                   String preferred = (String) section.get("disaster-recovery.preferred-site");
                   if (!mProperties.getProperty("ApplicationName1").equals(preferred)) {
                       // Switch Site 1 and site 2 in the properties file or wherever you store that info.
                   }
                   mSwitchoverDelay = Integer.parseInt((String) section.get("disaster-recovery.timeout"));
                   mFirstConnection = false;
               }
           }
           catch (Exception e) {
               mLogger.warn("Agent "  + mAgent.getName() + " does not have the expected annex");
           }
           mDN = (Dn) mPlace.getDns().iterator().next();
           // Listens to the DN status and initiates a switchover on graceful shutdown.
           mDnListener = new DnListener() {
                   public void handleDnEvent(DnEvent event) {
                       try {
                           if (event.getStatus().toInt() == Dn.Status.LOGGED_OUT_ || event.getStatus().toInt() == Dn.Status.BUSY_LOGGED_OUT_) {
                               Map tExtensions = event.getTEventExtensions();
                               if (tExtensions != null) {
                                   String reasonCode = (String) tExtensions.get("ReasonCode");
                                   if ("graceful_shutdown_logout".equals(reasonCode)) {
                                       switchover();
                                   }
                               }
                           }
                       } catch (Throwable t) { mLogger.error("While processing DNEvent, ", t); }
                   }
                   public void deleted() { }
                   public void contactChanged(InteractionEvent ie) { }
                   public void handleInteractionEvent(InteractionEvent ie) { }
              };
           if (mDN != null) {
               mDN.addDnListener(mDnListener);
           }
   
           mLogger.info("DN is " + mDN);
       } catch (Throwable t2) { mLogger.error("While connecting, ", t2); }
   }
   // Before actually doing a switchover, we want to give a chance to the server/network to get back in service
   private void scheduleSwitchover() {
       if (!mSwitchoverScheduled) {
           mSwitchoverScheduled = true;
           mLogger.info("Scheduling switchover");
           // Schedule the switchover in a timer task. We don't want to wait in this thread.
           // We are in a callback thread because this method is called from listeners.
           mTimer.schedule(new TimerTask() {
                   public void run() {
                       Map services = mAF.getServices();
                       
                       if (getService(services, ServiceStatus.Type.TELEPHONY).mStatus.toInt() == ServiceStatus.Status.ON_
                           && getService(services, ServiceStatus.Type.CONFIG).mStatus.toInt() == ServiceStatus.Status.ON_
                           && getService(services, ServiceStatus.Type.STAT).mStatus.toInt() == ServiceStatus.Status.ON_) {
                           mLogger.info("Services are ON. Switchover cancelled");
                           // Don't switchover if the services are all ON.
                           mSwitchoverScheduled = false;
                           return;
                       }
                       else {
                           switchover();
                           mSwitchoverScheduled = false;
                       }
                   }
               },
               mSwitchoverDelay * 1000);
       }
   }
   private ServiceStatus getService(Map services, ServiceStatus.Type type) {
       for (Iterator it = services.values().iterator() ; it.hasNext() ; ) {
           ServiceStatus ss = (ServiceStatus) it.next();
           if (ss.mType.toInt() == type.toInt()) {
               return ss;
           }
       }
       return null;
   }
   // The switchover procedure itself
   // It invokes the timer in order to release the thread that calls 
   // because it is probably a callback thread and we don't want to
   // 
   private void switchover() {
       try {
           if (mSwitchingOver) {
               mLogger.warn("Already switching over");
               return;
           }
           mSwitchingOver = true;
           mLogger.info("Switching over. Current site was " + mCurrentSite);
           if (mDN != null) { mDN.removeDnListener(mDnListener); }
           if (mAF != null) { mAF.removeServiceListener(ServiceStatus.Type.TELEPHONY, mServiceListener); }
           // Release all the references to the objects coming from the previous factory 
           mServiceListener = null;
           mDnListener = null;
           mPlace = null;
           mDN = null;
           mAF = null;
           // Kill the old AilFactory
           mAL.killFactory();
           if (mCurrentSite == 1) {
               mCurrentSite = 2;
               connect(mSite2);
           }
           else {
               mCurrentSite = 1;
               connect(mSite1);
           }
           mLogger.info("Switchover completed. Current site is now " + mCurrentSite);
           mSwitchingOver = false;
       }
       catch (Throwable t) {
           mLogger.error("While running switchover, ", t);
       }
   }
}
This page was last edited on June 10, 2013, at 13:54.
Comments or questions about this documentation? Contact us for support!