示例#1
0
        /// <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);
        }