/// <summary>
 /// Get configuration
 /// </summary>
 public AdoPersistenceConfigurationSection GetConfiguration()
 {
     if (m_configuration == null)
     {
         m_configuration = ApplicationServiceContext.Current.GetService <IConfigurationManager>().GetSection <AdoPersistenceConfigurationSection>();
     }
     return(m_configuration);
 }
        /// <summary>
        /// ADO freetext constructor
        /// </summary>
        public AdoFreetextSearchService(IJobManagerService jobManager, IServiceManager serviceManager, IConfigurationManager configurationManager, IThreadPoolService threadPoolService)
        {
            this.m_configuration = configurationManager.GetSection <AdoPersistenceConfigurationSection>();

            this.m_ftiRefreshThread = new Thread(this.MonitorFreetextJob)
            {
                Name         = "ADO.NET FullText Realtime Refresh",
                IsBackground = true,
                Priority     = ThreadPriority.Lowest
            };
            this.m_ftiRefreshThread.Start();

            if (this.m_configuration.Provider.GetFilterFunction("freetext") == null)
            {
                return;                                                                      // Freetext not supported
            }
            var job = serviceManager.CreateInjected <AdoRebuildFreetextIndexJob>();

            jobManager.AddJob(job, JobStartType.TimerOnly);
            if (jobManager.GetJobSchedules(job)?.Any() != true)
            {
                jobManager.SetJobSchedule(job, new DayOfWeek[] { DayOfWeek.Saturday }, new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0));
            }

            // Subscribe to common types and events
            var appServiceProvider = ApplicationServiceContext.Current;

            appServiceProvider.GetService <IDataPersistenceService <Bundle> >().Inserted               += (o, e) => e.Data.Item.ForEach(i => this.ReIndex(i));
            appServiceProvider.GetService <IDataPersistenceService <Patient> >().Inserted              += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.GetService <IDataPersistenceService <Provider> >().Inserted             += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.GetService <IDataPersistenceService <Material> >().Inserted             += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.GetService <IDataPersistenceService <ManufacturedMaterial> >().Inserted += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.GetService <IDataPersistenceService <Entity> >().Inserted               += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.GetService <IDataPersistenceService <Place> >().Inserted               += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.GetService <IDataPersistenceService <Organization> >().Inserted        += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.GetService <IDataPersistenceService <Person> >().Inserted              += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.GetService <IDataPersistenceService <Patient> >().Updated              += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.GetService <IDataPersistenceService <Provider> >().Updated             += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.GetService <IDataPersistenceService <Material> >().Updated             += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.GetService <IDataPersistenceService <ManufacturedMaterial> >().Updated += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.GetService <IDataPersistenceService <Entity> >().Updated               += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.GetService <IDataPersistenceService <Place> >().Updated        += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.GetService <IDataPersistenceService <Organization> >().Updated += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.GetService <IDataPersistenceService <Person> >().Updated       += (o, e) => this.ReIndex(e.Data);
            appServiceProvider.Stopping += (o, e) => this.m_shutdown = true;
        }
