[asterisk-scf-commits] asterisk-scf/integration/file_media_service.git branch "initial_development" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Tue Dec 6 09:53:00 CST 2011


branch "initial_development" has been updated
       via  1fb23472383c068f386784761b3591cefec7c11f (commit)
      from  968277e5293a89dd1afa8feb16a73f1eaedccead (commit)

Summary of changes:
 CMakeLists.txt                                     |    1 +
 config/FileMediaServiceConfigurator.py             |  115 ++++++
 .../FileMediaServiceConfigurationIf.ice            |   51 +++-
 .../FileMediaService/ContainerFileIf.ice           |   94 -----
 .../FileMediaServiceReplicationIf.ice              |  132 +++++++
 .../FileMediaService/FileMediaSessionStateIf.ice   |   72 ----
 src/CMakeLists.txt                                 |   23 +-
 src/Component.cpp                                  |  173 +++++++++-
 src/{ReplicationContext.h => ComponentDefs.h}      |   39 +--
 src/ComponentFeature.h                             |   58 +++
 src/Configuration.cpp                              |  377 ++++++++++++++++++++
 src/{LocalConfig.h => Configuration.h}             |   59 ++--
 src/ContainerConfigurationAdapter.h                |   13 +-
 src/ContainerImpl.cpp                              |   17 +-
 src/ContainerImpl.h                                |   18 +-
 src/ContainerInfoImpl.cpp                          |   69 ----
 src/ContainerInfoImpl.h                            |   74 ----
 src/ContainerRepository.cpp                        |   44 ++--
 src/ContainerRepository.h                          |   14 +-
 src/FileMediaServiceComponent.h                    |   15 +-
 src/FileMediaServiceReplicator.cpp                 |  218 +++++++++++
 src/MatroskaUtil.cpp                               |   49 ++-
 src/MatroskaUtil.h                                 |   50 +++-
 src/OpaqueContainerData.h                          |   57 ---
 src/ReplicatedObject.cpp                           |  127 +++++++
 src/ReplicatedObject.h                             |   56 +++
 src/ReplicationListener.h                          |   10 +-
 src/Replicator.h                                   |   57 +++
 src/RepositoryConfigurationAdapter.h               |   45 ++-
 src/RepositoryReplicationAdapter.h                 |    7 +-
 src/StreamImpl.cpp                                 |   44 ---
 src/StreamImpl.h                                   |   55 ---
 test/CMakeLists.txt                                |   10 +-
 test/UnitTest_ContainerRepository.cpp              |  239 +++---------
 34 files changed, 1676 insertions(+), 806 deletions(-)
 create mode 100755 config/FileMediaServiceConfigurator.py
 delete mode 100644 slice/AsteriskSCF/FileMediaService/ContainerFileIf.ice
 create mode 100644 slice/AsteriskSCF/Replication/FileMediaService/FileMediaServiceReplicationIf.ice
 delete mode 100644 slice/AsteriskSCF/Replication/FileMediaService/FileMediaSessionStateIf.ice
 rename src/{ReplicationContext.h => ComponentDefs.h} (51%)
 create mode 100644 src/ComponentFeature.h
 create mode 100644 src/Configuration.cpp
 copy src/{LocalConfig.h => Configuration.h} (76%)
 delete mode 100644 src/ContainerInfoImpl.cpp
 delete mode 100644 src/ContainerInfoImpl.h
 create mode 100644 src/FileMediaServiceReplicator.cpp
 delete mode 100644 src/OpaqueContainerData.h
 create mode 100644 src/ReplicatedObject.cpp
 create mode 100644 src/ReplicatedObject.h
 create mode 100644 src/Replicator.h
 delete mode 100644 src/StreamImpl.cpp
 delete mode 100644 src/StreamImpl.h


- Log -----------------------------------------------------------------
commit 1fb23472383c068f386784761b3591cefec7c11f
Author: Brent Eagles <beagles at digium.com>
Date:   Tue Dec 6 12:21:35 2011 -0330

    Code cleanups and copy replication/configuration strategies from the file
    session gateway. Removed slice for container file interface as this was an
    unnecessary distraction (structures need to be replaced.. in progress).

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2be9883..6533b3c 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,4 +7,5 @@ astscf_project(FileMediaService 3.4)
 add_subdirectory(slice)
 
 add_subdirectory(src)
+add_subdirectory(test)
 astscf_slice_collection_install(PROJECT)
diff --git a/config/FileMediaServiceConfigurator.py b/config/FileMediaServiceConfigurator.py
new file mode 100755
index 0000000..52429cd
--- /dev/null
+++ b/config/FileMediaServiceConfigurator.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+# FileMediaService configurator
+
+# Bring in the common configuration infrastructure
+import ConfigParser, Ice, Configurator, sys, os, traceback
+
+# Load our component specific configuration definitions
+Ice.loadSlice("--underscore -I\"" + os.environ["ASTSCF_HOME"] + "\"" + " -I" + Ice.getSliceDir() + " --all ../slice/AsteriskSCF/Configuration/FileMediaService/FileMediaServiceConfigurationIf.ice")
+import AsteriskSCF.Configuration.FileMediaService.V1
+
+# Add our own visitor implementations for the sections we support
+class SectionVisitors(Configurator.SectionVisitors):
+
+    def visit_replication_configuration_group(self, config, section):
+        group = AsteriskSCF.Configuration.FileMediaService.V1.ReplicationParameterGroup()
+        group.configurationItems = { }
+
+        mapper = Configurator.OptionMapper()
+        item = AsteriskSCF.Configuration.FileMediaService.V1.ProgressUpdateInterval()
+
+        #
+        # default values if 5000ms
+        #
+        mapper.map('progress_update_interval', item, 'update',
+                   AsteriskSCF.Configuration.FileMediaService.V1.ProgressUpdateIntervalItem, config.getint, 5000)
+
+        for option in config.options(section):
+            mapper.execute(group, section, option)
+        mapper.finish()
+        self.groups.append(group)
+        
+    def visit_repository_group(self, config, section):
+        #
+        # setup endpoint group.
+        #
+        group = AsteriskSCF.Configuration.FileMediaService.V1.RepositoryGroup()
+        group.configurationItems = { }
+
+        mapper = Configuration.OptionMapper()
+        item = AsteriskSCF.Configuration.FileMediaService.V1.BackgroundUpdates()
+        mapper.map('enable_updates', item, 'enabled',
+                   AsteriskSCF.Configuration.FileMediaService.V1.BackgroundUpdatesItem, config.getboolean, None)
+        mapper.map('update_interval', item, 'updateInterval',
+                   AsteriskSCF.Configuration.FileMediaService.V1.BackgroundUpdatesItem, config.get, None)
+        
+        for option in config.options(section):
+            mapper.execute(group, section, option)
+        mapper.finish()
+        self.groups.append(group)
+
+    def visit_container_group(self, config, section):
+        group = AsteriskSCF.Configuration.FileMediaService.V1.ContainerGroup()
+        group.configurationItems = { }
+
+        mapper = Configurator.OptionMapper()
+
+        #
+        # process config.
+        #
+        class FileOperationTransformer():
+            def __init__(self, config):
+                self.config = config
+
+            def get(self, section, item):
+                if (self.config.get(section, item) == 'playback'):
+                    return AsteriskSCF.Media.File.V1.FileOperations.Playback
+                if (self.config.get(section, item) == 'recording'):
+                    return AsteriskSCF.Media.File.V1.FileOperations.Recording
+                if (self.config.get(section, item) == 'both'):
+                    return AsteriskSCF.Media.File.V1.FileOperations.Both
+
+        mapper = Configurator.OptionMapper()
+        item = AsteriskSCF.Configuration.FileMediaService.V1.ContainerConfiguration()
+        mapper.map('catalog_id', item, 'catalogId',
+                   AsteriskSCF.Configuration.FileMediaService.V1.ContainerConfigurationItem, config.get, None)
+        mapper.map('path', item, 'uri',
+                   AsteriskSCF.Configuration.FileMediaService.V1.ContainerConfigurationItem, config.get, None)
+        fileOpTransformer = FileOperationTransformer(config)
+        mapper.map('supported_operations', item, 'operations',
+                   AsteriskSCF.Configuration.FileMediaService.V1.ContainerConfigurationItem, fileOpTransformer.get,
+                   AsteriskSCF.Media.File.V1.FileOperations.Playback)
+        for option in config.options(section):
+            mapper.execute(group, section, option)
+        mapper.finish(group)
+        self.groups.append(group)
+
+    def visit_unsupported(self, config, section):
+        if config.get(section, 'type') == 'endpoint':
+            self.visit_endpoint_group(config, section)
+            
+# In order to do service locator based lookup we need to pass in a params object
+serviceLocatorParams = AsteriskSCF.Core.Discovery.V1.ServiceLocatorParams()
+serviceLocatorParams.category = AsteriskSCF.Configuration.FileMediaService.V1.ConfigurationDiscoveryCategory
+serviceLocatorParams.service = 'default' 
+
+# Make a configurator application and let it run
+app = Configurator.ConfiguratorApp('FileMediaService.config', SectionVisitors(), None, serviceLocatorParams)
+sys.exit(app.main(sys.argv))
diff --git a/slice/AsteriskSCF/Configuration/FileMediaService/FileMediaServiceConfigurationIf.ice b/slice/AsteriskSCF/Configuration/FileMediaService/FileMediaServiceConfigurationIf.ice
index 0728b09..90afc26 100644
--- a/slice/AsteriskSCF/Configuration/FileMediaService/FileMediaServiceConfigurationIf.ice
+++ b/slice/AsteriskSCF/Configuration/FileMediaService/FileMediaServiceConfigurationIf.ice
@@ -17,7 +17,6 @@
 #pragma once
 
 #include <AsteriskSCF/System/Component/ConfigurationIf.ice>
