[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