Esempio n. 1
0
        public CommunicatorObserverI(IceInternal.MetricsAdminI metrics,
                                     Ice.Instrumentation.CommunicatorObserver del)
        {
            _metrics     = metrics;
            _delegate    = del;
            _connections = new ObserverFactoryWithDelegate <ConnectionMetrics, ConnectionObserverI,
                                                            Ice.Instrumentation.ConnectionObserver>(metrics, "Connection");
            _dispatch = new ObserverFactoryWithDelegate <DispatchMetrics, DispatchObserverI,
                                                         Ice.Instrumentation.DispatchObserver>(metrics, "Dispatch");
            _invocations = new ObserverFactoryWithDelegate <InvocationMetrics, InvocationObserverI,
                                                            Ice.Instrumentation.InvocationObserver>(metrics, "Invocation");
            _threads = new ObserverFactoryWithDelegate <ThreadMetrics, ThreadObserverI,
                                                        Ice.Instrumentation.ThreadObserver>(metrics, "Thread");
            _connects = new ObserverFactoryWithDelegate <Metrics, ObserverWithDelegateI,
                                                         Ice.Instrumentation.Observer>(metrics, "ConnectionEstablishment");
            _endpointLookups = new ObserverFactoryWithDelegate <Metrics, ObserverWithDelegateI,
                                                                Ice.Instrumentation.Observer>(metrics, "EndpointLookup");

            try
            {
                _invocations.registerSubMap <RemoteMetrics>("Remote", typeof(InvocationMetrics).GetField("remotes"));
            }
            catch (Exception)
            {
                Debug.Assert(false);
            }
        }
Esempio n. 2
0
 public CommunicatorObserverI(IceInternal.MetricsAdminI metrics) : this(metrics, null)
 {
 }
Esempio n. 3
0
 public ObserverFactoryWithDelegate(IceInternal.MetricsAdminI metrics, string name) : base(metrics, name)
 {
 }