-#include <AsteriskSCF/FileMediaService/ContainerFileIf.ice>
 #include <AsteriskSCF/Media/File/FileMediaIf.ice>
 
 /**
@@ -41,7 +40,7 @@ module V1
  * Service locator category for finding the configuration object for a file media service.
  *
  **/
-const string ConfigurationServiceDiscoveryCategory = "FileMediaServiceConfiguration";
+const string ConfigurationDiscoveryCategory = "FileMediaServiceConfiguration";
 
 local class GroupVisitor extends AsteriskSCF::System::Configuration::V1::ConfigurationGroupVisitor
 {
@@ -62,6 +61,32 @@ class FileMediaServiceItem extends  AsteriskSCF::System::Configuration::V1::Conf
 };
 
 /**
+ * In the case of the file media service, replication control deserves some configuration
+ * control. At the moment, only the rate of progress updates is configurable.
+ */
+class ReplicationParameterGroup extends FileMediaServiceGroup
+{
+};
+
+/**
+ * Base class for replication configuration items.
+ */
+class ReplicationConfigurationItem extends FileMediaServiceItem
+{
+};
+
+/**
+ * For Controls how frequency the replicas are notified of progress in playback (not relevant for other
+ * operations). Interval in milliseconds
+ */
+const string  ProgressUpdateIntervalItem = "progressUpdateInterval";
+class ProgressUpdateInterval extends ReplicationConfigurationItem
+{
+    int value;
+};
+
+
+/**
  * Configuration related to repository objects.
  */
 class RepositoryGroup extends FileMediaServiceGroup
@@ -69,19 +94,29 @@ class RepositoryGroup extends FileMediaServiceGroup
 };
 
 /**
+ * Base class for repository group configuration items.
+ */
+class RepositoryConfigurationItem extends FileMediaServiceItem
+{
+};
+
+/**
  * Configure the root path for storing/retreiving media files.
  */
-class RepositoryLocation extends FileMediaServiceItem
+const string RepositoryLocationItem = "repositoryLocation";
+class RepositoryLocation extends RepositoryConfigurationItem
 {
     string pathname;
 };
 
+
 const long DefaultUpdateInterval = 60; /* Update interval is specified in seconds */
 
 /**
  * Configure the background management facility.
  **/
-class BackgroundUpdates extends FileMediaServiceItem
+const string BackgroundUpdatesItem = "backgroundUpdates";
+class BackgroundUpdates extends RepositoryConfigurationItem
 {
     /**
      * Enable the background updates.
@@ -98,12 +133,13 @@ class ContainerGroup extends FileMediaServiceGroup
 {
 };
 
-class ContainerItem extends FileMediaServiceItem
+const string ContainerConfigurationItem = "containerSpecification";
+class ContainerConfiguration extends FileMediaServiceItem
 {
     /**
      * Unique id for the container. Not necessarily the object id nor the filename.
      **/
-    string catalogID;
+    string catalogId;
 
     /**
      * URI for locating the actual container.
@@ -113,7 +149,8 @@ class ContainerItem extends FileMediaServiceItem
     /**
      * Operations allowed for this container item.
      **/
-    // XXX default value name scope generation bug!! AsteriskSCF::Media::File::V1::FileOperations supportedOperations;
+    AsteriskSCF::Media::File::V1::FileOperations operations =
+        AsteriskSCF::Media::File::V1::Playback;
 };
 
 }; /* End of module V1 */