Exemple #3
0
        /// <summary>
        /// Start the service and bind all of the sub-services
        /// </summary>
        public bool Start()
        {
            // Startup on system
            AuthenticationContext.Current = new AuthenticationContext(AuthenticationContext.SystemPrincipal);
            // notify startup
            this.Starting?.Invoke(this, EventArgs.Empty);
            if (this.m_running) return true;

            try
            {
                // Verify schema version
                using (DataContext mdc = this.GetConfiguration().Provider.GetReadonlyConnection())
                {
                    mdc.Open();
                    Version dbVer = new Version(mdc.FirstOrDefault<String>("get_sch_vrsn")),
                        oizVer = typeof(AdoPersistenceService).Assembly.GetName().Version;

                    if (oizVer < dbVer)
                        throw new InvalidOperationException(String.Format("Invalid Schema Version. SanteDB version {0} is older than the database schema version {1}", oizVer, dbVer));
                    this.m_tracer.TraceInfo("SanteDB Schema Version {0} on {1}", dbVer, this.GetConfiguration().Provider.Invariant);
                }
            }
            catch (Exception e)
            {
                this.m_tracer.TraceEvent(EventLevel.Error,  "Error starting ADO provider: {0}", e);
                throw;
            }

            // Iterate the persistence services
            foreach (var t in typeof(AdoPersistenceService).GetTypeInfo().Assembly.ExportedTypes.Where(o => o.Namespace == "SanteDB.Persistence.Data.ADO.Services.Persistence" && !o.GetTypeInfo().IsAbstract && !o.IsGenericTypeDefinition))
            {
                try
                {
                    this.m_tracer.TraceEvent(EventLevel.Informational,  "Loading {0}...", t.AssemblyQualifiedName);

                    // If the persistence service is generic then we should check if we're allowed
                    if(!t.IsGenericType || 
                        t.IsGenericType && (this.GetConfiguration().AllowedResources.Count == 0 ||
                        this.GetConfiguration().AllowedResources.Contains(t.GetGenericArguments()[0].GetCustomAttribute<XmlTypeAttribute>()?.TypeName)))
	                    ApplicationServiceContext.Current.GetService<IServiceManager>().AddServiceProvider(t);

					// Add to cache since we're here anyways

					//s_persistenceCache.Add(t.GetGenericArguments()[0], Activator.CreateInstance(t) as IAdoPersistenceService);
				}
                catch (Exception e)
                {
                    this.m_tracer.TraceEvent(EventLevel.Error,  "Error adding service {0} : {1}", t.AssemblyQualifiedName, e);
                }
            }

            // Now iterate through the map file and ensure we have all the mappings, if a class does not exist create it
            try
            {
                this.m_tracer.TraceEvent(EventLevel.Informational,  "Creating secondary model maps...");

                var map = ModelMap.Load(typeof(AdoPersistenceService).GetTypeInfo().Assembly.GetManifestResourceStream(AdoDataConstants.MapResourceName));
                foreach (var itm in map.Class)
                {
                    // Is there a persistence service?
                    var idpType = typeof(IDataPersistenceService<>);
                    Type modelClassType = Type.GetType(itm.ModelClass),
                        domainClassType = Type.GetType(itm.DomainClass);

                    // Make sure we're allowed to run this
                    if (this.GetConfiguration().AllowedResources.Count > 0 &&
                        !this.GetConfiguration().AllowedResources.Contains(modelClassType.GetCustomAttribute<XmlTypeAttribute>()?.TypeName))
                        continue;

                    idpType = idpType.MakeGenericType(modelClassType);

                    if (modelClassType.IsAbstract || domainClassType.IsAbstract) continue;

                    // Already created
                    if (ApplicationServiceContext.Current.GetService(idpType) != null)
                        continue;

                    this.m_tracer.TraceEvent(EventLevel.Verbose, "Creating map {0} > {1}", modelClassType, domainClassType);


                    if (modelClassType.GetTypeInfo().ImplementedInterfaces.Contains(typeof(IBaseEntityData)) &&
                        domainClassType.GetTypeInfo().ImplementedInterfaces.Contains(typeof(IDbBaseData)))
                    {
                        // Construct a type
                        Type pclass = null;
                        if (modelClassType.GetTypeInfo().ImplementedInterfaces.Contains(typeof(IVersionedAssociation)))
                            pclass = typeof(GenericBaseVersionedAssociationPersistenceService<,>);
                        else if (modelClassType.GetTypeInfo().ImplementedInterfaces.Contains(typeof(ISimpleAssociation)))
                            pclass = typeof(GenericBaseAssociationPersistenceService<,>);
                        else
                            pclass = typeof(GenericBasePersistenceService<,>);
                        pclass = pclass.MakeGenericType(modelClassType, domainClassType);
                        ApplicationServiceContext.Current.GetService<IServiceManager>().AddServiceProvider(pclass);
                        // Add to cache since we're here anyways
                        this.m_persistenceCache.Add(modelClassType, Activator.CreateInstance(pclass) as IAdoPersistenceService);
                    }
                    else if (modelClassType.GetTypeInfo().ImplementedInterfaces.Contains(typeof(IIdentifiedEntity)) &&
                        domainClassType.GetTypeInfo().ImplementedInterfaces.Contains(typeof(IDbIdentified)))
                    {
                        // Construct a type
                        Type pclass = null;
                        if (modelClassType.GetTypeInfo().ImplementedInterfaces.Contains(typeof(IVersionedAssociation)))
                            pclass = typeof(GenericIdentityVersionedAssociationPersistenceService<,>);
                        else if (modelClassType.GetTypeInfo().ImplementedInterfaces.Contains(typeof(ISimpleAssociation)))
                            pclass = typeof(GenericIdentityAssociationPersistenceService<,>);
                        else
                            pclass = typeof(GenericIdentityPersistenceService<,>);

                        pclass = pclass.MakeGenericType(modelClassType, domainClassType);
                        ApplicationServiceContext.Current.GetService<IServiceManager>().AddServiceProvider(pclass);
                        this.m_persistenceCache.Add(modelClassType, Activator.CreateInstance(pclass) as IAdoPersistenceService);
                    }
                    else
                        this.m_tracer.TraceEvent(EventLevel.Warning, "Classmap {0}>{1} cannot be created, ignoring", modelClassType, domainClassType);

                }
            }
            catch (Exception e)
            {
                this.m_tracer.TraceEvent(EventLevel.Error,  "Error initializing local persistence: {0}", e);
                throw e;
            }

            // Bind subscription execution
            ApplicationServiceContext.Current.GetService<IServiceManager>().AddServiceProvider(typeof(AdoSubscriptionExector));

            // Bind BI stuff
            ApplicationServiceContext.Current.GetService<IBiMetadataRepository>()?.Insert(new SanteDB.BI.Model.BiDataSourceDefinition()
            {
                IsSystemObject = true,
                MetaData = new BiMetadata()
                {
                    Version = typeof(AdoPersistenceService).Assembly.GetName().Version.ToString(),
                    Status = BiDefinitionStatus.Active,
                },
                Id = "org.santedb.bi.dataSource.main",
                Name = "main",
                ConnectionString = this.m_configuration.ReadonlyConnectionString,
                ProviderType = typeof(OrmBiDataProvider)
            });

            // Bind some basic service stuff
            ApplicationServiceContext.Current.GetService<IDataPersistenceService<Core.Model.Security.SecurityUser>>().Inserting += (o, e) =>
            {
                if (String.IsNullOrEmpty(e.Data.SecurityHash))
                    e.Data.SecurityHash = Guid.NewGuid().ToString();
            };
            ApplicationServiceContext.Current.GetService<IDataPersistenceService<Core.Model.Security.SecurityUser>>().Updating += (o, e) =>
            {
                e.Data.SecurityHash = Guid.NewGuid().ToString();
            };

            // Unload configuration when app domain unloads
            ApplicationServiceContext.Current.Stopped += (o, e) => this.m_configuration = null;

            // Attempt to cache concepts
            this.m_tracer.TraceEvent(EventLevel.Verbose, "Caching concept dictionary...");
            this.m_running = true;
            this.Started?.Invoke(this, EventArgs.Empty);

            return true;
        }
