/// <summary> /// Execute all requested plugins. /// </summary> public PluginExecutionResult ExecutePlugins(PluginExecutionRequest request) { string pluginOutputLocation = GetRunOutputDirectory(applicationOutputDirectory, request.RunId); Directory.CreateDirectory(pluginOutputLocation); // Execute all plugins. using (new LogsharkTimer("Executed Plugins", GlobalEventTimingData.Add)) { ICollection <IPluginResponse> pluginResponses = ExecutePlugins(request.PluginsToExecute, request); int failures = pluginResponses.Count(pluginResponse => !pluginResponse.SuccessfulExecution); Log.InfoFormat("Finished executing plugins! [{0} {1}]", failures, "failure".Pluralize(failures)); return(new PluginExecutionResult(request.PluginsToExecute, pluginResponses, pluginOutputLocation)); } }
/// <summary> /// Instantiates a plugin request for the given plugin type. /// </summary> /// <param name="pluginType">The type of the plugin.</param> /// <param name="pluginExecutionRequest">The options associated with the plugin request.</param> /// <returns>IPluginRequest with all appropriate state initialized.</returns> protected IPluginRequest CreatePluginRequest(Type pluginType, PluginExecutionRequest pluginExecutionRequest) { Guid logsetHash = Guid.Parse(pluginExecutionRequest.LogsetHash); string outputDirectory = GetOutputLocation(pluginExecutionRequest.RunId); var pluginRequest = new PluginRequest(logsetHash, outputDirectory, pluginExecutionRequest.RunId); // Append all global and plugin specific arguments to the plugin argument map. foreach (string argumentKey in pluginExecutionRequest.PluginArguments.Keys) { if (argumentKey.StartsWith(pluginType.Name + ".", StringComparison.InvariantCultureIgnoreCase) || argumentKey.StartsWith("Global.", StringComparison.InvariantCultureIgnoreCase)) { pluginRequest.SetRequestArgument(argumentKey, pluginExecutionRequest.PluginArguments[argumentKey]); } } return(pluginRequest); }
/// <summary> /// Executes multiple plugins. /// </summary> protected ICollection <IPluginResponse> ExecutePlugins(IEnumerable <Type> pluginsToExecute, PluginExecutionRequest request) { var pluginResponses = new List <IPluginResponse>(); foreach (Type plugin in pluginsToExecute.OrderBy(PluginLoader.IsPostExecutionPlugin)) { IPluginResponse pluginResponse = ExecutePlugin(plugin, request, pluginResponses); pluginResponses.Add(pluginResponse); } return(pluginResponses); }
/// <summary> /// Calculates the output database name for the given plugin. If no plugin-specific database is requested, defer to the global name. /// </summary> protected string GetOutputDatabaseName(string pluginName, IPluginRequest pluginRequest, PluginExecutionRequest pluginExecutionRequest) { string pluginDatabaseNameRequestArgumentKey = String.Format("{0}.DatabaseName", pluginName); if (pluginRequest.ContainsRequestArgument(pluginDatabaseNameRequestArgumentKey)) { string requestedPluginDatabaseName = pluginRequest.GetRequestArgument(pluginDatabaseNameRequestArgumentKey).ToString(); if (!String.IsNullOrWhiteSpace(requestedPluginDatabaseName)) { Log.InfoFormat("Redirecting output from the {0} plugin to user-requested database '{1}'.", pluginName, requestedPluginDatabaseName); return(requestedPluginDatabaseName); } } return(pluginExecutionRequest.PostgresDatabaseName); }
/// <summary> /// Executes a single plugin. /// </summary> /// <param name="pluginType">The type of the plugin to execute.</param> /// <param name="pluginExecutionRequest">Plugin execution options.</param> /// <param name="previousPluginResponses">The set of plugin responses associated with the current run. Used for plugin chaining.</param> /// <returns>Response containing state about the success/failure of the plugin's execution.</returns> protected IPluginResponse ExecutePlugin(Type pluginType, PluginExecutionRequest pluginExecutionRequest, IEnumerable <IPluginResponse> previousPluginResponses) { string pluginName = pluginType.Name; // Setup plugin for execution. IPluginRequest pluginRequest = CreatePluginRequest(pluginType, pluginExecutionRequest); var pluginTimer = new LogsharkTimer("Executed Plugin", pluginName, GlobalEventTimingData.Add); // Execute plugin. IPluginResponse pluginResponse = new PluginResponse(pluginName); try { string outputDatabaseName = GetOutputDatabaseName(pluginName, pluginRequest, pluginExecutionRequest); var plugin = InitializePlugin(pluginType, pluginRequest, pluginExecutionRequest.MongoDatabaseName, outputDatabaseName, previousPluginResponses); Log.InfoFormat("Execution of {0} plugin started at {1}..", pluginName, DateTime.Now.ToString("h:mm tt", CultureInfo.InvariantCulture)); pluginResponse = plugin.Execute(); // Flush any workbooks, if this was a workbook creation plugin. if (plugin is IWorkbookCreationPlugin) { IEnumerable <string> workbookFilePaths = WriteWorkbooksToDisk(pluginRequest.OutputDirectory, plugin as IWorkbookCreationPlugin, pluginResponse, outputDatabaseName); pluginResponse.WorkbooksOutput.AddRange(workbookFilePaths); } // Publish any associated workbooks, if requested. if (pluginExecutionRequest.PublishingOptions != null && pluginExecutionRequest.PublishingOptions.PublishWorkbooks) { var restApiRequestor = new RestApiRequestor(tableauConnectionInfo.Uri, tableauConnectionInfo.Username, tableauConnectionInfo.Password, tableauConnectionInfo.Site); var workbookPublisher = new WorkbookPublisher(tableauConnectionInfo, postgresConnectionInfo, pluginExecutionRequest.PublishingOptions, restApiRequestor); ICollection <PublishedWorkbookResult> workbooksPublished = workbookPublisher.PublishWorkbooks(pluginResponse); pluginResponse.WorkbooksPublished.AddRange(workbooksPublished); } } catch (PluginInitializationException ex) { string errorMessage = String.Format("Failed to initialize {0} plugin: {1}", pluginName, ex.Message); HandlePluginExecutionFailure(pluginResponse, errorMessage, ex); } catch (PublishingException ex) { string errorMessage = String.Format("Failed to publish workbooks: {0}", ex.Message); HandlePluginExecutionFailure(pluginResponse, errorMessage, ex); } catch (Exception ex) { string errorMessage = String.Format("Encountered uncaught exception while executing plugin '{0}': {1}", pluginName, ex.GetFlattenedMessage()); HandlePluginExecutionFailure(pluginResponse, errorMessage, ex); } finally { pluginTimer.Stop(); pluginResponse.PluginRunTime = pluginTimer.Elapsed; LogExecutionOutcome(pluginResponse); } return(pluginResponse); }