[asterisk-scf-commits] asterisk-scf/integration/ice-util-cpp.git branch "baserep" created.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Fri Dec 16 08:40:29 CST 2011


branch "baserep" has been created
        at  03c60235bcd92430db36cb1d60297277514a8016 (commit)

- Log -----------------------------------------------------------------
commit 03c60235bcd92430db36cb1d60297277514a8016
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Fri Dec 16 08:39:50 2011 -0600

    Added new ComponentStateReplicator class as a base class for state replicators.

diff --git a/include/AsteriskSCF/Component/Component.h b/include/AsteriskSCF/Component/Component.h
index 176c967..680530e 100644
--- a/include/AsteriskSCF/Component/Component.h
+++ b/include/AsteriskSCF/Component/Component.h
@@ -63,6 +63,7 @@ protected:
     // Notification for some of 
     // the component events. 
     virtual void onPreInitialize() {}
+    virtual void onPreServiceCreation() {}
     virtual void onPostInitialize() {}
     virtual void onSuspend() {}
     virtual void onResume() {}
@@ -203,7 +204,7 @@ protected:
     /**
      * Helper that caches the service references for the primary adapter.
      */
-    void managePrimaryService(const AsteriskSCF::Discovery::LocatorRegistrationWrapperPtr& service);
+    virtual void managePrimaryService(const AsteriskSCF::Discovery::LocatorRegistrationWrapperPtr& service);
 
     /**
      * Helper that caches the service references for the backplane adapter. 
@@ -253,6 +254,7 @@ protected:
     /////////////////////////////////////////////////////////////////////
     // Accessors to state. 
     const AsteriskSCF::Replication::ReplicationContextPtr& getReplicationContext() const {return mReplicationContext;}
+    void setReplicationContext(const AsteriskSCF::Replication::ReplicationContextPtr& context) {mReplicationContext = context;}
     const AsteriskSCF::Component::TestContextPtr& getTestContext() const {return mTestContext;}
     const std::string& getName() const {return mName;}
     const std::string& getServiceName() const {return mServiceName;}
@@ -274,7 +276,13 @@ protected:
     AsteriskSCF::System::Logging::Logger mLogger;
 
 private:
-    void initialize();
+
+    /** 
+     * We just aren't going to let anyone else do this. There
+     * are hooks and overrides aplenty. 
+     */
+    virtual void initialize();
+
     void suspendService(bool shuttingDown);
 
     /////////////////////////////////////////////////////////////////////
diff --git a/include/AsteriskSCF/Component/ComponentStateReplicator.h b/include/AsteriskSCF/Component/ComponentStateReplicator.h
new file mode 100644
index 0000000..6936a61
--- /dev/null
+++ b/include/AsteriskSCF/Component/ComponentStateReplicator.h
@@ -0,0 +1,126 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+#pragma once
+
+#include <Ice/Ice.h>
+#include <IceBox/IceBox.h>
+
+#include <boost/shared_ptr.hpp>
+
+#include <AsteriskSCF/Component/Component.h>
+#include <AsteriskSCF/logger.h>
+#include <AsteriskSCF/System/Component/ConfigurationIf.h>
+#include <AsteriskSCF/CollocatedIceStorm/CollocatedIceStorm.h>
+
+namespace AsteriskSCF
+{
+namespace Component
+{
+class ASTSCF_DLL_EXPORT ComponentStateReplicator : public AsteriskSCF::Component::Component
+{
+public:
+    ComponentStateReplicator(const AsteriskSCF::System::Logging::Logger& logger,
+              const std::string& componentDiscoveryCategory,
+              bool replicatesConfiguration);
+
+protected:
+   
+    //////////////////////////////////////////////
+    // Overrides of Component class operations. 
+
+    /** 
+     * Unregister as a listener to our state replicator. 
+     * A component in active mode doesn't neeed to listen to
+     * state replication data. 
+     * Note: This currently defaults to no-op, since our replicators
+     * don't yet replicate themeselve. 
+     */
+    virtual void stopListeningToStateReplicators() {}
+
+    /** 
+     * Register as a listener to our state replicator. 
+     * A component in standby mode will do this to monitor state changes
+     * being sent from an active component. 
+     * Note: This currently defaults to no-op, since our replicators
+     * don't yet replicate themeselve. 
+     */
+    virtual void listenToStateReplicators() {}
+
+    /**
+     * Note: This currently defaults to no-op, since our replicators
+     * don't yet replicate themeselve. 
+     */
+    virtual void createReplicationStateListeners() {}
+
+    /**
+     * Creates a replication context using the factory method
+     * createReplicationContext(). Override the factory method if 
+     * you want to create a custom replication context. 
+     * Note: State replicators don't actually replicate themselves currently,
+     * but this is behavior from the base Component class. 
+     */
+    virtual void initReplicationContext();
+
+    /**
+     * By default we're assuming State Replicators don't need to locate
+     * remote services. But override this if you need to. 
+     */
+    virtual void findRemoteServices() {}
+
+    /**
+     * We've specialized this from the base Component class. 
+     */
+    virtual void managePrimaryService(const AsteriskSCF::Discovery::LocatorRegistrationWrapperPtr& service);
+
+    ////////////////////////////////////////////////////////
+    // These are required overrides. 
+
+    /**
+     * Create all services to be associated with the primary service adapter. 
+     * This is where you create the servants for your replication interfaces. 
+     */
+    virtual void createPrimaryServices() = 0;
+
+    /**
+     * The derived component is expected to wrap each 
+     * primary adapter service that should be 
+     * registered with the Service Locator. 
+     */
+    virtual void preparePrimaryServicesForDiscovery() = 0;
+
+    /**
+     * Some notifications from the Component we rely on.
+     */
+    void onStop();
+
+    void onPreServiceCreation();
+
+    /////////////////////////////////////////////////////////
+    // Implementation
+    virtual void createConfigurationReplicationService();
+
+private:
+    /////////////////////////////////////////////////////////////////////
+    // State data
+
+    AsteriskSCF::System::Configuration::V1::ConfigurationReplicatorPtr mConfigurationReplicator;
+    AsteriskSCF::CollocatedIceStorm::CollocatedIceStormPtr mIceStorm;
+    Ice::ObjectPrx mConfigurationPublisher;
+    bool mReplicatesConfiguration;
+};
+
+} // end namespace Component
+} // end namespace AsteriskSCF
diff --git a/include/AsteriskSCF/Discovery/LocatorRegistrationWrapper.h b/include/AsteriskSCF/Discovery/LocatorRegistrationWrapper.h
index e6d410f..0d3b233 100644
--- a/include/AsteriskSCF/Discovery/LocatorRegistrationWrapper.h
+++ b/include/AsteriskSCF/Discovery/LocatorRegistrationWrapper.h
@@ -127,6 +127,11 @@ public:
         return mServiceManagement;
     }
 
