context: /*
  * sones GraphDB - Community Edition - http://www.sones.com
  * Copyright (C) 2007-2011 sones GmbH
  *
  * This file is part of sones GraphDB Community Edition.
  *
  * sones GraphDB is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as published by
  * the Free Software Foundation, version 3 of the License.
  * 
  * sones GraphDB is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU Affero General Public License for more details.
  *
  * You should have received a copy of the GNU Affero General Public License
  * along with sones GraphDB. If not, see <http://www.gnu.org/licenses/>.
  * 
  */
  
  using System;
  using System.Linq;
  using System.Collections.Generic;
  using System.IdentityModel.Selectors;
  using System.IdentityModel.Tokens;
  using System.Net;
  using sones.GraphDB;
  using sones.GraphDB.Request;
  using sones.GraphDS.PluginManager;
  using sones.GraphDS.PluginManager.GraphDSPluginManager;
  using sones.GraphDSServer.ErrorHandling;
  using sones.GraphQL;
  using sones.GraphQL.Result;
  using sones.Library.Commons.Security;
  using sones.Library.Commons.Transaction;
  using sones.Library.Network.HttpServer;
  using sones.Library.Network.HttpServer.Security;
  using sones.Library.VersionedPluginManager;
  using sones.Plugins.GraphDS.Services;
  using sones.GraphDS;
  using sones.Plugins.GraphDS;
  using sones.GraphDS.UDC;
  
  namespace sones.GraphDSServer
  {
      public sealed class GraphDS_Server : IGraphDSServer
      {
          #region Data
  
          /// <summary>
          /// The internal iGraphDB instance
          /// </summary>
          private readonly IGraphDB                       _iGraphDB;
  
          /// <summary>
          /// The service guid.
          /// </summary>
          private readonly Guid                           _ID;
  
          /// <summary>
          /// The graph ds plugin manager.
          /// </summary>
          private readonly GraphDSPluginManager           _pluginManager;
  
          /// <summary>
          /// The plugins with there settings.
          /// </summary>
          private readonly GraphDSPlugins                 _plugins;
  
          /// <summary>
          /// The list of supported graph ql type instances
          /// </summary>
          private readonly Dictionary<String, IGraphQL>   _QueryLanguages;     // dictionary because we can only have one query language instance per name
          private readonly Dictionary<String, IService>   _graphDSServices;    // dictionary because only one name per service
          private readonly Dictionary<String, IDrainPipe> _DrainPipes;         // you could have multiple drainpipes with different parameters sporting the same name
          private readonly Dictionary<String, IUsageDataCollector> _usagedatacollectors; // Usage Data Collector
  
          #endregion
  
          #region Constructor
  
          /// <summary>
          /// The GraphDS server constructor.
          /// </summary>
          /// <param name="myGraphDB">The graph db instance.</param>
          /// <param name="myIPAddress">the IP adress this GraphDS Server should bind itself to</param>
          /// <param name="myPort">the port this GraphDS Server should listen on</param>
          /// <param name="PluginDefinitions">the plugins that shall be loaded and their according parameters</param>
          public GraphDS_Server(IGraphDB myGraphDB, GraphDSPlugins Plugins = null)
          {        
              _iGraphDB = myGraphDB;
              _pluginManager = new GraphDSPluginManager();
              _ID = new Guid();
              _QueryLanguages = new Dictionary<string, IGraphQL>();
              _DrainPipes = new Dictionary<string, IDrainPipe>();
              _graphDSServices = new Dictionary<String, IService>();
              _usagedatacollectors = new Dictionary<string, IUsageDataCollector>();
              _plugins = Plugins;
  
              #region Load Configured Plugins
              
              if (_plugins == null)
              {
                  #region set the defaults
                  // which are: 
                  //  GQL with GraphDB Parameter
                  #region GQL
                  List<PluginDefinition> QueryLanguages = new List<PluginDefinition>();
                  Dictionary<string, object> GQL_Parameters = new Dictionary<string, object>();
                  GQL_Parameters.Add("GraphDB", myGraphDB);
  
                  QueryLanguages.Add(new PluginDefinition("sones.gql", GQL_Parameters));
                  #endregion
  
                  _plugins = new GraphDSPlugins(QueryLanguages,null);
                  #endregion
              }
  
              // now at least the default plugins or a user setup is stored in the _plugins structure
              // iterate through and instantiate if found
              #region IGraphQL Plugins
              if (_plugins.IGraphQLPlugins != null)
              {
                  // we got QL
                  foreach (PluginDefinition _pd in _plugins.IGraphQLPlugins)
                  {
                      // load!
                      IGraphQL loaded = LoadIGraphQLPlugins(_pd);
                      
                      // add!
                      if (loaded != null)
                      {
                          _QueryLanguages.Add(_pd.NameOfPlugin, loaded);
                      }
                      //                    else
                      //                        System.Diagnostics.Debug.WriteLine("Could not load plugin " + _pd.NameOfPlugin);
                  }
              }
              #endregion
             
              #region IDrainPipe Plugins
              if (_plugins.IDrainPipePlugins != null)
              {
                  // we got IDrainPipePlugins
                  foreach (PluginDefinition _pd in _plugins.IDrainPipePlugins)
                  {
                      // load!
                      IDrainPipe loaded = LoadIDrainPipes(_pd);
                      // add!
                      if (loaded != null)
                      {
                          _DrainPipes.Add(_pd.NameOfPlugin, loaded);
                      }
                      //                    else
                      //                        System.Diagnostics.Debug.WriteLine("Could not load plugin " + _pd.NameOfPlugin);
  
                  }
              }
              #endregion
  
              #region IUsageDataCollector Plugins
              if (_plugins.IUsageDataCollectorPlugIns!= null)
              {
                  // we got IUsageDataCollector
                  foreach (PluginDefinition _pd in _plugins.IUsageDataCollectorPlugIns)
                  {
                      // load!
                      IUsageDataCollector loaded = LoadIUsageDataCollector(_pd);
                      // add!
                      if (loaded != null)
                      {
                          _usagedatacollectors.Add(_pd.NameOfPlugin, loaded);
                      }
                  }
              }
              #endregion
  
              #endregion
          }
  
          
  
          #endregion
  
          #region Plugin Loading Helpers
          /// <summary>
          /// Load the IUsageDateCollector plugins
          /// </summary>
          private IUsageDataCollector LoadIUsageDataCollector(PluginDefinition myIUsageDataCollector)
          {
              return _pluginManager.GetAndInitializePlugin<IUsageDataCollector>(myIUsageDataCollector.NameOfPlugin, myParameter: myIUsageDataCollector.PluginParameter);
          }
          /// <summary>
          /// Load the IDrainPipes plugins
          /// </summary>
          private IDrainPipe LoadIDrainPipes(PluginDefinition myIDrainPipesPlugin)
          {
              return _pluginManager.GetAndInitializePlugin<IDrainPipe>(myIDrainPipesPlugin.NameOfPlugin, myParameter: myIDrainPipesPlugin.PluginParameter);
          }
  
          /// <summary>
          /// Load the IGraphQL plugins
          /// </summary>
          private IGraphQL LoadIGraphQLPlugins(PluginDefinition myIGraphQLPlugin)
          {
              return _pluginManager.GetAndInitializePlugin<IGraphQL>(myIGraphQLPlugin.NameOfPlugin, myParameter: myIGraphQLPlugin.PluginParameter);
          }
  
          #endregion
  
          #region IGraphDSServer Member
  
          #region Start GraphDS Service
  
          public void StartService(String myServiceName, IDictionary<string, object> myParameter)
          {
              IService Service = null;
  
              if (!_graphDSServices.TryGetValue(myServiceName, out Service))
              {
                  try
                  {
                      IGraphDS GraphDS = this as IGraphDS;
                      Dictionary<string, object> Parameter = new Dictionary<string, object>();
                      Parameter.Add("GraphDS", GraphDS);
                      Service = _pluginManager.GetAndInitializePlugin<IService>(myServiceName, Parameter);
                  }
                  catch (Exception Ex)
                  {
                      throw new ServiceException("An error occured when trying to initialize " + myServiceName + "!" + Environment.NewLine + "See inner exception for details.", Ex);
                  }
                  _graphDSServices.Add(Service.PluginName, Service);
              }
              try
              {
                  Service.Start(myParameter);
              }
              catch (Exception Ex)
              {
                  throw new ServiceException("An error occured when trying to start " + myServiceName + "!" + Environment.NewLine + "See inner exception for details.", Ex);
              }
  
          }
  
          #endregion
  
          #region Stop GraphDS Service
  
          public void StopService(String myServiceName)
          {
              IService Service = null;
              if (_graphDSServices.TryGetValue(myServiceName, out Service))
              {
                  try
                  {
                      Service.Stop();
                  }
                  catch (Exception Ex)
                  {
                      throw new ServiceException("An error occured when trying to stop " + myServiceName + "!", Ex);
                  }
  
              }
              else
              {
                  throw new ServiceException("The service " + myServiceName + "is unrecognized! Maybe the service was never started.");
              }
          }
  
          #endregion
  
          #region Status
  
          public ServiceStatus GetServiceStatus(String myServiceName)
          {
              IService Service = null;
              if (_graphDSServices.TryGetValue(myServiceName, out Service))
              {
                  try
                  {
                      return Service.GetCurrentStatus();
                  }
                  catch (Exception Ex)
                  {
                      throw new ServiceException("An error occured when trying to get the current status of " + myServiceName + "!", Ex);
                  }
  
              }
              else
              {
                  throw new ServiceException("The service " + myServiceName + " is unrecognized! Maybe the service was never started.");
              }
          }
  
          #endregion
  
          #region Available Services
  
          public IEnumerable<IService> AvailableServices
          {
  
gt:             get { return _graphDSServices.Select(_ => _.Value); }