diff --git a/slice/AsteriskSCF/FileMediaService/ContainerFileIf.ice b/slice/AsteriskSCF/FileMediaService/ContainerFileIf.ice
deleted file mode 100644
index 178bc92..0000000
--- a/slice/AsteriskSCF/FileMediaService/ContainerFileIf.ice
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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/BuiltinSequences.ice>
-#include <AsteriskSCF/Media/File/FileMediaIf.ice>
-
-/**
- * The MediaContainer elements define a contract that a media container implementation should satisfy for the file media
- * service. While not defined as local interfaces, it may be desirable to instantiate collocated instances to enchance
- * performance. As such, none of the interfaces define AMD methods (AMI is always available, but may not be used on //
- * collocated proxies.
- **/
-
-module AsteriskSCF
-{
-module FileMediaService
-{
-module MediaContainer
-{
-module V1
-{
-
-/**
- *
- * Information about a container. At minimum, this includes a descriptive name and a unique id. The name may or may not
- * have significance with respect to locating the file, it is up to the implemenation. The id field however should be
- * globally unique to a *conceptual* instance of the container (replica's should share the same id).  Note: as an
- * unsliceable, concrete implemenations are free to add additional data which can be propogated through this system.
- **/
-unsliceable class ContainerInfo
-{
-    /**
-     * Descriptive name
-     */
-    string name;
-
-    /**
-     * Unique id for the container object.
-     */
-    string id;
-
-    /**
-     *  A physical resource identifier
-     */
-    string filename;
- 
-    /**
-     * The operations supported by this container. Some may only support a subset of the operations 
-     * supplied by the hosting service.
-     */
-    AsteriskSCF::Media::File::V1::FileOperations supportedOperations = 
-        AsteriskSCF::Media::File::V1::Playback;
-};
-
-sequence<ContainerInfo> ContainerInfoSeq;
-
-interface Container
-{
-    ContainerInfo getInfo();
-    
-    AsteriskSCF::Media::File::V1::FileSession* getMediaSession();
-};
-
-exception ContainerNotExist
-{
-    string id;
-};
-
-interface ContainerRepository
-{
-    ContainerInfoSeq getContainerList();
-
-    Container* getContainer(string containerId) throws ContainerNotExist;
-};
-
-}; /* End of module V1 */
-}; /* End of module MediaContainer */
-}; /* End of module FileMediaService */
-}; /* End of module AsteriskSCF */
diff --git a/slice/AsteriskSCF/Replication/FileMediaService/FileMediaServiceReplicationIf.ice b/slice/AsteriskSCF/Replication/FileMediaService/FileMediaServiceReplicationIf.ice
new file mode 100644
index 0000000..f583058
--- /dev/null
+++ b/slice/AsteriskSCF/Replication/FileMediaService/FileMediaServiceReplicationIf.ice
@@ -0,0 +1,132 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, 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/BuiltinSequences.ice>
+#include <Ice/Identity.ice>
+#include <AsteriskSCF/Media/MediaIf.ice>
+#include <AsteriskSCF/Media/File/FileMediaIf.ice>
+#include <AsteriskSCF/SessionCommunications/SessionCommunicationsIf.ice>
+
+module AsteriskSCF
+{
+
+module Replication
+{
+
+module FileMediaService
+{
+
+["suppress"]
+module V1
+{
+
+const string Version ="1";
+
+const string ComponentCategory = "FileMediaReplicatorComponent";
+const string DiscoveryCategory = "FileMediaReplicator";
+
+unsliceable class StateItem
+{
+    string key;
+};
+
+sequence<StateItem> StateItemSeq;
+
+interface StateReplicatorListener
+{
+    void stateRemoved(Ice::StringSeq itemKeys);
+    void stateRemovedForItems(StateItemSeq items);
+    void stateSet(StateItemSeq items);
+};
+
+interface StateReplicator
+{
+    void addListener(StateReplicatorListener* listener);
+    void removeListener(StateReplicatorListener* listener);
+    void setState (StateItemSeq items);
+    void removeState(Ice::StringSeq items);
+    void removeStateForItems(StateItemSeq items);
+    idempotent StateItemSeq getState(Ice::StringSeq iteKeys);
+    idempotent StateItemSeq getAllState();
+};
+
+unsliceable class SessionDefinitionState extends StateItem
+{
+    AsteriskSCF::SessionCommunications::V1::Session* parentSession;
+
+    /**
+     *
+     * The catalog identifier for the current media session.
+     *
+     */
+    string catalogId;
+
+    /**
+     *
+     * Hash/digest for the catalog (only valid for playback sessions).
+     *
+     */
+    
+    /**
+     *
+     * The stringified form of the object id for a media session.
+     *
+     */
+    string sessionObjectId;
+
+    /**
+     *
+     * The operations supported by this particular media session.
+     *
+     */
+    AsteriskSCF::Media::File::V1::FileOperations operations =
+      AsteriskSCF::Media::File::V1::Playback;
+};
+
+unsliceable class ConnectedSinksState extends StateItem
+{
+    string sessionObjectId;
+    
+    AsteriskSCF::Media::V1::StreamSinkSeq connectedSinks;
+};
+
+unsliceable class ConnectedSourceState extends StateItem
+{
+    string sessionObjectId;
+    
+    AsteriskSCF::Media::V1::StreamSourceSeq connectedSources;
+};
+
+unsliceable class PlaybackProgress extends StateItem
+{
+    string sessionObjectId;
+
+    /**
+     *
+     * Updated point in the playback. 
+     * 
+     */
+    long timestamp;
+};
+
+}; /* module V1 */
+
+}; /* module FileMediaService */
+
+}; /* module Replication */
+
+}; /* module AsteriskSCF */
diff --git a/slice/AsteriskSCF/Replication/FileMediaService/FileMediaSessionStateIf.ice b/slice/AsteriskSCF/Replication/FileMediaService/FileMediaSessionStateIf.ice
deleted file mode 100644
index 592a897..0000000
--- a/slice/AsteriskSCF/Replication/FileMediaService/FileMediaSessionStateIf.ice
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Asterisk SCF -- An open-source communications framework.
- *
- * Copyright (C) 2010, 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/BuiltinSequences.ice>
-#include <Ice/Identity.ice>
-#include <AsteriskSCF/Media/MediaIf.ice>
-
-module AsteriskSCF
-{
-
-module Replication
-{
-
-module FileMediaService
-{
-
-["suppress"]
-module V1
-{
-
-const string ComponentCategory = "FileMediaReplicator";
-const string DiscoveryCategory = "FileMediaReplicator";
-
-/***
- * TODO, replication is coming.
- */
-
-unsliceable class StateItem
-{
-};
-
-sequence<StateItem> StateItemSeq;
-
-interface ReplicationListener
-{
-    void stateRemoved(Ice::StringSeq itemKeys);
-    void stateRemovedForItems(StateItemSeq items);
-    void stateSet(StateItemSeq items);
-};
-
-interface StateReplicator
-{
-    void addListener(ReplicationListener* listener);
-    void removeListener(ReplicationListener* listener);
-    void setState (StateItemSeq items);
-    void removeState(Ice::StringSeq items);
-    void removeStateForItems(StateItemSeq items);
-    idempotent StateItemSeq getState(Ice::StringSeq iteKeys);
-    idempotent StateItemSeq getAllState();
-};
-
-}; /* module V1 */
-
-}; /* module FileMediaService */
-
-}; /* module Replication */
-
-}; /* module AsteriskSCF */
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ed09944..37e660e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -11,14 +11,15 @@ astscf_component_add_files(FileMediaService
 	Component.cpp
         LocalConfig.h
 	ContainerConfigurationAdapter.h
-	ContainerInfoImpl.cpp
-	ContainerInfoImpl.h
 	ContainerRepository.cpp
 	ContainerRepository.h
 	FileMediaServiceComponent.cpp
 	FileMediaServiceComponent.h
         ContainerImpl.cpp
         ContainerImpl.h
+	Configuration.cpp
+	Configuration.h
+	ComponentFeature.h
 	LoggerF.h
 	ReplicationListener.h
 	RepositoryConfigurationAdapter.h
@@ -35,5 +36,21 @@ astscf_component_add_boost_libraries(FileMediaService core)
 astscf_component_add_slice_collection_libraries(FileMediaService FILEMEDIASERVICE)
 astscf_component_add_slice_collection_libraries(FileMediaService ASTSCF)
 astscf_component_build_icebox(FileMediaService)
-target_link_libraries(FileMediaService logging-client astscf-ice-util-cpp)
+target_link_libraries(FileMediaService logging-client astscf-ice-util-cpp matroska2 ebml2 corec)
 astscf_component_install(FileMediaService)
+
+astscf_component_init(FileMediaServiceReplicator)
+astscf_component_add_files(FileMediaServiceReplicator
+     FileMediaServiceReplicator.cpp
+     Replicator.h
+     ReplicationListener.h
+     )
+ 
+astscf_component_add_ice_libraries(FileMediaServiceReplicator IceStorm)
+astscf_component_add_boost_libraries(FileMediaServiceReplicator core)
+astscf_component_add_slice_collection_libraries(FileMediaServiceReplicator FILESESSIONGATEWAY ASTSCF)
+astscf_component_build_icebox(FileMediaServiceReplicator)
+target_link_libraries(FileMediaServiceReplicator astscf-ice-util-cpp logging-client)
+astscf_component_install(FileMediaServiceReplicator)
+
+
diff --git a/src/Component.cpp b/src/Component.cpp
index 5c8aac9..7717c73 100644
--- a/src/Component.cpp
+++ b/src/Component.cpp
@@ -14,23 +14,27 @@
  * at the top of the source tree.
  */
 
-#include <AsteriskSCF/Component/Component.h>
+#include "ReplicationListener.h"
+#include "FileMediaServiceComponent.h"
+#include "MatroskaUtil.h"
+#include "ComponentDefs.h"
+#include "ContainerRepository.h"
+#include "Configuration.h"
 
-#include <boost/thread.hpp>
 #include <boost/shared_ptr.hpp>
+#include <boost/thread/locks.hpp>
 
+#include <AsteriskSCF/Core/Discovery/ServiceLocatorIf.h>
 #include <AsteriskSCF/Core/Routing/RoutingIf.h>
 #include <AsteriskSCF/SessionCommunications/SessionCommunicationsIf.h>
+#include <AsteriskSCF/System/Component/ConfigurationIf.h>
+#include <AsteriskSCF/System/Component/ReplicaIf.h>
 #include <AsteriskSCF/Discovery/SmartProxy.h>
 #include <AsteriskSCF/Media/File/FileMediaIf.h>
 
 #include <AsteriskSCF/Logger/IceLogger.h>
 #include <AsteriskSCF/logger.h>
 
-#include "ReplicationListener.h"
-#include "ReplicationContext.h"
-#include "FileMediaServiceComponent.h"
-
 using namespace std;
 using namespace AsteriskSCF::Core::Routing::V1;
 using namespace AsteriskSCF::Core::Discovery::V1;
@@ -52,6 +56,7 @@ public:
                 AsteriskSCF::Media::File::V1::DiscoveryCategory)
     {
     }
+    
 
     //
     // The File media service needs to perform a few things:
@@ -60,35 +65,187 @@ public:
     // - set up a replication listener, etc
     // - initialize the Container file library 
     //
