Exemple #1
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();
            }
        }
Exemple #2
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();
        }
    }