Exemple #4
0
 /// <summary>
 /// Creates a new DI injected policy manager
 /// </summary>
 public AdoRoleProvider(IConfigurationManager configurationManager, IPolicyEnforcementService pepService)
 {
     this.m_configuration = configurationManager.GetSection <AdoPersistenceConfigurationSection>();
     this.m_policyService = pepService;
 }
Exemple #5
0
 /// <summary>
 /// DI constructor
 /// </summary>
 public AdoDeviceIdentityProvider(IConfigurationManager configurationManager, IPolicyEnforcementService pepService)
 {
     this.m_policyService = pepService;
     this.m_configuration = ApplicationServiceContext.Current.GetService <IConfigurationManager>().GetSection <AdoPersistenceConfigurationSection>();
 }
        /// <summary>
        /// Configure the service
        /// </summary>
        public void Configure(SanteDBConfiguration configuration, IDictionary <string, string> settings)
        {
            var configSection = configuration.GetSection <AdoPersistenceConfigurationSection>();

            if (configSection == null)
            {
                configSection = new AdoPersistenceConfigurationSection()
                {
                    AutoInsertChildren        = true,
                    AutoUpdateExisting        = true,
                    ProviderType              = "Npgsql",
                    ReadonlyConnectionString  = "MAIN",
                    ReadWriteConnectionString = "MAIN",
                    UseFuzzyTotals            = false,
                    Validation = new EntityValidationFlags()
                    {
                        IdentifierFormat     = true,
                        IdentifierUniqueness = true,
                        ValidationLevel      = Core.BusinessRules.DetectedIssuePriorityType.Warning
                    }
                };
                configuration.AddSection(configSection);
            }

            if (settings.TryGetValue(ReadonlyConnectionSetting, out string roConnection))
            {
                configSection.ReadonlyConnectionString = roConnection;
            }

            if (settings.TryGetValue(ConnectionStringSetting, out string rwConnection))
            {
                configSection.ReadWriteConnectionString = rwConnection;
            }

            if (settings.TryGetValue(FuzzyTotalSetting, out string fuzzyTotal))
            {
                if (!Boolean.TryParse(fuzzyTotal, out bool fuzzyTotalBool))
                {
                    throw new ArgumentException($"{fuzzyTotal} is not a valid Boolean");
                }
                configSection.UseFuzzyTotals = fuzzyTotalBool;
            }

            // Service types
            var serviceTypes = new Type[] {
                typeof(SanteDB.Persistence.Data.ADO.Services.AdoApplicationIdentityProvider),
                typeof(SanteDB.Persistence.Data.ADO.Services.AdoDeviceIdentityProvider),
                typeof(SanteDB.Persistence.Data.ADO.Services.AdoIdentityProvider),
                typeof(SanteDB.Persistence.Data.ADO.Services.AdoSecurityChallengeProvider),
                typeof(SanteDB.Persistence.Data.ADO.Services.AdoSessionProvider),
                typeof(SanteDB.Persistence.Data.ADO.Services.AdoPolicyInformationService),
                typeof(SanteDB.Persistence.Data.ADO.Services.AdoRoleProvider),
                typeof(SanteDB.Persistence.Data.ADO.Services.AdoPersistenceService),
                typeof(SanteDB.Persistence.Data.ADO.Services.AdoSubscriptionExecutor),
                typeof(SanteDB.Persistence.Data.ADO.Services.AdoServiceFactory)
            };
            // Add services
            var serviceConfiguration = configuration.GetSection <ApplicationServiceContextConfigurationSection>().ServiceProviders;

            serviceConfiguration.AddRange(serviceTypes.Where(t => !serviceConfiguration.Any(c => c.Type == t)).Select(t => new TypeReferenceConfiguration(t)));
        }
 /// <summary>
 /// DI constructor
 /// </summary>
 public AdoRebuildFreetextIndexJob(IConfigurationManager configurationManager, IJobStateManagerService stateManagerService)
 {
     this.m_configuration = configurationManager.GetSection <AdoPersistenceConfigurationSection>();
     this.m_stateManager  = stateManagerService;
 }
 /// <summary>
 /// DI constructor for ADO CHallenge
 /// </summary>
 public AdoSecurityChallengeProvider(IConfigurationManager configurationManager, IPolicyEnforcementService pepService)
 {
     this.m_policyEnforcementService = pepService;
     this.m_configuration            = configurationManager.GetSection <AdoPersistenceConfigurationSection>();
     this.m_securityConfiguration    = configurationManager.GetSection <SecurityConfigurationSection>();
 }
        /// <summary>
        /// Start the service and bind all of the sub-services
        /// </summary>
        public bool Start()
        {
            // Startup on system
            using (AuthenticationContext.EnterSystemContext())
            {
                // notify startup
                this.Starting?.Invoke(this, EventArgs.Empty);
                if (this.m_running)
                {
                    return(true);
                }

                try
                {
                    // Verify schema version
                    using (DataContext mdc = this.GetConfiguration().Provider.GetReadonlyConnection())
                    {
                        mdc.Open();
                        Version dbVer  = new Version(mdc.ExecuteProcedure <String>("get_sch_vrsn")),
                                oizVer = typeof(AdoPersistenceService).Assembly.GetName().Version;

                        if (oizVer < dbVer)
                        {
                            throw new InvalidOperationException(String.Format("Invalid Schema Version. SanteDB version {0} is older than the database schema version {1}", oizVer, dbVer));
                        }
                        this.m_tracer.TraceInfo("SanteDB Schema Version {0} on {1}", dbVer, this.GetConfiguration().Provider.Invariant);
                    }
                }
                catch (Exception e)
                {
                    this.m_tracer.TraceEvent(EventLevel.Error, "Error starting ADO provider: {0}", e);
                    throw new InvalidOperationException("Could not start up ADO provider", e);
                }

                // Iterate the persistence services
                foreach (var t in typeof(AdoPersistenceService).Assembly.ExportedTypes.Where(o => o.Namespace == "SanteDB.Persistence.Data.ADO.Services.Persistence" && !o.IsAbstract && !o.IsGenericTypeDefinition))
                {
                    try
                    {
                        this.m_tracer.TraceEvent(EventLevel.Informational, "Loading {0}...", t.AssemblyQualifiedName);

                        // If the persistence service is generic then we should check if we're allowed
                        if (!t.IsGenericType ||
                            t.IsGenericType && (this.GetConfiguration().AllowedResources.Count == 0 ||
                                                this.GetConfiguration().AllowedResources.Any(r => r.Type == t.GetGenericArguments()[0])))
                        {
                            var instance = Activator.CreateInstance(t, this);
                            ApplicationServiceContext.Current.GetService <IServiceManager>().AddServiceProvider(instance);
                        }
                    }
                    catch (Exception e)
                    {
                        this.m_tracer.TraceEvent(EventLevel.Error, "Error adding service {0} : {1}", t.AssemblyQualifiedName, e);
                        throw new InvalidOperationException($"Error adding service {t.AssemblyQualifiedName}", e);
                    }
                }

                // Bind BI stuff
                ApplicationServiceContext.Current.GetService <IBiMetadataRepository>()?.Insert(new SanteDB.BI.Model.BiDataSourceDefinition()
                {
                    IsSystemObject = true,
                    MetaData       = new BiMetadata()
                    {
                        Version = typeof(AdoPersistenceService).Assembly.GetName().Version.ToString(),
                        Status  = BiDefinitionStatus.Active,
                    },
                    Id               = "org.santedb.bi.dataSource.main",
                    Name             = "main",
                    ConnectionString = this.m_configuration.ReadonlyConnectionString,
                    ProviderType     = typeof(OrmBiDataProvider)
                });

                // Bind some basic service stuff
                ApplicationServiceContext.Current.GetService <IDataPersistenceService <Core.Model.Security.SecurityUser> >().Inserting += (o, e) =>
                {
                    if (String.IsNullOrEmpty(e.Data.SecurityHash))
                    {
                        e.Data.SecurityHash = Guid.NewGuid().ToString();
                    }
                };
                ApplicationServiceContext.Current.GetService <IDataPersistenceService <Core.Model.Security.SecurityUser> >().Updating += (o, e) =>
                {
                    e.Data.SecurityHash = Guid.NewGuid().ToString();
                };

                // Unload configuration when app domain unloads
                ApplicationServiceContext.Current.Stopped += (o, e) => this.m_configuration = null;

                // Attempt to cache concepts
                this.m_tracer.TraceEvent(EventLevel.Verbose, "Caching concept dictionary...");
                this.m_running = true;
                this.Started?.Invoke(this, EventArgs.Empty);

                return(true);
            }
        }