-
     void onPreInitialize()
     {
-       
+        //
+        // We want to initialize the Matroska library before anything else
+        // gets started. The constructor for Matroska::Environment takes
+        // care of pretty much everything.
+        //
+        mMatroskaEnvironment.reset(new Matroska::Environment);
+    }
+
+    void onActivated()
+    {
+        mContainerRepository->updateReplicator(mReplicator);
+    }
+
+    void onStandby()
+    {
+        mContainerRepository->updateReplicator(ReplicatorSmartProxy());
     }
 
     void createReplicationStateListeners()
     {
+        //
+        // The listener is created in startListening for now. It is a
+        // little different than other implementations but serves as an
+        // experiment in alternate implemenations.  This may revert back if
+        // its problematic.
+        //
     }
 
     void stopListeningToStateReplicators()
     {
+        boost::mutex::scoped_lock lock(mReplicationStateMutex);
+        if (!mReceivingReplicationUpdates)
+        {
+            //
+            // We aren't listening for updates, so nothing to do.
+            //
+            return;
+        }
+
+        mReceivingReplicationUpdates = false;
     }
 
     void listenToStateReplicators()
     {
+        if (getReplicationContext()->getState() != AsteriskSCF::Replication::STANDBY_IN_REPLICA_GROUP)
+        {
+            {
+                boost::mutex::scoped_lock lock(mReplicationStateMutex);
+                if (mReceivingReplicationUpdates)
+                {
+                    return;
+                }
+            }
+
+            try
+            {
+                AsteriskSCF::Replication::FileMediaService::V1::StateReplicatorListenerPtr servant =
+                    AsteriskSCF::FileMediaService::ReplicationListener::create(mContainerRepository,
+                            getServiceAdapter(), mLogger);
+                mReplicatorListenerProxy = 
+                    AsteriskSCF::Replication::FileMediaService::V1::StateReplicatorListenerPrx::uncheckedCast(
+                        getServiceAdapter()->addWithUUID(servant));
+                try
+                {
+                    mReplicatorListenerProxy = 
+                        AsteriskSCF::Replication::FileMediaService::V1::StateReplicatorListenerPrx::uncheckedCast(
+                            mReplicatorListenerProxy->ice_oneway());
+                }
+                catch (const Ice::NoEndpointException&)
+                {
+                    //
+                    // If this exception is thrown it simply means that oneways
+                    // cannot be supported, mReplicatorListenerProxy's original
+                    // value will not be affected.
+                    //
+                }
+            }
+            catch (const std::exception& ex)
+            {
+                mLogger(Error) << "Unable to instantiate replication listener in " << getName() << ": " << ex.what();
+
+            }
+            catch (...)
+            {
+                mLogger(Error) << "Unable to instantiate replication listener in " << getName() <<
+                    " (unknown exception).";
+            }
+
+            //
+            // Find the replication service.
+            //
+            try
+            {
+                assert(mReplicator);
+                mReplicator->addListener(mReplicatorListenerProxy);
+                boost::mutex::scoped_lock lock(mReplicationStateMutex);
+                mReceivingReplicationUpdates = true;
+            }
+            catch (const std::exception& ex)
+            {
+                mLogger(Error) << "Unable to add listener to replication server: " << ex.what();
+                throw;
+            }
+
+        }
     }
 
     void createPrimaryServices()
     {
+        if (!mContainerRepository)
+        {
+            mContainerRepository = ContainerRepositoryImpl::create(getServiceAdapter(), getName(), mLogger);
+        }
+    }
+
+    void createBackplaneServices()
+    {
+        mConfigurationFeature =
+            createConfigurationFeature(mContainerRepository);
+        mConfigurationProxy =
+            AsteriskSCF::System::Configuration::V1::ConfigurationServicePrx::uncheckedCast(
+                mConfigurationFeature->activate(getBackplaneAdapter()));
+        mConfigurationFeature->registerFeature(this);
     }
     
     void findRemoteServices()
     {
+        if (getReplicationContext()->getState() != AsteriskSCF::Replication::ACTIVE_STANDALONE)
+        {
+            AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr replicatorParams =
+                new AsteriskSCF::Core::Discovery::V1::ServiceLocatorParams;
+            replicatorParams->category =
+                AsteriskSCF::Replication::FileMediaService::V1::DiscoveryCategory;
+            replicatorParams->service = getCommunicator()->getProperties()->getPropertyWithDefault(
+                getName() + ".StateReplicatorService", "default");
+            replicatorParams->id = getCommunicator()->getProperties()->getPropertyWithDefault(
+                getName() + ".StateReplicatorId", "");
+
+            try
+            {
+                mReplicator = AsteriskSCF::FileMediaService::ReplicatorSmartProxy(getServiceLocator(),
+                    replicatorParams, mLogger);
+            }
+            catch (const AsteriskSCF::Core::Discovery::V1::ServiceNotFound&)
+            {
+                mLogger(Error) << getName() << ": unable to get replicator from service locator. Please "
+                    "check configuration.";
+                throw;
+            }
+        }
     }
 
     void preparePrimaryServicesForDiscovery()
     {
+        //
+        // XXX: create feature for the repo or change how this is activated.
+        //
+//        mMediaServicePrx = AsteriskSCF::Media::File::V1::FileMediaServicePrx::uncheckedCast(
+//            mContainerRepository->activate(getServiceAdapter()));
     }
+
+private:
+
+    //
+    // A mutex to protect state that may change in shifting from
+    // active->standby and vice-versa.
+    //
+    boost::mutex mReplicationStateMutex;
+    ReplicatorSmartProxy mReplicator;
+    bool mReceivingReplicationUpdates;
+    
+    AsteriskSCF::Media::File::V1::FileMediaServicePrx mMediaServicePrx;
+    Matroska::EnvironmentPtr mMatroskaEnvironment;
+
+    ContainerRepositoryImplPtr mContainerRepository;
+    AsteriskSCF::Replication::FileMediaService::V1::StateReplicatorListenerPrx mReplicatorListenerProxy;
+
+    ComponentFeaturePtr mConfigurationFeature;
+    AsteriskSCF::System::Configuration::V1::ConfigurationServicePrx mConfigurationProxy;
 };
 
 } /* end of namespace FileMediaService */
diff --git a/src/ReplicationContext.h b/src/ComponentDefs.h
similarity index 51%
rename from src/ReplicationContext.h
rename to src/ComponentDefs.h
index 18305e6..cd3796d 100644
--- a/src/ReplicationContext.h
+++ b/src/ComponentDefs.h
@@ -1,7 +1,7 @@
 /*
  * Asterisk SCF -- An open-source communications framework.
  *
- * Copyright (C) 2011, Digium, Inc.
+ * Copyright (C) 2010, Digium, Inc.
  *
  * See http://www.asterisk.org for more information about
  * the Asterisk SCF project. Please do not directly contact
@@ -13,38 +13,29 @@
  * the GNU General Public License Version 2. See the LICENSE.txt file
  * at the top of the source tree.
  */
+
 #pragma once
 
-#include <AsteriskSCF/Replication/ReplicationContext.h>
-#include <AsteriskSCF/Replication/FileMediaService/FileMediaSessionStateIf.h>
-#include <boost/shared_ptr.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <AsteriskSCF/Discovery/SmartProxy.h>
+#include <AsteriskSCF/Replication/FileMediaService/FileMediaServiceReplicationIf.h>
 
 namespace AsteriskSCF
 {
 namespace FileMediaService
 {
 
-typedef AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::FileMediaService::V1::StateReplicatorPrx>
-ReplicatorSmartPrx;
-
-//
-// Forward declarations.
-//
-class ReplicationContext;
-typedef boost::shared_ptr<ReplicationContext> ReplicationContextPtr;
-
-class ReplicationContext : public AsteriskSCF::Replication::ReplicationContext
-{
-public:
-    static ReplicationContextPtr create(const AsteriskSCF::Replication::ReplicationStateType stateType);
-protected:
-    ReplicationContext(AsteriskSCF::Replication::ReplicationStateType stateType) :
-        AsteriskSCF::Replication::ReplicationContext(stateType)
-    {
-    }
-};
+/**
+ * Some simple typedefs to abbreviate code a bit. Arguably makes it
+ * a bit more readable too.
+ */
+typedef boost::unique_lock<boost::shared_mutex> UniqueLock;
+typedef boost::shared_lock<boost::shared_mutex> SharedLock;
 
+typedef AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::FileMediaService::V1::StateReplicatorPrx>
+    ReplicatorSmartProxy;
 
 } /* End of namespace FileSessionGtw */
 } /* End of namespace AsteriskSCF */
