예제 #1
0
        /// <summary>
        /// Adds or updates the handler with the given job script
        /// </summary>
        public AddJobScriptResult Add(JobScriptInfo jobScriptInfo)
        {
            // Prepare the info object
            var addResult = new AddJobScriptResult();

            // Parse the content
            var jobScriptFile = JobScriptFileParser.Parse(jobScriptInfo.JobScript);

            if (jobScriptFile.ParsingFailed)
            {
                Logger.Error("Failed to parse job script: {0}", jobScriptFile.ErrorMessage);
                addResult.SetError(AddJobScriptError.ParsingFailed, jobScriptFile.ErrorMessage);
                return(addResult);
            }

            // Compile the job file
            var compileResult = JobScriptCompiler.Compile(jobScriptFile, _packageManager.GetPackagePath(jobScriptFile.PackageName));

            // Check for compilation error
            if (compileResult.ResultType == CompileResultType.Failed)
            {
                Logger.Error("Failed to compile job script: {0}", compileResult.ErrorString);
                addResult.SetError(AddJobScriptError.CompilationFailed, compileResult.ErrorString);
                return(addResult);
            }
            // Check if it already was compiled
            if (compileResult.ResultType == CompileResultType.AlreadyCompiled)
            {
                Logger.Info("Job script already exists");
            }

            // Get the settings from the job file
            HandlerSettings handlerSettings;
            var             readScuccess = JobFileHandlerSettingsReader.ReadSettingsInOwnDomain(compileResult.OutputAssembly, out handlerSettings);

            if (!readScuccess)
            {
                Logger.Error("Initializer type not found");
                addResult.SetError(AddJobScriptError.HandlerInitializerMissing, "Handler initializer type not found");
                return(addResult);
            }

            // Search for an already existing handler
            var             currentFullName = Helpers.BuildFullName(jobScriptFile.PackageName, handlerSettings.HandlerName, handlerSettings.JobName);
            HandlerInstance handlerInstance = null;

            lock (_loadedHandlers.GetSyncRoot())
            {
                bool foundExisting = false;
                foreach (var handler in _loadedHandlers)
                {
                    if (handler.Value.FullName == currentFullName)
                    {
                        // Found an existing same handler
                        handlerInstance = handler.Value;
                        foundExisting   = true;
                        break;
                    }
                }
                if (!foundExisting)
                {
                    // No handler instance found, create a new one
                    handlerInstance = new HandlerInstance(Logger, _packageManager);
                    _loadedHandlers.Add(handlerInstance.Id, handlerInstance);
                }
                // Initialize/update the values
                var replaced = handlerInstance.InitializeFromJobScript(jobScriptFile, compileResult.OutputAssembly, handlerSettings);

                if (foundExisting)
                {
                    if (replaced)
                    {
                        addResult.SetOk(handlerInstance.Id, AddJobScriptStatus.JobScriptReplaced);
                        Logger.Info(entry => entry.SetHandlerId(handlerInstance.Id), "Updated jobscript");
                    }
                    else
                    {
                        addResult.SetOk(handlerInstance.Id, AddJobScriptStatus.NoUpdateNeeded);
                        Logger.Info(entry => entry.SetHandlerId(handlerInstance.Id), "No jobscript update needed");
                    }
                    return(addResult);
                }
            }

            // Autostart if wanted
            if (handlerInstance.HandlerSettings.AutoStart)
            {
                Start(handlerInstance.Id);
            }

            // Fill the info object from the result
            addResult.SetOk(handlerInstance.Id, AddJobScriptStatus.Ok);
            Logger.Info(entry => entry.SetHandlerId(handlerInstance.Id), "Added", handlerInstance.Id);
            return(addResult);
        }
예제 #2
0
        /// <summary>
        /// Initializes the handler and everything it needs to run
        /// </summary>
        public JobScriptInitializeResult InitializeAndStart(RunningHandlerInitializeParams runningHandlerInitializeParams)
        {
            // Initialization
            _jobScriptHash = runningHandlerInitializeParams.JobHash;
            var packageName          = runningHandlerInitializeParams.PackageName;
            var currentPackageFolder = _packageManager.GetPackagePath(packageName);

            // Preparations
            var result = new JobScriptInitializeResult();

            // Assign the path to the output assembly
            var jobAssemblyPath = runningHandlerInitializeParams.JobAssemblyPath;

            // Read the settings
            IHandlerCustomSettings customSettings;

            JobFileHandlerSettingsReader.LoadAssemblyAndReadSettings(jobAssemblyPath, out _handlerSettings, out customSettings);

            // Read the package information object
            var packageInfo = _packageManager.GetInfo(packageName);

            // Search for the correct handler type in the given assemblies
            Type handlerType = null;

            foreach (var handlerAssemblyName in packageInfo.HandlerAssemblies)
            {
                // Load the assembly
                var handlerAssemblyPath = Path.Combine(currentPackageFolder, handlerAssemblyName);
                var handlerAssembly     = AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(handlerAssemblyPath));

                // Try loading the from the assembly
                Type[] types;
                try
                {
                    types = handlerAssembly.GetTypes();
                }
                catch (ReflectionTypeLoadException ex)
                {
                    result.SetError(AddJobScriptError.TypeException, ex.LoaderExceptions.First().Message);
                    return(result);
                }

                // Search for the correct handler type
                foreach (var type in types)
                {
                    if (typeof(IHandler).IsAssignableFrom(type))
                    {
                        var att = type.GetCustomAttribute <HandlerNameAttribute>(true);
                        if (att != null)
                        {
                            if (att.HandlerName == _handlerSettings.HandlerName)
                            {
                                handlerType = type;
                                break;
                            }
                        }
                    }
                }
                if (handlerType != null)
                {
                    break;
                }
            }

            if (handlerType == null)
            {
                result.SetError(AddJobScriptError.JobScriptMissing, String.Format("Handler type for handler '{0}' not found", _handlerSettings.HandlerName));
                return(result);
            }
            // Initialize the handler
            var handlerInstance = (IHandler)Activator.CreateInstance(handlerType);

            // Initialize the handler with the custom settings
            handlerInstance.InitializeCustomSettings(customSettings);
            // Attach to the logger
            handlerInstance.Logger.LogEvent += (sender, args) => Logger.Log(args.LogEntry.SetHandlerId(Id));
            // Call the virtual initialize method
            handlerInstance.Initialize();
            // Event when a job was added
            handlerInstance.EnqueueJobEvent += EnqueueJob;
            // Assign the handler
            _handler = handlerInstance;

            // Start the control thread
            _controlTaskCancelToken = new CancellationTokenSource();
            _controlTask            = new Task(ControlThread, _controlTaskCancelToken.Token);
            _controlTask.ContinueWith(t =>
            {
                Logger.Fatal(t.Exception, "Handler: '{0}' has exception", Id);
                TearDown(true);
                OnStateChangedEvent(new RunningHandlerStateChangedEventArgs(RunningHandlerState.Failed));
            }, TaskContinuationOptions.OnlyOnFaulted);
            _controlTask.Start();

            // Notify the start event
            _handler.OnStart();

            // Fill and return the info object
            result.HandlerId = Id;
            return(result);
        }