/// <summary> /// Create new data quality service /// </summary> public DataQualityService(IConfigurationManager configurationManager, IServiceManager serviceProvider, IDataQualityConfigurationProviderService configurationProvider = null) { this.m_configuration = configurationManager.GetSection <DataQualityConfigurationSection>(); if (configurationProvider == null) { configurationProvider = serviceProvider.CreateInjected <LegacyRulesetConfigurationProvider>(); serviceProvider.AddServiceProvider(configurationProvider); } this.m_dataQualityConfigurationProvider = configurationProvider; this.m_serviceManager = serviceProvider; }
/// <summary> /// Creates a new instance of the ADO cache /// </summary> public AdoPersistenceService(IServiceManager serviceManager, IPolicyEnforcementService policyEnforcementService) { this.m_policyEnforcementService = policyEnforcementService; var tracer = new Tracer(AdoDataConstants.TraceSourceName); // Apply the migrations this.m_tracer.TraceInfo("Scanning for schema updates..."); // TODO: Refactor this to a common library within the ORM tooling this.GetConfiguration().Provider.UpgradeSchema("SanteDB.Persistence.Data.ADO"); try { this.m_mapper = new ModelMapper(typeof(AdoPersistenceService).Assembly.GetManifestResourceStream(AdoDataConstants.MapResourceName)); List <IQueryBuilderHack> hax = new List <IQueryBuilderHack>() { new SecurityUserEntityQueryHack(), new RelationshipGuardQueryHack(), new CreationTimeQueryHack(this.m_mapper), new EntityAddressNameQueryHack() }; if (this.GetConfiguration().DataCorrectionKeys.Any(k => k == "ConceptQueryHack")) { hax.Add(new ConceptQueryHack(this.m_mapper)); } this.m_queryBuilder = new QueryBuilder(this.m_mapper, this.GetConfiguration().Provider, hax.Where(o => o != null).ToArray() ); // Bind subscription execution serviceManager.AddServiceProvider(typeof(AdoSubscriptionExecutor)); } catch (ModelMapValidationException ex) { tracer.TraceEvent(EventLevel.Error, "Error validating model map: {0}", ex); throw ex; } catch (Exception ex) { tracer.TraceEvent(EventLevel.Error, "Error validating model map: {0}", ex); throw ex; } }
/// <summary> /// Start the daemon /// </summary> public bool Start() { this.Starting?.Invoke(this, EventArgs.Empty); // Pre-register types for serialization foreach (var itm in this.m_configuration.ResourceTypes) { if (itm.Type == typeof(Entity)) { throw new InvalidOperationException("Cannot bind MDM control to Entity or Act , only sub-classes"); } var rt = itm.Type; string typeName = $"{rt.Name}Master"; if (typeof(Entity).IsAssignableFrom(rt)) { rt = typeof(EntityMaster <>).MakeGenericType(rt); } else if (typeof(Act).IsAssignableFrom(rt)) { rt = typeof(ActMaster <>).MakeGenericType(rt); } ModelSerializationBinder.RegisterModelType(typeName, rt); } // Wait until application context is started ApplicationServiceContext.Current.Started += (o, e) => { if (this.m_matchingService == null) { this.m_traceSource.TraceWarning("The MDM Service should be using a record matching service"); } // Replace matching var mdmMatcher = this.m_serviceManager.CreateInjected <MdmRecordMatchingService>(); this.m_serviceManager.AddServiceProvider(mdmMatcher); var mdmMatchConfig = this.m_serviceManager.CreateInjected <MdmMatchConfigurationService>(); this.m_serviceManager.AddServiceProvider(mdmMatchConfig); if (this.m_matchingService != null) { this.m_serviceManager.RemoveServiceProvider(this.m_matchingService.GetType()); } if (this.m_matchConfigurationService != null) { this.m_serviceManager.RemoveServiceProvider(this.m_matchConfigurationService.GetType()); } foreach (var itm in this.m_configuration.ResourceTypes) { this.m_traceSource.TraceInfo("Adding MDM listener for {0}...", itm.Type.Name); MdmDataManagerFactory.RegisterDataManager(itm.Type); var idt = typeof(MdmResourceHandler <>).MakeGenericType(itm.Type); var ids = this.m_serviceManager.CreateInjected(idt) as IDisposable; this.m_listeners.Add(ids); this.m_serviceManager.AddServiceProvider(ids); this.m_serviceManager.AddServiceProvider(MdmDataManagerFactory.CreateMerger(itm.Type)); // Add job var jobType = typeof(MdmMatchJob <>).MakeGenericType(itm.Type); var job = this.m_serviceManager.CreateInjected(jobType) as IJob; this.m_jobManager?.AddJob(job, JobStartType.Never); } // Add an entity relationship and act relationship watcher to the persistence layer for after update // this will ensure that appropriate cleanup is performed on successful processing of data this.m_entityRelationshipService = ApplicationServiceContext.Current.GetService <IDataPersistenceService <EntityRelationship> >(); this.m_entityService = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Entity> >(); ApplicationServiceContext.Current.GetService <IDataPersistenceService <Bundle> >().Inserted += RecheckBundleTrigger; ApplicationServiceContext.Current.GetService <IDataPersistenceService <Bundle> >().Updated += RecheckBundleTrigger; ApplicationServiceContext.Current.GetService <IDataPersistenceService <Bundle> >().Obsoleted += RecheckBundleTrigger; this.m_entityRelationshipService.Inserted += RecheckRelationshipTrigger; this.m_entityRelationshipService.Updated += RecheckRelationshipTrigger; this.m_entityRelationshipService.Obsoleted += RecheckRelationshipTrigger; // Add an MDM listener for subscriptions if (this.m_subscriptionExecutor != null) { m_subscriptionExecutor.Executing += MdmSubscriptionExecuting; m_subscriptionExecutor.Executed += MdmSubscriptionExecuted; } this.m_listeners.Add(new BundleResourceInterceptor(this.m_listeners)); // Slipstream the MdmEntityProvider //EntitySource.Current = new EntitySource(new MdmEntityProvider()); // HACK: Replace any freetext service with our own this.m_serviceManager.RemoveServiceProvider(typeof(IFreetextSearchService)); m_serviceManager.AddServiceProvider(new MdmFreetextSearchService()); }; this.Started?.Invoke(this, EventArgs.Empty); return(true); }