-     
+
diff --git a/src/ComponentFeature.h b/src/ComponentFeature.h
new file mode 100644
index 0000000..33dea6e
--- /dev/null
+++ b/src/ComponentFeature.h
@@ -0,0 +1,58 @@
+/*
+ * 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 "FileMediaServiceComponent.h"
+
+#include <IceUtil/Shared.h>
+#include <AsteriskSCF/Core/Discovery/ServiceLocatorIf.h>
+
+namespace AsteriskSCF
+{
+namespace FileMediaService
+{
+
+/**
+ * Helper class that wraps up details of the Component initialization.  It kind
+ * of makes it easier to avoid pulling in a lot of physical dependencies into
+ * the main component class as well as avoiding multiple member variables for
+ * each service.
+ **/
+class ComponentFeature : public IceUtil::Shared
+{
+public:
+    virtual ~ComponentFeature() {}
+
+    virtual Ice::ObjectPrx activate(const Ice::ObjectAdapterPtr& adapter) = 0;
+    virtual void registerFeature(const FileMediaServiceComponentPtr& component) = 0;
+
+    /**
+     * make final preparations.
+     */
+    virtual void makeReady(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& locator,
+        const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr& params) = 0;
+
+    /**
+     *
+     */
+    virtual void suspend() = 0;
+};
+
+typedef IceUtil::Handle<ComponentFeature> ComponentFeaturePtr;
+
+} /* End of namespace FileSessionGtw */
+} /* End of namespace AsteriskSCF */
diff --git a/src/Configuration.cpp b/src/Configuration.cpp
new file mode 100644
index 0000000..f474141
--- /dev/null
+++ b/src/Configuration.cpp
@@ -0,0 +1,377 @@
+/*
+ * 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 "Configuration.h"
+
+#include <AsteriskSCF/Configuration/FileMediaService/FileMediaServiceConfigurationIf.h>
+#include <AsteriskSCF/logger.h>
+#include <AsteriskSCF/System/Component/ConfigurationIf.h>
+
+#include <Ice/Ice.h>
+#include <IceUtil/UUID.h>
+
+using namespace AsteriskSCF::FileMediaService;
+using namespace AsteriskSCF::Configuration::FileMediaService::V1;
+using namespace AsteriskSCF::System::Configuration::V1;
+using namespace AsteriskSCF::System::Logging;
+using namespace std;
+
+namespace 
+{
+
+class ConfigurationImpl : public AsteriskSCF::System::Configuration::V1::ConfigurationService
+{
+public:
+    ConfigurationImpl(const ContainerRepositoryImplPtr& containerRepository,
+        const Logger& logger) :
+        mContainerRepository(containerRepository),
+        mRemoteServices(remoteServices),
+        mLogger(logger)
+    {
+    }
+
+    ConfigurationGroupSeq getConfiguration(const ConfigurationGroupSeq& groups, const Ice::Current&)
+    {
+        ConfigurationAdapterPtr configAdapter = mContainerRepository->getConfigurationAdapter();
+        ReplicationParameterGroupPtr replicationConfigurationGroup;
+        RepositoryGroupPtr repositoryConfigurationGroup;
+        vector<ContainerConfigurationPtr> containerConfigurations;
+        
+        ConfigurationGroupSeq result;
+        for (ConfigurationGroupSeq::const_iterator iter = groups.begin(); iter != groups.end(); ++iter)
+        {
+            //
+            // There aren't a lot of different types, so the visitor is a little overkill.
+            //
+            ReplicationParameterGroupPtr replicationParameters = ReplicationParameterGroupPtr::dynamicCast(*iter);
+            if (replicationParameters)
+            {
+                ConfigurationItemDict::const_iterator itemIter =
+                    replicationParameters->configurationItems.find(ProgressUpdateIntervalItem);
+                if (itemIter != replicationParameters->configurationItems.end())
+                {
+                    PrgoressUpdateIntervalPtr updateInterval = new ProgressUpdateInterval;
+                    updateInterval->value = configAdapter->getProgressUpdateInterval();
+                    if (!replicationConfigurationGroup)
+                    {
+                        replicationConfigurationGroup = new ReplicationParameterGroup;
+                        result.push_back(resultGroup);
+                    }
+                    replicationConfiugrationGroup->configurationItems[itemIter->first] = updateInterval;
+                }
+                continue;
+            }
+
+            RepositoryGroupPtr repositoryGroup = RepositoryGroupPtr::dynamicCast(*iter);
+            if (respositoryGroup)
+            {
+                ConfigurationItemDict::const_iterator itemIter =
+                    repositoryGroup->configurationItems.find(RepositoryLocationItem);
+                if (itemIter != repositoryGroup->configurationItems.end())
+                {
+                    RepositoryLocationPtr location = new RepositoryLocation;
+                    location->pathname = configAdapter->getRootPath();
+                    if (!repositoryConfigurationGroup)
+                    {
+                        repositoryConfigurationGroup = new RepositoryGroup;
+                        result.push_back(repositoryConfigurationGroup);
+                    }
+                    repositoryConfigurationGroup->configurationItems[itemIter->first] = location;
+                }
+                itemIter = repositoryGroup->configurationItems.find(BackgroundUpdatesItem);
+                if (itemIter != repositoryGroup->configurationItems.end())
+                {
+                    BackgroundUpdatesPtr backgroundUpdates = new BackgroundUpdates;
+                    backgroundUpdates.enabled = configAdapter->getAutoUpdateOption();
+                    backgroundUpdates.updateInterval = configAdapter->getAutoUpdateInterval();
+                    if (!repositoryConfigurationGroup)
+                    {
+                        repositoryConfigurationGroup = new RepositoryGroup;
+                        result.push_back(repositoryConfigurationGroup);
+                    }
+                    repositoryConfigurationGroup->configurationItems[itemIter->first] = backgroundUpdates;
+                }
+                continue;
+            }
+
+            ContainerConfigurationPtr containerGroup = ContainerConfigurationPtr::dynamicCast(*iter);
+            if (containerGroup)
+            {
+                ConfigurationItemDict::const_iterator itemIter =
+                    containerGroup->configurationItems.find(ContainerConfigurationItem);
+                if (itemIter != containerGroup->configurationItems.end())
+                {
+                    ContainerConfigurationPtr containerQuery =
+                        ContainerConfigurationPtr::dynamicCast(itemIter->second);
+                    if (containerQuery)
+                    {
+                        ContainerConfigurationAdapterPtr containerConfig =
+                            configAdapter->getContainer(containerQuery->catalogId);
+                        if (containerConfig)
+                        {
+                            ContainerConfigurationPtr containerData =
+                                new ContainerConfiguration;
+                            containerData->catalogId = containerConfig->catalogId();
+                            containerData->uri = containerConfig->uri();
+                            containerData->operations = containerConfig->operations();
+                        }
+                    }
+                }
+                if (!resultItems.empty())
+                {
+                    ContainerConfigurationGroupPtr resultGroup = new RepositoryGroup;
+                    resultGroup->configurationItems = resultItems;
+                    result.push_back(resultGroup);
+                }
+                continue;
+            }
+        }
+        return result;
+    }
+
+    ConfigurationGroupSeq getConfigurationAll(const ConfigurationGroupSeq& groups, const Ice::Current&)
+    {
+        ConfigurationGroupSeq result;
+        ConfigurationAdapterPtr configAdapter = mContainerRepository->getConfigurationAdapter();
+        for (ConfigurationGroupSeq::const_iterator iter = groups.begin(); iter != groups.end(); ++iter)
+        {
+
+            ReplicationParameterGroupPtr replicationParameters = ReplicationParameterGroupPtr::dynamicCast(*iter);
+            if (replicationParameters)
+            {
+                ProgressUpdateIntervalPtr updateInterval = new ProgressUpdateInterval;
+                updateInterval->value = configAdapter->getProgressInterval();
+                continue;
+            }
+            ContainerConfigurationPtr containerGroup = ContainerConfigurationPtr::dynamicCast(*iter);
+            if (containerGroup)
+            {
+                continue;
+            }
+            RepositoryGroupPtr repositoryGroup = RepositoryGroupPtr::dynamicCast(*iter);
+            if (respositoryGroup)
+            {
+                continue;
+            }
+        }
+                
+        return result;
+    }
+
+    ConfigurationGroupSeq getConfigurationGroups(const Ice::Current&)
+    {
+        ConfigurationGroupSeq groups;
+        
+        EndpointImplSeq endpointImpls = mEndpointLocator->getEndpoints();
+        for (EndpointImplSeq::const_iterator iter = endpointImpls.begin();
+             iter != endpointImpls.end(); ++iter)
+        {
+            EndpointGroupPtr endpointGroup = new EndpointGroup;
+            endpointGroup->name = (*iter)->getName();
+            groups.push_back(endpointGroup);
+        }
+        groups.push_back(new GeneralGroup);
+        return groups;
+    }
+
+    void setConfiguration(const ConfigurationGroupSeq& config, const Ice::Current&)
+    {
+        EndpointSpecificationSeq newSpecs;
+        for (ConfigurationGroupSeq::const_iterator configIter = config.begin();
+             configIter != config.end(); ++configIter)
+        {
+            EndpointGroupPtr endpointGroup = EndpointGroupPtr::dynamicCast(*configIter);
+            if (endpointGroup)
+            {
+                newSpecs.push_back(createSpecificationFromGroup(endpointGroup));
+                continue;
+            }
+            GeneralGroupPtr generalGroup = GeneralGroupPtr::dynamicCast(*configIter);
+            if (generalGroup)
+            {
+                ConfigurationItemDict::const_iterator itemIter = generalGroup->configurationItems.find(
+                    RoutingServiceItem);
+                if (itemIter != generalGroup->configurationItems.end())
+                {
+                    RoutingServicePtr routingService = RoutingServicePtr::dynamicCast(itemIter->second);
+                    if (routingService)
+                    {
+                        mRemoteServices->setRoutingServiceName(routingService->serviceName);
+                    }
+                    continue;
+                }
+
+                itemIter = generalGroup->configurationItems.find(FileMediaServiceItem);
+                if (itemIter != generalGroup->configurationItems.end())
+                {
+                    FileMediaServicePtr fileMediaService = FileMediaServicePtr::dynamicCast(itemIter->second);
+                    if (fileMediaService)
+                    {
+                        mRemoteServices->setMediaServiceName(fileMediaService->serviceName);
+                    }
+                    continue;
+                }
+
+            }
+        }
+        if (!newSpecs.empty())
+        {
+            mEndpointLocator->addEndpoints(newSpecs);
+        }
+    }
+
+    //
+    // TODO: Some configuration is not really decomposeable in this way, so I will need to look at this more
+    // closely.
+    //
+    void removeConfigurationItems(const ConfigurationGroupSeq& config, const Ice::Current&)
+    {
+        for (ConfigurationGroupSeq::const_iterator configIter = config.begin();
+             configIter != config.end(); ++configIter)
+        {
+            GeneralGroupPtr generalGroup = GeneralGroupPtr::dynamicCast(*configIter);
+            if (generalGroup)
+            {
+                for (ConfigurationItemDict::const_iterator itemIter = generalGroup->configurationItems.begin();
+                     itemIter != generalGroup->configurationItems.end(); ++itemIter)
+                {
+                    if (itemIter->first == RoutingServiceItem)
+                    {
+                        mRemoteServices->setRoutingServiceName("default");
+                    }
+                    else if (itemIter->first == FileMediaServiceItem)
+                    {
+                        mRemoteServices->setMediaServiceName("default");
+                    }
+                }
+            }
+        }
+    }
+
+    void removeConfigurationGroups(const ConfigurationGroupSeq& config, const Ice::Current&)
+    {
+        EndpointSpecificationSeq specsToRemove;
+        EndpointImplSeq endpoints = mEndpointLocator->getEndpoints();
+        for (ConfigurationGroupSeq::const_iterator configIter = config.begin();
+             configIter != config.end(); ++configIter)
+        {
+            EndpointGroupPtr endpointGroup = EndpointGroupPtr::dynamicCast(*configIter);
+            if (endpointGroup)
+            {
+                for (EndpointImplSeq::const_iterator endpointIter = endpoints.begin();
+                     endpointIter != endpoints.end(); ++endpointIter)
+                {
+                    EndpointSpecificationPtr spec = (*endpointIter)->getSpecification();
+                    if (spec->name == endpointGroup->name)
+                    {
+                        specsToRemove.push_back(spec);
+                        break;
+                    }
+                }
+            }
+
+            //
+            // General group cannot be removed.
+            //
+        }
+
+        if (!specsToRemove.empty())
+        {
+            mEndpointLocator->removeEndpoints(specsToRemove);
+        }
+    }
+private:
+    EndpointLocatorImplPtr mEndpointLocator;
+    RemoteServicesPtr mRemoteServices;
+    Logger mLogger;
+};
+typedef IceUtil::Handle<ConfigurationImpl> ConfigurationImplPtr;
+
+class ConfigurationFeature : public ComponentFeature
+{
+public:
+    ConfigurationFeature(const EndpointLocatorImplPtr& endpointLocator,
+        const RemoteServicesPtr& remoteServices, const Logger& logger) :
+        mServant(new ConfigurationImpl(endpointLocator, remoteServices, logger)),
+        mId(std::string("ascf.fsgtw.") + IceUtil::generateUUID()),
+        mLogger(logger)
+    {
+    }
+
+    Ice::ObjectPrx activate(const Ice::ObjectAdapterPtr& adapter)
+    {
+        Ice::Identity id(adapter->getCommunicator()->stringToIdentity(mId));
+        mPublicProxy = ConfigurationServicePrx::uncheckedCast(adapter->add(mServant, id));
+        mDirectProxy = ConfigurationServicePrx::uncheckedCast(adapter->createDirectProxy(id));
+        return mDirectProxy;
+    }
+
+    void registerFeature(const FileSessionGatewayComponentPtr& gatewayComponent)
+    {
+        assert(gatewayComponent);
+        if (gatewayComponent)
+        {
+            //
+            // This should be a public proxy because if we fail over to a
+            // replica, we want the proxy in discovery to be remain generally
+            // valid.
+            //
+            gatewayComponent->addFeatureProxyToBackplane(mPublicProxy, 
+                AsteriskSCF::Configuration::FileSessionGateway::V1::ConfigurationDiscoveryCategory);
+        }
+        else
+        {
+            mLogger(Error) << "Unable to register configuration service. Provided component reference is nil";
+        }
+    }
+
+    void makeReady(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& /* locator */,
+        const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr& /* params */)
+    {
+        //
+        // I do not think there is anything required here at this time.
+        //
+    }
+
+    void suspend()
+    {
+        //
+        // I do not think there is anything required here at this time.
+        //
+    }
+
+private:
+    //
+    // These variable names are pretty self-explanatory, so we will let them.
+    //
+    ConfigurationImplPtr mServant; 
+    string mId;
+    ConfigurationServicePrx mPublicProxy;
+    ConfigurationServicePrx mDirectProxy;
+    Logger mLogger;
+};
+
+typedef IceUtil::Handle<ConfigurationFeature> ConfigurationFeaturePtr;
+
+}
+
+AsteriskSCF::FileSessionGtw::ComponentFeaturePtr AsteriskSCF::FileSessionGtw::createConfigurationFeature(
+    const EndpointLocatorImplPtr& endpointLocator,
+    const RemoteServicesPtr& remoteServices)
+{
+    return new ConfigurationFeature(endpointLocator, remoteServices,
+        getLoggerFactory().getLogger(LoggerId + ".Configuration"));
+}
diff --git a/src/StreamImpl.cpp b/src/Configuration.h
similarity index 56%
rename from src/StreamImpl.cpp
rename to src/Configuration.h
index aef5ff7..8700a97 100644
--- a/src/StreamImpl.cpp
+++ b/src/Configuration.h
@@ -14,31 +14,17 @@
  * at the top of the source tree.
  */
 