+    Ice::Identity getServiceIdentity()
+    {
+        return mService->ice_getIdentity();
+    }
+
 private:
 
     //
diff --git a/src/Component/CMakeLists.txt b/src/Component/CMakeLists.txt
index 34df0fa..74a0a6b 100644
--- a/src/Component/CMakeLists.txt
+++ b/src/Component/CMakeLists.txt
@@ -1,2 +1,3 @@
 astscf_component_add_files(astscf-ice-util-cpp Component.cpp)
+astscf_component_add_files(astscf-ice-util-cpp ComponentStateReplicator.cpp)
 astscf_component_add_files(astscf-ice-util-cpp TestContext.cpp)
diff --git a/src/Component/Component.cpp b/src/Component/Component.cpp
index 70866e1..5511ca0 100644
--- a/src/Component/Component.cpp
+++ b/src/Component/Component.cpp
@@ -874,6 +874,8 @@ void Component::initialize()
 
         configureLogger();
 
+        onPreServiceCreation();
+
         createPrimaryServices();
 
         createBackplaneServices();
diff --git a/src/Component/ComponentStateReplicator.cpp b/src/Component/ComponentStateReplicator.cpp
new file mode 100644
index 0000000..c8e70f8
--- /dev/null
+++ b/src/Component/ComponentStateReplicator.cpp
@@ -0,0 +1,209 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#include <boost/lexical_cast.hpp>
+
+#include <Ice/Ice.h>
+#include <IceUtil/Thread.h>
+#include <IceBox/IceBox.h>
+
+#include <AsteriskSCF/Helpers/PropertyHelper.h>
+#include <AsteriskSCF/Component/ComponentStateReplicator.h>
+#include <AsteriskSCF/Core/Discovery/ServiceLocatorIf.h>
+#include <AsteriskSCF/System/Component/ComponentServiceIf.h>
+#include <AsteriskSCF/System/Component/ReplicaIf.h>
+#include <AsteriskSCF/Discovery/LocatorRegistrationWrapper.h>
+#include <AsteriskSCF/System/Component/ConfigurationIf.h>
+#include <AsteriskSCF/CollocatedIceStorm/CollocatedIceStorm.h>
+
+using namespace std;
+using namespace AsteriskSCF::System::Component::V1;
+using namespace AsteriskSCF::System::Logging;
+using namespace AsteriskSCF::Core::Discovery::V1;
+using namespace AsteriskSCF::Discovery;
+using namespace AsteriskSCF::Replication;
+using namespace AsteriskSCF::System::Configuration::V1;
+using namespace AsteriskSCF::CollocatedIceStorm;
+
+namespace AsteriskSCF
+{
+namespace Component
+{
+static const string ServiceLocatorManagementPropertyName("LocatorServiceManagement.Proxy");
+static const string ServiceLocatorPropertyName("LocatorService.Proxy");
+	
+static const string ComponentServiceProxyId("ComponentService");
+static const string ReplicaProxyId("Replica");
+
+/**
+* Servant that provides configuration data replication. 
+*/
+class ConfigurationReplicatorImpl : public ConfigurationReplicator
+{
+public:
+    ConfigurationReplicatorImpl(const IceStorm::TopicPrx& topic) : mConfigurationReplicationTopic(topic) { };
+    void registerConfigurationService(const AsteriskSCF::System::Configuration::V1::ConfigurationServicePrx&, const Ice::Current&);
+private:
+    IceStorm::TopicPrx mConfigurationReplicationTopic;
+};
+
+void ConfigurationReplicatorImpl::registerConfigurationService(const AsteriskSCF::System::Configuration::V1::ConfigurationServicePrx& service, const Ice::Current&)
+{
+    if (mConfigurationReplicationTopic)
+    {
+	IceStorm::QoS qos;
+        qos["reliability"] = "ordered";
+
+        try
+        {
+            mConfigurationReplicationTopic->subscribeAndGetPublisher(qos, service);
+        }
+        catch (const IceStorm::AlreadySubscribed&)
+        {
+            // This is perfectly okay actually, it just means what they wanted us to do
+            // is already done.
+        }
+    }
+}
+ComponentStateReplicator::ComponentStateReplicator(const AsteriskSCF::System::Logging::Logger& logger,
+                     const string& componentDiscoveryCategory,
+                     bool replicatesConfiguration) :
+      Component(logger, componentDiscoveryCategory),
+      mReplicatesConfiguration(replicatesConfiguration)
+{
+}
+
+/**
+ * In the required override of registerPrimaryServices(), this operation should
+ * be called for each primary interface registered with the service locator.
+ */
+void ComponentStateReplicator::managePrimaryService(const LocatorRegistrationWrapperPtr& service)
+{
+    Component::managePrimaryService(service);
+
+    if (mReplicatesConfiguration)
+    {
+        // Add the configuration repliator service as a facet to all primary services being registered
+        // with this state replicator. 
+        getServiceAdapter()->addFacet(mConfigurationReplicator, 
+                                      service->getServiceIdentity(),
+	                              ReplicatorFacet);
+    }
+}
+
+/**
+ * Create a ReplicationContext for this component. 
+ * This operation is a step in initialize()'s Template Method pattern.
+ */
+void ComponentStateReplicator::initReplicationContext()
+{
+    try
+    {
+        // Currently replicators are all assumed to be standalone instances.
+        // In the near future this will change. When it does, change the 
+        // default for this property to false.
+        bool standalone = AsteriskSCF::getBooleanPropertyValueWithDefault( 
+            getCommunicator()->getProperties(), getName() + ".Standalone", true);
+
+        ReplicationStateType state(STANDBY_IN_REPLICA_GROUP);
+
+        if (standalone)
+        {
+            state = ACTIVE_STANDALONE;
+        }
+
+        // Create the replication context.
+        setReplicationContext(createReplicationContext(state));
+    }
+    catch(const std::exception& e)
+    {
+        mLogger(Error) << BOOST_CURRENT_FUNCTION << e.what();
+        throw;
+    }
+}
+
+/**
+ * Create a service that supports replicating configuration data.  
+ * This operation is a step in initialize()'s Template Method pattern,
+ * but is only called if this object was constructed with the 'replicatesConfiguration'
+ * parameter set to true. 
+ */
+void ComponentStateReplicator::createConfigurationReplicationService()
+{
+    mIceStorm = new AsteriskSCF::CollocatedIceStorm::CollocatedIceStorm(getName(), getCommunicator()->getProperties());
+    IceStorm::TopicManagerPrx topicManager = mIceStorm->createTopicManagerProxy(getCommunicator());
+
+    IceStorm::TopicPrx topic;
+
+    if (topicManager)
+    {
+        try
+        {
+            topic = topicManager->retrieve("ConfigurationReplication");
+        }
+        catch (const IceStorm::NoSuchTopic&)
+        {
+            try
+            {
+                topic = topicManager->create("ConfigurationReplication");
+            }
+            catch (const IceStorm::TopicExists&)
+            {
+                mLogger(Error) << "Race condition creating topic, aborting";
+                return;
+            }
+        }
+        // There is no cast here on purpose as this is just going to get passed to
+        // the service locator which just takes a plain ol' proxy anyway.
+        mConfigurationPublisher = topic->getPublisher();
+    }
+    else
+    {
+        mLogger(Info) << "IceStorm topic manager proxy not present, unable to perform configuration replication.";
+    }
+
+    // Create our ConfigurationReplicator interface support.
+    mConfigurationReplicator = new ConfigurationReplicatorImpl(topic);
+}
+
+/**
+ * This notification is called by base Component during initialization, 
+ * just before required overrides are called to create the primary 
+ * services of the component. 
+ */
+void ComponentStateReplicator::onPreServiceCreation()
+{
+    if (mReplicatesConfiguration)
+    {
+        createConfigurationReplicationService();
+    }
+}
+
+/**
+ * This notification is called by base Component during initialization, 
+ * just before required overrides are called to create the primary 
+ * services of the component. 
+ */
+void ComponentStateReplicator::onStop()
+{
+    if (mReplicatesConfiguration)
+    {
+        mIceStorm->stop();
+    }
+}
+
+} // end Component
+} // end AsteriskSCF

-----------------------------------------------------------------------


-- 
asterisk-scf/integration/ice-util-cpp.git



More information about the asterisk-scf-commits mailing list