Esempio n. 4
0
        private void startService(string service, string entryPoint, string[] args)
        {
            _m.Lock();
            try
            {
                //
                // Extract the assembly name and the class name.
                //
                string err    = "ServiceManager: unable to load service '" + entryPoint + "': ";
                int    sepPos = entryPoint.IndexOf(':');
                if (sepPos != -1 && IceInternal.AssemblyUtil.platform_ == IceInternal.AssemblyUtil.Platform.Windows)
                {
                    const string driveLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
                    if (entryPoint.Length > 3 &&
                        sepPos == 1 &&
                        driveLetters.IndexOf(entryPoint[0]) != -1 &&
                        (entryPoint[2] == '\\' || entryPoint[2] == '/'))
                    {
                        sepPos = entryPoint.IndexOf(':', 3);
                    }
                }
                if (sepPos == -1)
                {
                    FailureException e = new FailureException();
                    e.reason = err + "invalid entry point format";
                    throw e;
                }

                System.Reflection.Assembly serviceAssembly = null;
                string assemblyName = entryPoint.Substring(0, sepPos);
                string className    = entryPoint.Substring(sepPos + 1);

                try
                {
                    //
                    // First try to load the assembly using Assembly.Load, which will succeed
                    // if a fully-qualified name is provided or if a partial name has been qualified
                    // in configuration. If that fails, try Assembly.LoadFrom(), which will succeed
                    // if a file name is configured or a partial name is configured and DEVPATH is used.
                    //
                    try
                    {
                        serviceAssembly = System.Reflection.Assembly.Load(assemblyName);
                    }
                    catch (System.IO.IOException ex)
                    {
                        try
                        {
                            serviceAssembly = System.Reflection.Assembly.LoadFrom(assemblyName);
                        }
                        catch (System.IO.IOException)
                        {
                            throw ex;
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    FailureException e = new FailureException(ex);
                    e.reason = err + "unable to load assembly: " + assemblyName;
                    throw e;
                }

                //
                // Instantiate the class.
                //
                System.Type c = null;
                try
                {
                    c = serviceAssembly.GetType(className, true);
                }
                catch (System.Exception ex)
                {
                    FailureException e = new FailureException(ex);
                    e.reason = err + "GetType failed for '" + className + "'";
                    throw e;
                }

                ServiceInfo info = new ServiceInfo();
                info.name   = service;
                info.status = ServiceStatus.Stopped;
                info.args   = args;

                //
                // If IceBox.UseSharedCommunicator.<name> is defined, create a
                // communicator for the service. The communicator inherits
                // from the shared communicator properties. If it's not
                // defined, add the service properties to the shared
                // commnunicator property set.
                //
                Ice.Communicator          communicator;
                IceInternal.MetricsAdminI metricsAdmin = null;
                if (_communicator.getProperties().getPropertyAsInt("IceBox.UseSharedCommunicator." + service) > 0)
                {
                    Debug.Assert(_sharedCommunicator != null);
                    communicator = _sharedCommunicator;
                    if (communicator.getObserver() is IceInternal.CommunicatorObserverI)
                    {
                        IceInternal.CommunicatorObserverI o = (IceInternal.CommunicatorObserverI)communicator.getObserver();
                        metricsAdmin = o.getMetricsAdmin();
                    }
                }
                else
                {
                    //
                    // Create the service properties. We use the communicator properties as the default
                    // properties if IceBox.InheritProperties is set.
                    //
                    Ice.InitializationData initData = new Ice.InitializationData();
                    initData.properties = createServiceProperties(service);
                    if (info.args.Length > 0)
                    {
                        //
                        // Create the service properties with the given service arguments. This should
                        // read the service config file if it's specified with --Ice.Config.
                        //
                        initData.properties = Ice.Util.createProperties(ref info.args, initData.properties);

                        //
                        // Next, parse the service "<service>.*" command line options (the Ice command
                        // line options were parsed by the createProperties above)
                        //
                        info.args = initData.properties.parseCommandLineOptions(service, info.args);
                    }

                    //
                    // Clone the logger to assign a new prefix. If one of the built-in loggers is configured
                    // don't set any logger.
                    //
                    if (initData.properties.getProperty("Ice.LogFile").Length == 0 &&
                        (initData.properties.getPropertyAsInt("Ice.UseSyslog") == 0 ||
                         IceInternal.AssemblyUtil.platform_ == IceInternal.AssemblyUtil.Platform.Windows))
                    {
                        initData.logger = _logger.cloneWithPrefix(initData.properties.getProperty("Ice.ProgramName"));
                    }

                    //
                    // If Ice metrics are enabled on the IceBox communicator, we also enable them on
                    // the service communicator.
                    //
                    if (_communicator.getObserver() is IceInternal.CommunicatorObserverI)
                    {
                        metricsAdmin      = new IceInternal.MetricsAdminI(initData.properties, initData.logger);
                        initData.observer = new IceInternal.CommunicatorObserverI(metricsAdmin);
                    }

                    //
                    // Remaining command line options are passed to the communicator. This is
                    // necessary for Ice plug-in properties (e.g.: IceSSL).
                    //
                    info.communicator = Ice.Util.initialize(ref info.args, initData);
                    communicator      = info.communicator;

                    //
                    // Ensure the metrics admin plugin uses the same property set as the
                    // communicator. This is necessary to correctly deal with runtime
                    // property updates.
                    //
                    if (metricsAdmin != null)
                    {
                        metricsAdmin.setProperties(communicator.getProperties());
                    }
                }

                try
                {
                    //
                    // Add a PropertiesAdmin facet to the service manager's communicator that provides
                    // access to this service's property set. We do this prior to instantiating the
                    // service so that the service's constructor is able to access the facet (e.g.,
                    // in case it wants to set a callback).
                    //
                    string facetName = "IceBox.Service." + info.name + ".Properties";
                    IceInternal.PropertiesAdminI propAdmin = new IceInternal.PropertiesAdminI(facetName,
                                                                                              communicator.getProperties(),
                                                                                              communicator.getLogger());
                    _communicator.addAdminFacet(propAdmin, facetName);

                    //
                    // If a metrics admin facet is setup for the service, register
                    // it with the IceBox communicator.
                    //
                    if (metricsAdmin != null)
                    {
                        _communicator.addAdminFacet(metricsAdmin, "IceBox.Service." + info.name + ".Metrics");

                        // Ensure the metrics admin facet is notified of property updates.
                        propAdmin.addUpdateCallback(metricsAdmin);
                    }

                    //
                    // Instantiate the service.
                    //
                    try
                    {
                        //
                        // If the service class provides a constructor that accepts an Ice.Communicator argument,
                        // use that in preference to the default constructor.
                        //
                        Type[] parameterTypes = new Type[1];
                        parameterTypes[0] = typeof(Ice.Communicator);
                        System.Reflection.ConstructorInfo ci = c.GetConstructor(parameterTypes);
                        if (ci != null)
                        {
                            try
                            {
                                Object[] parameters = new Object[1];
                                parameters[0] = _communicator;
                                info.service  = (Service)ci.Invoke(parameters);
                            }
                            catch (System.MethodAccessException ex)
                            {
                                FailureException e = new FailureException(ex);
                                e.reason = err + "unable to access service constructor " + className + "(Ice.Communicator)";
                                throw e;
                            }
                        }
                        else
                        {
                            //
                            // Fall back to the default constructor.
                            //
                            try
                            {
                                info.service = (Service)IceInternal.AssemblyUtil.createInstance(c);
                                if (info.service == null)
                                {
                                    FailureException e = new FailureException();
                                    e.reason = err + "no default constructor for '" + className + "'";
                                    throw e;
                                }
                            }
                            catch (System.UnauthorizedAccessException ex)
                            {
                                FailureException e = new FailureException(ex);
                                e.reason = err + "unauthorized access to default service constructor for " + className;
                                throw e;
                            }
                        }
                    }
                    catch (FailureException)
                    {
                        throw;
                    }
                    catch (System.InvalidCastException ex)
                    {
                        FailureException e = new FailureException(ex);
                        e.reason = err + "service does not implement IceBox.Service";
                        throw e;
                    }
                    catch (System.Reflection.TargetInvocationException ex)
                    {
                        if (ex.InnerException is IceBox.FailureException)
                        {
                            throw ex.InnerException;
                        }
                        else
                        {
                            FailureException e = new FailureException(ex.InnerException);
                            e.reason = err + "exception in service constructor for " + className;
                            throw e;
                        }
                    }
                    catch (System.Exception ex)
                    {
                        FailureException e = new FailureException(ex);
                        e.reason = err + "exception in service constructor " + className;
                        throw e;
                    }


                    try
                    {
                        info.service.start(service, communicator, info.args);
                    }
                    catch (FailureException)
                    {
                        throw;
                    }
                    catch (System.Exception ex)
                    {
                        FailureException e = new FailureException(ex);
                        e.reason = "exception while starting service " + service;
                        throw e;
                    }

                    info.status = ServiceStatus.Started;
                    _services.Add(info);
                }
                catch (Ice.ObjectAdapterDeactivatedException)
                {
                    //
                    // Can be raised by addAdminFacet if the service manager communicator has been shut down.
                    //
                    if (info.communicator != null)
                    {
                        destroyServiceCommunicator(service, info.communicator);
                    }
                }
                catch (System.Exception ex)
                {
                    try
                    {
                        _communicator.removeAdminFacet("IceBox.Service." + service + ".Properties");
                    }
                    catch (Ice.LocalException)
                    {
                        // Ignored
                    }

                    if (info.communicator != null)
                    {
                        destroyServiceCommunicator(service, info.communicator);
                    }

                    throw ex;
                }
            }
            finally
            {
                _m.Unlock();
            }
        }
Esempio n. 5
0
        public int run()
        {
            try
            {
                Ice.Properties properties = _communicator.getProperties();

                //
                // Create an object adapter. Services probably should NOT share
                // this object adapter, as the endpoint(s) for this object adapter
                // will most likely need to be firewalled for security reasons.
                //
                Ice.ObjectAdapter adapter = null;
                if (properties.getProperty("IceBox.ServiceManager.Endpoints").Length != 0)
                {
                    adapter = _communicator.createObjectAdapter("IceBox.ServiceManager");

                    Ice.Identity identity = new Ice.Identity();
                    identity.category = properties.getPropertyWithDefault("IceBox.InstanceName", "IceBox");
                    identity.name     = "ServiceManager";
                    adapter.add(this, identity);
                }

                //
                // Parse the property set with the prefix "IceBox.Service.". These
                // properties should have the following format:
                //
                // IceBox.Service.Foo=<assembly>:Package.Foo [args]
                //
                // We parse the service properties specified in IceBox.LoadOrder
                // first, then the ones from remaining services.
                //
                string prefix = "IceBox.Service.";
                Dictionary <string, string> services = properties.getPropertiesForPrefix(prefix);
                string[] loadOrder = properties.getPropertyAsList("IceBox.LoadOrder");
                List <StartServiceInfo> servicesInfo = new List <StartServiceInfo>();
                for (int i = 0; i < loadOrder.Length; ++i)
                {
                    if (loadOrder[i].Length > 0)
                    {
                        string key   = prefix + loadOrder[i];
                        string value = services[key];
                        if (value == null)
                        {
                            FailureException ex = new FailureException();
                            ex.reason = "ServiceManager: no service definition for `" + loadOrder[i] + "'";
                            throw ex;
                        }
                        servicesInfo.Add(new StartServiceInfo(loadOrder[i], value, _argv));
                        services.Remove(key);
                    }
                }
                foreach (KeyValuePair <string, string> entry in services)
                {
                    string name  = entry.Key.Substring(prefix.Length);
                    string value = entry.Value;
                    servicesInfo.Add(new StartServiceInfo(name, value, _argv));
                }

                //
                // Check if some services are using the shared communicator in which
                // case we create the shared communicator now with a property set which
                // is the union of all the service properties (services which are using
                // the shared communicator).
                //
                if (properties.getPropertiesForPrefix("IceBox.UseSharedCommunicator.").Count > 0)
                {
                    Ice.InitializationData initData = new Ice.InitializationData();
                    initData.properties = createServiceProperties("SharedCommunicator");
                    foreach (StartServiceInfo service in servicesInfo)
                    {
                        if (properties.getPropertyAsInt("IceBox.UseSharedCommunicator." + service.name) <= 0)
                        {
                            continue;
                        }

                        //
                        // Load the service properties using the shared communicator properties as
                        // the default properties.
                        //
                        Ice.Properties svcProperties = Ice.Util.createProperties(ref service.args, initData.properties);

                        //
                        // Erase properties from the shared communicator which don't exist in the
                        // service properties (which include the shared communicator properties
                        // overriden by the service properties).
                        //
                        Dictionary <string, string> allProps = initData.properties.getPropertiesForPrefix("");
                        foreach (string key in allProps.Keys)
                        {
                            if (svcProperties.getProperty(key).Length == 0)
                            {
                                initData.properties.setProperty(key, "");
                            }
                        }

                        //
                        // Add the service properties to the shared communicator properties.
                        //
                        foreach (KeyValuePair <string, string> entry in svcProperties.getPropertiesForPrefix(""))
                        {
                            initData.properties.setProperty(entry.Key, entry.Value);
                        }

                        //
                        // Parse <service>.* command line options (the Ice command line options
                        // were parsed by the createProperties above)
                        //
                        service.args = initData.properties.parseCommandLineOptions(service.name, service.args);
                    }

                    //
                    // If Ice metrics are enabled on the IceBox communicator, we also enable them on the
                    // shared communicator.
                    //
                    IceInternal.MetricsAdminI metricsAdmin = null;
                    if (_communicator.getObserver() is IceInternal.CommunicatorObserverI)
                    {
                        metricsAdmin      = new IceInternal.MetricsAdminI(initData.properties, Ice.Util.getProcessLogger());
                        initData.observer = new IceInternal.CommunicatorObserverI(metricsAdmin);
                    }

                    _sharedCommunicator = Ice.Util.initialize(initData);

                    //
                    // Ensure the metrics admin plugin uses the same property set as the
                    // communicator. This is necessary to correctly deal with runtime
                    // property updates.
                    //
                    if (metricsAdmin != null)
                    {
                        metricsAdmin.setProperties(_sharedCommunicator.getProperties());
                    }
                }

                foreach (StartServiceInfo s in servicesInfo)
                {
                    startService(s.name, s.entryPoint, s.args);
                }

                //
                // We may want to notify external scripts that the services
                // have started. This is done by defining the property:
                //
                // PrintServicesReady=bundleName
                //
                // Where bundleName is whatever you choose to call this set of
                // services. It will be echoed back as "bundleName ready".
                //
                // This must be done after start() has been invoked on the
                // services.
                //
                string bundleName = properties.getProperty("IceBox.PrintServicesReady");
                if (bundleName.Length > 0)
                {
                    Console.Out.WriteLine(bundleName + " ready");
                }

                //
                // Don't move after the adapter activation. This allows
                // applications to wait for the service manager to be
                // reachable before sending a signal to shutdown the
                //
                //
                Ice.Application.shutdownOnInterrupt();

                //
                // Register "this" as a facet to the Admin object and create Admin object
                //
                try
                {
                    _communicator.addAdminFacet(this, "IceBox.ServiceManager");
                    _communicator.getAdmin();
                }
                catch (Ice.ObjectAdapterDeactivatedException)
                {
                    //
                    // Expected if the communicator has been shutdown.
                    //
                }

                //
                // Start request dispatching after we've started the services.
                //
                if (adapter != null)
                {
                    try
                    {
                        adapter.activate();
                    }
                    catch (Ice.ObjectAdapterDeactivatedException)
                    {
                        //
                        // Expected if the communicator has been shutdown.
                        //
                    }
                }

                _communicator.waitForShutdown();
            }
            catch (FailureException ex)
            {
                _logger.error(ex.ToString());
                return(1);
            }
            catch (Exception ex)
            {
                _logger.error("ServiceManager: caught exception:\n" + ex.ToString());
                return(1);
            }
            finally
            {
                //
                // Invoke stop() on the services.
                //
                stopAll();
            }

            return(0);
        }
Esempio n. 6
0
    private void startService(string service, string entryPoint, string[] args)
    {
        _m.Lock();
        try
        {
            //
            // Extract the assembly name and the class name.
            //
            string err = "ServiceManager: unable to load service '" + entryPoint + "': ";
            int sepPos = entryPoint.IndexOf(':');
            if(sepPos != -1 && IceInternal.AssemblyUtil.platform_ == IceInternal.AssemblyUtil.Platform.Windows)
            {
                const string driveLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
                if(entryPoint.Length > 3 &&
                   sepPos == 1 &&
                   driveLetters.IndexOf(entryPoint[0]) != -1 &&
                   (entryPoint[2] == '\\' || entryPoint[2] == '/'))
                {
                    sepPos = entryPoint.IndexOf(':', 3);
                }
            }
            if(sepPos == -1)
            {
                FailureException e = new FailureException();
                e.reason = err + "invalid entry point format";
                throw e;
            }

            System.Reflection.Assembly serviceAssembly = null;
            string assemblyName = entryPoint.Substring(0, sepPos);
            string className = entryPoint.Substring(sepPos + 1);

            try
            {
                //
                // First try to load the assembly using Assembly.Load, which will succeed
                // if a fully-qualified name is provided or if a partial name has been qualified
                // in configuration. If that fails, try Assembly.LoadFrom(), which will succeed
                // if a file name is configured or a partial name is configured and DEVPATH is used.
                //
                try
                {
                    serviceAssembly = System.Reflection.Assembly.Load(assemblyName);
                }
                catch(System.IO.IOException ex)
                {
                    try
                    {
                        serviceAssembly = System.Reflection.Assembly.LoadFrom(assemblyName);
                    }
                    catch(System.IO.IOException)
                    {
                         throw ex;
                    }
                }
            }
            catch(System.Exception ex)
            {
                FailureException e = new FailureException(ex);
                e.reason = err + "unable to load assembly: " + assemblyName;
                throw e;
            }

            //
            // Instantiate the class.
            //
            System.Type c = null;
            try
            {
                c = serviceAssembly.GetType(className, true);
            }
            catch(System.Exception ex)
            {
                FailureException e = new FailureException(ex);
                e.reason = err + "GetType failed for '" + className + "'";
                throw e;
            }

            ServiceInfo info = new ServiceInfo();
            info.name = service;
            info.status = ServiceStatus.Stopped;
            info.args = args;
            
            //
            // If IceBox.UseSharedCommunicator.<name> is defined, create a
            // communicator for the service. The communicator inherits
            // from the shared communicator properties. If it's not
            // defined, add the service properties to the shared
            // commnunicator property set.
            //
            Ice.Communicator communicator;
            IceInternal.MetricsAdminI metricsAdmin = null;
            if(_communicator.getProperties().getPropertyAsInt("IceBox.UseSharedCommunicator." + service) > 0)
            {
                Debug.Assert(_sharedCommunicator != null);
                communicator = _sharedCommunicator;
                if(communicator.getObserver() is IceInternal.CommunicatorObserverI)
                {
                    IceInternal.CommunicatorObserverI o = (IceInternal.CommunicatorObserverI)communicator.getObserver();
                    metricsAdmin = o.getMetricsAdmin();
                }
            }
            else
            {
                //
                // Create the service properties. We use the communicator properties as the default
                // properties if IceBox.InheritProperties is set.
                //
                Ice.InitializationData initData = new Ice.InitializationData();
                initData.properties = createServiceProperties(service);
                if(info.args.Length > 0)
                {
                    //
                    // Create the service properties with the given service arguments. This should
                    // read the service config file if it's specified with --Ice.Config.
                    //
                    initData.properties = Ice.Util.createProperties(ref info.args, initData.properties);

                    //
                    // Next, parse the service "<service>.*" command line options (the Ice command
                    // line options were parsed by the createProperties above)
                    //
                    info.args = initData.properties.parseCommandLineOptions(service, info.args);
                }

                //
                // Clone the logger to assign a new prefix. If one of the built-in loggers is configured
                // don't set any logger.
                //
                if(initData.properties.getProperty("Ice.LogFile").Length == 0 &&
                   (initData.properties.getPropertyAsInt("Ice.UseSyslog") == 0 ||
                    IceInternal.AssemblyUtil.platform_ == IceInternal.AssemblyUtil.Platform.Windows))
                {
                    initData.logger = _logger.cloneWithPrefix(initData.properties.getProperty("Ice.ProgramName"));
                }

                //
                // If Ice metrics are enabled on the IceBox communicator, we also enable them on
                // the service communicator.
                // 
                if(_communicator.getObserver() is IceInternal.CommunicatorObserverI)
                {
                    metricsAdmin = new IceInternal.MetricsAdminI(initData.properties, initData.logger);
                    initData.observer = new IceInternal.CommunicatorObserverI(metricsAdmin);
                }

                //
                // Remaining command line options are passed to the communicator. This is
                // necessary for Ice plug-in properties (e.g.: IceSSL).
                //
                info.communicator = Ice.Util.initialize(ref info.args, initData);
                communicator = info.communicator;

                //
                // Ensure the metrics admin plugin uses the same property set as the
                // communicator. This is necessary to correctly deal with runtime 
                // property updates.
                //
                if(metricsAdmin != null)
                {
                    metricsAdmin.setProperties(communicator.getProperties());
                }
            }

            try
            {   
                //
                // Add a PropertiesAdmin facet to the service manager's communicator that provides
                // access to this service's property set. We do this prior to instantiating the
                // service so that the service's constructor is able to access the facet (e.g.,
                // in case it wants to set a callback).
                //
                string facetName = "IceBox.Service." + info.name + ".Properties";
                IceInternal.PropertiesAdminI propAdmin = new IceInternal.PropertiesAdminI(facetName, 
                                                                                          communicator.getProperties(), 
                                                                                          communicator.getLogger());
                _communicator.addAdminFacet(propAdmin, facetName);
                
                //
                // If a metrics admin facet is setup for the service, register
                // it with the IceBox communicator.
                //
                if(metricsAdmin != null)
                {
                    _communicator.addAdminFacet(metricsAdmin, "IceBox.Service." + info.name + ".Metrics");

                    // Ensure the metrics admin facet is notified of property updates.
                    propAdmin.addUpdateCallback(metricsAdmin);
                }

                //
                // Instantiate the service.
                //
                try
                {
                    //
                    // If the service class provides a constructor that accepts an Ice.Communicator argument,
                    // use that in preference to the default constructor.
                    //
                    Type[] parameterTypes = new Type[1];
                    parameterTypes[0] = typeof(Ice.Communicator);
                    System.Reflection.ConstructorInfo ci = c.GetConstructor(parameterTypes);
                    if(ci != null)
                    {
                        try
                        {
                            Object[] parameters = new Object[1];
                            parameters[0] = _communicator;
                            info.service = (Service)ci.Invoke(parameters);
                        }
                        catch(System.MethodAccessException ex)
                        {
                            FailureException e = new FailureException(ex);
                            e.reason = err + "unable to access service constructor " + className + "(Ice.Communicator)";
                            throw e;
                        }
                    }
                    else
                    {
                        //
                        // Fall back to the default constructor.
                        //
                        try
                        {
                            info.service = (Service)IceInternal.AssemblyUtil.createInstance(c);
                            if(info.service == null)
                            {
                                FailureException e = new FailureException();
                                e.reason = err + "no default constructor for '" + className + "'";
                                throw e;
                            }
                        }
                        catch(System.UnauthorizedAccessException ex)
                        {
                            FailureException e = new FailureException(ex);
                            e.reason = err + "unauthorized access to default service constructor for " + className;
                            throw e;
                        }
                    }
                }
                catch(FailureException)
                {
                    throw;
                }
                catch(System.InvalidCastException ex)
                {
                    FailureException e = new FailureException(ex);
                    e.reason = err + "service does not implement IceBox.Service";
                    throw e;
                }
                catch(System.Reflection.TargetInvocationException ex)
                {
                    if(ex.InnerException is IceBox.FailureException)
                    {
                        throw ex.InnerException;
                    }
                    else
                    {
                        FailureException e = new FailureException(ex.InnerException);
                        e.reason = err + "exception in service constructor for " + className;
                        throw e;
                    }
                }
                catch(System.Exception ex)
                {
                    FailureException e = new FailureException(ex);
                    e.reason = err + "exception in service constructor " + className;
                    throw e;
                }


                try
                {
                    info.service.start(service, communicator, info.args);
                }
                catch(FailureException)
                {
                    throw;
                }
                catch(System.Exception ex)
                {
                    FailureException e = new FailureException(ex);
                    e.reason = "exception while starting service " + service;
                    throw e;
                }

                info.status = ServiceStatus.Started;
                _services.Add(info);
            }
            catch(Ice.ObjectAdapterDeactivatedException)
            {
                //
                // Can be raised by addAdminFacet if the service manager communicator has been shut down.
                //
                if(info.communicator != null)
                {
                    destroyServiceCommunicator(service, info.communicator);
                }
            }
            catch(System.Exception ex)
            {
                try
                {
                    _communicator.removeAdminFacet("IceBox.Service." + service + ".Properties");
                }
                catch(Ice.LocalException)
                {
                    // Ignored
                }

                if(info.communicator != null)
                {
                    destroyServiceCommunicator(service, info.communicator);
                }

                throw ex;
            }

        }
        finally
        {
            _m.Unlock();
        }
    }
Esempio n. 7
0
    public int run()
    {
        try
        {
            Ice.Properties properties = _communicator.getProperties();

            //
            // Create an object adapter. Services probably should NOT share
            // this object adapter, as the endpoint(s) for this object adapter
            // will most likely need to be firewalled for security reasons.
            //
            Ice.ObjectAdapter adapter = null;
            if(properties.getProperty("IceBox.ServiceManager.Endpoints").Length != 0)
            {
                adapter = _communicator.createObjectAdapter("IceBox.ServiceManager");

                Ice.Identity identity = new Ice.Identity();
                identity.category = properties.getPropertyWithDefault("IceBox.InstanceName", "IceBox");
                identity.name = "ServiceManager";
                adapter.add(this, identity);
            }

            //
            // Parse the property set with the prefix "IceBox.Service.". These
            // properties should have the following format:
            //
            // IceBox.Service.Foo=<assembly>:Package.Foo [args]
            //
            // We parse the service properties specified in IceBox.LoadOrder
            // first, then the ones from remaining services.
            //
            string prefix = "IceBox.Service.";
            Dictionary<string, string> services = properties.getPropertiesForPrefix(prefix);
            string[] loadOrder = properties.getPropertyAsList("IceBox.LoadOrder");
            List<StartServiceInfo> servicesInfo = new List<StartServiceInfo>();
            for(int i = 0; i < loadOrder.Length; ++i)
            {
                if(loadOrder[i].Length > 0)
                {
                    string key = prefix + loadOrder[i];
                    string value = services[key];
                    if(value == null)
                    {
                        FailureException ex = new FailureException();
                        ex.reason = "ServiceManager: no service definition for `" + loadOrder[i] + "'";
                        throw ex;
                    }
                    servicesInfo.Add(new StartServiceInfo(loadOrder[i], value, _argv));
                    services.Remove(key);
                }
            }
            foreach(KeyValuePair<string, string> entry in services)
            {
                string name = entry.Key.Substring(prefix.Length);
                string value = entry.Value;
                servicesInfo.Add(new StartServiceInfo(name, value, _argv));
            }

            //
            // Check if some services are using the shared communicator in which
            // case we create the shared communicator now with a property set which
            // is the union of all the service properties (services which are using
            // the shared communicator).
            //
            if(properties.getPropertiesForPrefix("IceBox.UseSharedCommunicator.").Count > 0)
            {
                Ice.InitializationData initData = new Ice.InitializationData();
                initData.properties = createServiceProperties("SharedCommunicator");
                foreach(StartServiceInfo service in servicesInfo)
                {
                    if(properties.getPropertyAsInt("IceBox.UseSharedCommunicator." + service.name) <= 0)
                    {
                        continue;
                    }

                    //
                    // Load the service properties using the shared communicator properties as
                    // the default properties.
                    //
                    Ice.Properties svcProperties = Ice.Util.createProperties(ref service.args, initData.properties);

                    //
                    // Erase properties from the shared communicator which don't exist in the
                    // service properties (which include the shared communicator properties
                    // overriden by the service properties).
                    //
                    Dictionary<string, string> allProps = initData.properties.getPropertiesForPrefix("");
                    foreach(string key in allProps.Keys)
                    {
                        if(svcProperties.getProperty(key).Length == 0)
                        {
                            initData.properties.setProperty(key, "");
                        }
                    }

                    //
                    // Add the service properties to the shared communicator properties.
                    //
                    foreach(KeyValuePair<string, string> entry in svcProperties.getPropertiesForPrefix(""))
                    {
                        initData.properties.setProperty(entry.Key, entry.Value);
                    }

                    //
                    // Parse <service>.* command line options (the Ice command line options
                    // were parsed by the createProperties above)
                    //
                    service.args = initData.properties.parseCommandLineOptions(service.name, service.args);
                }

                //
                // If Ice metrics are enabled on the IceBox communicator, we also enable them on the 
                // shared communicator.
                // 
                IceInternal.MetricsAdminI metricsAdmin = null;
                if(_communicator.getObserver() is IceInternal.CommunicatorObserverI)
                {
                    metricsAdmin = new IceInternal.MetricsAdminI(initData.properties, Ice.Util.getProcessLogger());
                    initData.observer = new IceInternal.CommunicatorObserverI(metricsAdmin);
                }

                _sharedCommunicator = Ice.Util.initialize(initData);

                //
                // Ensure the metrics admin plugin uses the same property set as the
                // communicator. This is necessary to correctly deal with runtime 
                // property updates.
                //
                if(metricsAdmin != null)
                {
                    metricsAdmin.setProperties(_sharedCommunicator.getProperties());
                }
            }

            foreach(StartServiceInfo s in servicesInfo)
            {
                startService(s.name, s.entryPoint, s.args);
            }

            //
            // We may want to notify external scripts that the services
            // have started. This is done by defining the property:
            //
            // PrintServicesReady=bundleName
            //
            // Where bundleName is whatever you choose to call this set of
            // services. It will be echoed back as "bundleName ready".
            //
            // This must be done after start() has been invoked on the
            // services.
            //
            string bundleName = properties.getProperty("IceBox.PrintServicesReady");
            if(bundleName.Length > 0)
            {
                Console.Out.WriteLine(bundleName + " ready");
            }

            //
            // Don't move after the adapter activation. This allows
            // applications to wait for the service manager to be
            // reachable before sending a signal to shutdown the
            //
            //
            Ice.Application.shutdownOnInterrupt();

            //
            // Register "this" as a facet to the Admin object and create Admin object
            //
            try
            {
                _communicator.addAdminFacet(this, "IceBox.ServiceManager");
                _communicator.getAdmin();
            }
            catch(Ice.ObjectAdapterDeactivatedException)
            {
                //
                // Expected if the communicator has been shutdown.
                //
            }

            //
            // Start request dispatching after we've started the services.
            //
            if(adapter != null)
            {
                try
                {
                    adapter.activate();
                }
                catch(Ice.ObjectAdapterDeactivatedException)
                {
                    //
                    // Expected if the communicator has been shutdown.
                    //
                }
            }

            _communicator.waitForShutdown();
        }
        catch(FailureException ex)
        {
            _logger.error(ex.ToString());
            return 1;
        }
        catch(Exception ex)
        {
            _logger.error("ServiceManager: caught exception:\n" + ex.ToString());
            return 1;
        }
        finally
        {
            //
            // Invoke stop() on the services.
            //
            stopAll();
        }

        return 0;
    }