-#include "StreamImpl.h"
-#include <AsteriskSCF/FileMediaService/ContainerFileIf.h>
-#include <AsteriskSCF/logger.h>
-#include <matroska/FileKax.h>
-#include <matroska/KaxSegment.h>
+#pragma once
 
-using namespace AsteriskSCF::System::Logging;
-using namespace AsteriskSCF::FileMediaService::MediaContainer::V1;
-using namespace std;
-using namespace libebml;
-using namespace libmatroska;
+#include "ComponentFeature.h"
+#include "ContainerRepository.h"
 
 namespace AsteriskSCF
 {
 namespace FileMediaService
 {
-namespace Implementation
-{
 
-StreamSinkImpl::StreamSinkImpl(const TrackWriterPtr& writer) :
-    mWriter(writer)
-{
-}
+ComponentFeaturePtr createConfigurationFeature(const ContainerRepositoryImplPtr& endpointLocator);
 
-} /* End of namespace Implementation */
 } /* End of namespace FileMediaService */
 } /* End of namespace AsteriskSCF */
-
diff --git a/src/ContainerConfigurationAdapter.h b/src/ContainerConfigurationAdapter.h
index 7a20189..1335e02 100644
--- a/src/ContainerConfigurationAdapter.h
+++ b/src/ContainerConfigurationAdapter.h
@@ -23,8 +23,6 @@ namespace AsteriskSCF
 {
 namespace FileMediaService
 {
-namespace Implementation
-{
 
 /**
  * Configuration adapter for container repository.
@@ -32,11 +30,16 @@ namespace Implementation
 class ContainerConfigurationAdapter : public IceUtil::Shared
 {
 public:
+    virtual ~ContainerConfigurationAdapter() {}
+
+    virtual std::string catalogId() = 0;
+    virtual std::string uri() = 0;
+    virtual AsteriskSCF::Media::File::V1::FileOperations operations() = 0;
+    
     virtual void update(const std::string& uri, AsteriskSCF::Media::File::V1::FileOperations supportedOperations) = 0;
 };
 
 typedef IceUtil::Handle<ContainerConfigurationAdapter> ContainerConfigurationAdapterPtr;
 
-}
-}
-}
+} /* End of namespace FileMediaService */
+} /* End of namespace AsteriskSCF */
diff --git a/src/ContainerImpl.cpp b/src/ContainerImpl.cpp
index 6f52e74..8f7cc3d 100644
--- a/src/ContainerImpl.cpp
+++ b/src/ContainerImpl.cpp
@@ -17,6 +17,7 @@
 #include "ContainerImpl.h"
 #include "ContainerRepository.h"
 
+#define BOOST_FILESYSTEM_VERSION 3
 #include <boost/thread/shared_mutex.hpp>
 #include <boost/lexical_cast.hpp>
 #include <boost/filesystem.hpp>
@@ -291,8 +292,9 @@ public:
                 const Ice::ObjectAdapterPtr& adapter,
                 const Logger& logger) :
             mId(id),
-            mLogger(logger),
             mTimeScale(trackTimecodeScale),
+            mFormat(AudioFormatPtr::dynamicCast(format)),
+            mLogger(logger),
             mAdapter(adapter),
             mSeqno(0)
         {
@@ -367,7 +369,8 @@ public:
             //
             unsigned long bytesToDecode = data->frameData.Size;
             unsigned char* buf = static_cast<unsigned char*>(data->frameData.Data);
-            timecode_t startTimecode = static_cast<timecode_t>(data->frameData.Timecode / mTimeScale);
+                        
+            timecode_t startTimecode = static_cast<timecode_t>( static_cast<double>(data->frameData.Timecode) / mTimeScale);
             size_t sampleCount = 0;
             size_t durationFactor = (mFormat->sampleSize / sizeof(buf[0])) * mFormat->sampleRate; // bits per second
 
@@ -563,6 +566,7 @@ public:
         mId(id),
         mSpec(spec),
         mLogger(logger),
+        mMatroskaEnvironment(matroskaEnvironment),
         mStream(0),
         mStarted(false)
     {
@@ -873,6 +877,7 @@ private:
     Ice::ObjectAdapterPtr mObjectAdapter;
     const string mId;
     FileMediaSpecification mSpec;
+    Logger mLogger;
     Matroska::Environment* mMatroskaEnvironment;
     boost::shared_ptr<ContainerReader> mContainerReader;
 
@@ -881,7 +886,6 @@ private:
     //
     stream* mStream;
     
-    Logger mLogger;
     CookieManager mCookieManager;
     SinkManagerSeq mSinkManagers;
     StreamSourceSeq mSources;
@@ -1273,11 +1277,12 @@ public:
 
     private:
         string mId;
-        StreamSourcePrx mSource;
-        unsigned mTrack;
         FrameWriterPtr mWriter;
-        IceUtil::Time mStartTime;
+        unsigned mTrack;
         bool mWriting;
+
+        StreamSourcePrx mSource;
+        IceUtil::Time mStartTime;
         FrameSeq mQueuedFrames;
         boost::shared_mutex mLock;
     };
diff --git a/src/ContainerImpl.h b/src/ContainerImpl.h
index e75afba..79a8a35 100644
--- a/src/ContainerImpl.h
+++ b/src/ContainerImpl.h
@@ -16,24 +16,19 @@
 
 #pragma once
 
-#include <AsteriskSCF/FileMediaService/ContainerFileIf.h>
 #include "LoggerF.h"
+#include "MatroskaUtil.h"
+#include "ContainerRepository.h"
 
-#include "ContainerInfoImpl.h"
-
-namespace Matroska
-{
-class Environment;
-}
+#include <AsteriskSCF/Media/File/FileMediaIf.h>
 
 namespace AsteriskSCF
 {
 namespace FileMediaService
 {
-namespace Implementation
-{
 
-class ContainerImpl : public AsteriskSCF::FileMediaService::MediaContainer::V1::Container
+class ContainerImpl : public IceUtil::Shared,
+                      public ReplicatedObject
 {
 public:
 
@@ -49,8 +44,7 @@ public:
 };
 typedef IceUtil::Handle<ContainerImpl>  ContainerImplPtr;
 
-} /* End of namespace Implementation */
-} /* End of namespace FileMedaiService */
+} /* End of namespace FileMediaService */
 } /* End of namespace AsteriskSCF */
 
     
diff --git a/src/ContainerInfoImpl.cpp b/src/ContainerInfoImpl.cpp
deleted file mode 100644
index 622225a..0000000
--- a/src/ContainerInfoImpl.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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 "ContainerInfoImpl.h"
-
-namespace AsteriskSCF
-{
-namespace FileMediaService
-{
-namespace Implementation
-{
-
-Ice::ObjectPtr ContainerInfoFactory::create(const std::string& typeId)
-{
-    Ice::ObjectPtr result;
-    if (typeId == AsteriskSCF::FileMediaService::MediaContainer::V1::ContainerInfo::ice_staticId())
-    {
-        result = new ContainerInfoImpl;
-    }
-    return result;
-}
-
-void ContainerInfoFactory::destroy()
-{
-    //
-    // NO-OP.
-    //
-}
-
-ContainerInfoImpl::ContainerInfoImpl(const ContainerInfoImpl& rhs) :
-    IceUtil::Shared(),
-    AsteriskSCF::FileMediaService::MediaContainer::V1::ContainerInfo(rhs),
-    mExists(false)
-{
-}
-
-ContainerInfoImpl::ContainerInfoImpl() :
-    mExists(false)
-{
-}
-
-void ContainerInfoImpl::setExistFlag(bool existsFlag)
-{
-    IceUtil::Mutex::Lock lock(mLock);
-    mExists = existsFlag;
-}
-
-bool ContainerInfoImpl::exists()
-{
-    IceUtil::Mutex::Lock lock(mLock);
-    return mExists;
-}
-
-}
-}
-}
diff --git a/src/ContainerInfoImpl.h b/src/ContainerInfoImpl.h
deleted file mode 100644
index 43fe06e..0000000
--- a/src/ContainerInfoImpl.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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 <AsteriskSCF/FileMediaService/ContainerFileIf.h>
-#include <vector>
-#include <Ice/ObjectFactory.h>
-
-namespace AsteriskSCF
-{
-namespace FileMediaService
-{
-namespace Implementation
-{
-
-/**
- *
- * Factory to register with the Ice runtime for creating instances of ContainerInfo.
- *
- */
-class ContainerInfoFactory : public Ice::ObjectFactory
-{
-public:
-    Ice::ObjectPtr create(const std::string& type);
-    void destroy();
-};
-
-/**
- * Why create a local version of container object instances? To avoid having to wrap and/or translate to
- * an internal implementation type.
- */
-class ContainerInfoImpl : public AsteriskSCF::FileMediaService::MediaContainer::V1::ContainerInfo
-{
-public:
-    ContainerInfoImpl(const ContainerInfoImpl& rhs);
-    ContainerInfoImpl();
-
-    /**
-     * Used to "flag" the container as confirmed that it exists. Containers that have registered information but do not
-     * exist may be handled differently.
-     */
-    void setExistFlag(bool exists);
-
-    /**
-     * Accessor to check whether the container that this info exists in the current repositor at the moment.
-     * "At the moment" is an important distinction as the file may be in the process of being replicated or
-     * may be pending on completion of a recording process.
-     */
-    bool exists();
-
-protected:
-    bool mExists;
-    IceUtil::Mutex mLock;
-};
-
-typedef IceUtil::Handle<ContainerInfoImpl> ContainerInfoImplPtr;
-typedef std::vector<ContainerInfoImplPtr> ContainerInfoImplSeq;
-
-} 
-}
-}
diff --git a/src/ContainerRepository.cpp b/src/ContainerRepository.cpp
index 59ee7ed..80f930e 100644
--- a/src/ContainerRepository.cpp
+++ b/src/ContainerRepository.cpp
@@ -15,10 +15,17 @@
  */
 
 #include "ContainerRepository.h"
-#include "ContainerInfoImpl.h"
 #include "ContainerImpl.h"
 #include "ContainerConfigurationAdapter.h"
 
+//
+// Use latest boost stuff. There is some sensitivity with this boost filesystem
+// and the matroska code, so I've included it up here.
+//
+#define BOOST_FILESYSTEM_VERSION 3
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/filesystem.hpp>
+
 #include <AsteriskSCF/logger.h>
 #include <AsteriskSCF/Media/File/FileMediaIf.h>
 
@@ -31,16 +38,9 @@
 
 #include "MatroskaUtil.h"
 
-//
-// Use latest boost stuff.
-//
-
-#include <boost/filesystem.hpp>
-#include <boost/thread/shared_mutex.hpp>
-
 using namespace AsteriskSCF::FileMediaService::MediaContainer::V1;
 using namespace AsteriskSCF::System::Logging;
-using namespace AsteriskSCF::FileMediaService::Implementation;
+using namespace AsteriskSCF::FileMediaService;
 using namespace AsteriskSCF::Media::File::V1;
 using namespace std;
 
@@ -130,7 +130,7 @@ private:
 
     set<string> mExtensions;
 
-    Matroska::Environment mMatroskaEnvironment;
+    Matroska::Environment* mMatroskaEnvironment;
 
     //
     // A *locked* accessor for obtaining the path string. Handy for methods that want the path,
@@ -463,7 +463,7 @@ ContainerPrx ContainerRepositoryServant::getContainer(const string& containerId,
     //
     // If we got this far, we need to create a new servant, activate it and move on!
     //
-    ContainerImplPtr newContainer(ContainerImpl::create(containerInfo, spec, mAdapter, mLogger));
+    ContainerImplPtr newContainer(ContainerImpl::create(containerInfo, spec, mMatroskaEnvironment, mAdapter, mLogger));
     return ContainerPrx::uncheckedCast(mAdapter->add(newContainer, id));
 }
 
@@ -477,6 +477,8 @@ RepositoryReplicationAdapterPtr ContainerRepositoryServant::replicationAdapter()
     return new ReplicationAdapterImpl(this, mLogger);
 }
 
