private SageActionsObserverable StartPollApination(Config config, ApinationApi apinationApi) { Log.InfoFormat("StartPollApination running with config: '{0}'", config); // Observable creation IJobDetail pollApinationJob = JobBuilder.Create <PollApinationJob>() .WithIdentity("PollApinationJob") .Build(); var cronTrigger = TriggerBuilder.Create() .StartNow() .WithCronSchedule(config.HeartBeatCronSchedule) .Build(); var schedulerFactory = new StdSchedulerFactory(); scheduler = schedulerFactory.GetScheduler(); scheduler.JobFactory = new JobFactory(apinationApi); var sageActionsObservable = new SageActionsObserverable( job: pollApinationJob, trigger: cronTrigger, scheduler: scheduler, apinationJobListener: new PollApinationJobListener(new SageActionFromJsonFactory()), config: config ); scheduler.Start(); return(sageActionsObservable); }
public void StartHeartBeatReporting(Config config) { Log.InfoFormat("HeartBeatProcessor running with config: '{0}'", config); try { var apinationApi = new ApinationApi(new WebClientHttpUtility(), config); IJobDetail heartBeatJob = JobBuilder.Create <HeartBeatJob>() .WithIdentity("HeartBeatJob") .Build(); var cronTrigger = TriggerBuilder.Create() .StartNow() .WithCronSchedule(config.HeartBeatCronSchedule) .Build(); var schedulerFactory = new StdSchedulerFactory(); scheduler = schedulerFactory.GetScheduler(); scheduler.JobFactory = new JobFactory(apinationApi); scheduler.ScheduleJob(heartBeatJob, cronTrigger); scheduler.TriggerJob(heartBeatJob.Key); scheduler.Start(); } catch (Exception ex) { Log.Error("Unknown Exception received: ", ex); } }
public SageActionsObserverable StartActionsProcessing(Config config) { var apinationApi = new ApinationApi(new WebClientHttpUtility(), config); var observable = StartPollApination(config, apinationApi); observable.Subscribe(sageActions => ProcessSageActions(sageActions, apinationApi)); return(observable); }
protected override void OnStart(string[] args) { Log.Info("********************************************************************************************************************"); Log.Info("* Sage50Connector Service starting"); Log.Info("********************************************************************************************************************"); try { AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; // retrieve config Log.Info("Retrieve Connector Config ..."); var config = new ApinationApi(new WebClientHttpUtility(), config: null).GetConnectorConfig(); Log.InfoFormat("Received Config: {0}", config); OpenCopaniesForSecurityCheck(); heartBeatProcessor = new HeartBeatReporter(); heartBeatProcessor.StartHeartBeatReporting(config); sageActionsProcessor = new SageActionsProcessor(); sageActionsProcessor.StartActionsProcessing(config); } catch (Exception ex) { Log.FatalFormat("Sage50Connector Service start failed: {0}. Trace: {1}", ex.Message, ex); // if loader exception throw, log exception with loaderException details if (ex is ReflectionTypeLoadException loaderException) { loaderException.LogLoaderExceptions((e, le) => Log.FatalFormat("Loader Exception: {0}. Trace: {1}", le.Message, le)); } // stopping service Stop(); } }
public PollApinationJob(ApinationApi api) { this.api = api; }
private static void ProcessSageActions(IEnumerable <SageAction> sageActions, ApinationApi apinationApi) { // actions can be handled in any order, this is the right place to put this logic // most of the time it will be just 1-1 action to handler assocciation try { var actions = sageActions.ToArray(); foreach (var sageAction in actions) { try { Log.InfoFormat("Create handler for action (type: {0}, id: {1}) ...", sageAction.type, sageAction.id); using (var handler = SageActionHandlerFactory.CreateHandler(sageAction.type)) { Log.InfoFormat("Handling action (type: {0}, id: {1}) ...", sageAction.type, sageAction.id); // dynamic ActionHandler generic type require derived type, not base SageAction type handler.Handle((dynamic)sageAction); Log.InfoFormat("Handling action successful (type: {0}, id: {1}) ...", sageAction.type, sageAction.id); sageAction.ProcessingStatus = new ProcessingStatus { id = sageAction.id, processingStatus = Status.SUCCESS }; // sending Success log to apination .... apinationApi.Log(new ApinationLogRecord { Status = "Success", TriggerId = sageAction.triggerId, Uid = sageAction.mainLogId, Data = "{}", Date = DateTime.Now }); } } catch (AbortException ex) { Log.Error("Handling action failed", ex); sageAction.ProcessingStatus = new ProcessingStatus { id = sageAction.id, processingStatus = Status.FAIL, error = ex.Message }; // sending ex log to apination .... var exJson = JsonConvert.SerializeObject(ex); apinationApi.Log(new ApinationLogRecord { Message = ex.Message, // https://msdn.microsoft.com/ru-ru/library/c3s1ez6e(v=vs.110).aspx Status = ex.StatusCode.ToString("G"), TriggerId = sageAction.triggerId, Uid = sageAction.mainLogId, Data = exJson, Date = DateTime.Now }); } catch (Exception ex) { Log.Error("Handling action failed", ex); sageAction.ProcessingStatus = new ProcessingStatus { id = sageAction.id, processingStatus = Status.FAIL, error = ex.Message }; // sending ex log to apination .... var exJson = JsonConvert.SerializeObject(ex); apinationApi.Log(new ApinationLogRecord { Message = ex.Message, Status = "Fail", TriggerId = sageAction.triggerId, Uid = sageAction.mainLogId, Data = exJson, Date = DateTime.Now }); } } var sageProcessingStatusJson = JsonConvert.SerializeObject(actions.Select(i => i.ProcessingStatus)); Log.InfoFormat("Sending actions processing status: {0}", sageProcessingStatusJson); var responce = apinationApi.ReportProcessingStatus(sageProcessingStatusJson); Log.InfoFormat("Actions processing status sent succesful: {0}", responce); } catch (Exception ex) { Log.Error("Process sage actions failed", ex); } }
public HeartBeatJob(ApinationApi api) { this.api = api; }
public JobFactory(ApinationApi apinationApi) { this.apinationApi = apinationApi; }