+using namespace boost::filesystem;
+
 void ContainerRepositoryServant::refresh()
 {
     string pathString(getPath());
@@ -489,19 +491,19 @@ void ContainerRepositoryServant::refresh()
         return;
     }
             
-    boost::filesystem::path p(pathString);
+    path p(pathString);
     try
     {
-        if (boost::filesystem::exists(p))
+        if (exists(p))
         {
-            if (!boost::filesystem::is_directory(p))
+            if (!is_directory(p))
             {
                 mLogger(Error) << mName << ": container repository path (" << mPath << ") must be a directory";
                 return;
             }
-            vector<boost::filesystem::path> dirList;
-            for (boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator(p);
-                 i !=  boost::filesystem::directory_iterator(); ++i)
+            vector<path> dirList;
+            for (directory_iterator i = directory_iterator(p);
+                 i !=  directory_iterator(); ++i)
             {
                 dirList.push_back(i->path());
             }
@@ -520,7 +522,7 @@ void ContainerRepositoryServant::refresh()
                  containerInfo != mContainerInfoList.end(); ++containerInfo)
             {
                 bool found = false;
-                for (vector<boost::filesystem::path>::iterator filename = dirList.begin(); filename != dirList.end();
+                for (vector<path>::iterator filename = dirList.begin(); filename != dirList.end();
                      ++filename)
                 {
                     
@@ -551,10 +553,10 @@ void ContainerRepositoryServant::refresh()
             }
             if (mAutoUpdate && !dirList.empty())
             {
-                for (vector<boost::filesystem::path>::const_iterator filename = dirList.begin(); filename != dirList.end();
+                for (vector<path>::const_iterator filename = dirList.begin(); filename != dirList.end();
                      ++filename)
                 {
-                    string extension = filename->extension().string();
+                    string extension = filename->extension().native();
                     if (!extension.empty() && mExtensions.count(extension.substr(1)) == 0)
                     {
                         //
@@ -585,7 +587,7 @@ void ContainerRepositoryServant::refresh()
             mLogger(Error) << mName << ": container repository path " << mPath << " does not exist";
         }
     }
-    catch (const boost::filesystem::filesystem_error& ex)
+    catch (const filesystem_error& ex)
     {
         mLogger(Error) << mName << ": error refreshing repository from " << mPath << ": " << ex.what();
         //
diff --git a/src/ContainerRepository.h b/src/ContainerRepository.h
index ab705c2..1e9e509 100644
--- a/src/ContainerRepository.h
+++ b/src/ContainerRepository.h
@@ -16,22 +16,27 @@
 
 #pragma once
 
-#include <AsteriskSCF/FileMediaService/ContainerFileIf.h>
 #include "RepositoryConfigurationAdapter.h"
 #include "RepositoryReplicationAdapter.h"
 #include "LoggerF.h"
+#include "ReplicatedObject.h"
+
+#include <AsteriskSCF/Media/File/FileMediaIf.h>
 
 namespace AsteriskSCF
 {
 namespace FileMediaService
 {
-namespace Implementation
-{
 
-class ContainerRepositoryImpl : public AsteriskSCF::FileMediaService::MediaContainer::V1::ContainerRepository
+class ContainerRepositoryImpl : public IceUtil::Shared, public ReplicatedObject
 {
 public:
 
+    /**
+     * The media service is a type of "view" on the repository, hence the association.
+     */
+    virtual AsteriskSCF::Media::File::V1::FileMediaServicePrx mediaService() = 0;
+
     virtual RepositoryConfigurationAdapterPtr configurationAdapter() = 0;
     virtual RepositoryReplicationAdapterPtr replicationAdapter() = 0;
     
@@ -44,6 +49,5 @@ public:
 };
 typedef IceUtil::Handle<ContainerRepositoryImpl> ContainerRepositoryImplPtr;
 
-} /* End of namespace Implementation */
 } /* End of namespace FileMediaService */
 } /* End of namespace AsteriskSCF */
diff --git a/src/FileMediaServiceComponent.h b/src/FileMediaServiceComponent.h
index d9cb098..77c1425 100644
--- a/src/FileMediaServiceComponent.h
+++ b/src/FileMediaServiceComponent.h
@@ -24,10 +24,13 @@ namespace AsteriskSCF
 namespace FileMediaService
 {
 //
-// The file media service defines a derived instance of the common component base class to expose certain features as
-// public, allowing some of the initialization implementation to be moved out of the core Component.cpp.  With that in
-// mind, to keep consistency with the other component implementations there is a mismatch between this header file name
-// and its corresponding implementation source file (i.e. look in Component.cpp).
+// The file media service defines a derived instance of the common
+// component base class to expose certain features as public, allowing some
+// of the initialization implementation to be moved out of the core
+// Component.cpp.  With that in mind, to keep consistency with the other
+// component implementations there is a mismatch between this header file
+// name and its corresponding implementation source file (i.e. look in
+// Component.cpp).
 //
 class FileMediaServiceComponent : public AsteriskSCF::Component::Component
 {
@@ -47,7 +50,7 @@ public:
 
     FileMediaServiceComponent(const AsteriskSCF::System::Logging::Logger& logger,
             const std::string& componentDiscoveryCategory) :
-        Component(logger, componentDiscoveryCategory)
+        AsteriskSCF::Component::Component(logger, componentDiscoveryCategory)
     {
     }
 
@@ -57,5 +60,5 @@ private:
 };
 typedef IceUtil::Handle<FileMediaServiceComponent> FileMediaServiceComponentPtr;
 
-} /* End of namespace FileSessionGtw */
+} /* End of namespace FileMediaService */
 } /* End of namespace AsteriskSCF */
diff --git a/src/FileMediaServiceReplicator.cpp b/src/FileMediaServiceReplicator.cpp
new file mode 100644
index 0000000..a991aa8
--- /dev/null
+++ b/src/FileMediaServiceReplicator.cpp
@@ -0,0 +1,218 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010-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 <Ice/Ice.h>
... 1238 lines suppressed ...


-- 
asterisk-scf/integration/file_media_service.git



More information about the asterisk-scf-commits mailing list