Пример #1
0
        /// <summary>
        ///     Exports the tenant.
        /// </summary>
        /// <param name="tenantName">Name of the tenant.</param>
        /// <param name="packagePath">The package path.</param>
        /// <param name="metadataOnly">If true, exclude user data.</param>
        /// <param name="context">The context.</param>
        /// <exception cref="System.ArgumentNullException">
        ///     tenantName
        ///     or
        ///     tenantStorePath
        /// </exception>
        public static void ExportTenant(string tenantName, string packagePath, bool metadataOnly, IProcessingContext context = null)
        {
            if (string.IsNullOrEmpty(tenantName))
            {
                throw new ArgumentNullException("tenantName");
            }

            if (string.IsNullOrEmpty(packagePath))
            {
                throw new ArgumentNullException("packagePath");
            }

            if (context == null)
            {
                context = new ProcessingContext( );
            }

            context.Report.StartTime = DateTime.Now;

            long tenantId = TenantHelper.GetTenantId(tenantName, true);

            IDataSource source = metadataOnly
                ? (IDataSource) new TenantMetadataSource {
                TenantId = tenantId, TenantName = tenantName
            }
                : (IDataSource) new TenantSource {
                TenantId = tenantId, TenantName = tenantName
            };

            /////
            // Create source to load app data from tenant
            /////
            using ( source )
            {
                Format packageFormat = FileManager.GetExportFileFormat(packagePath);

                /////
                // Create target to write to SQLite database
                /////
                using (var target = FileManager.CreateDataTarget(packageFormat, packagePath))
                {
                    /////
                    // Copy the data
                    /////
                    var processor = new CopyProcessor(source, target, context);
                    processor.MigrateData( );
                }
            }

            context.Report.EndTime = DateTime.Now;
        }
Пример #2
0
        /// <summary>
        ///     Imports the tenant.
        /// </summary>
        /// <param name="packagePath">The package path.</param>
        /// <param name="tenantName">Name of the tenant.</param>
        /// <param name="overwrite">
        ///     if set to <c>true</c> [overwrite].
        /// </param>
        /// <param name="context">The context.</param>
        /// <exception cref="System.ArgumentNullException">tenantStorePath</exception>
        /// <exception cref="System.InvalidOperationException">
        ///     The package does not contain a tenant.
        ///     or
        /// </exception>
        /// <exception cref="System.ArgumentException">The package is corrupt.</exception>
        /// <remarks>
        ///     If a tenant with the same name already exists, an exception will be thrown.
        ///     To overwrite an existing tenant with the same name, call OverwriteTenant.
        /// </remarks>
        /// <returns>the tenant id</returns>
        private static long ImportTenant_Impl(string packagePath, string tenantName, bool overwrite, IProcessingContext context)
        {
            if (string.IsNullOrEmpty(packagePath))
            {
                throw new ArgumentNullException("packagePath");
            }

            if (context == null)
            {
                context = new ProcessingContext( );
            }

            context.Report.StartTime = DateTime.Now;

            try
            {
                /////
                // Create source to load app data from tenant
                /////
                using (var source = FileManager.CreateDataSource(packagePath))
                {
                    Metadata metadata = source.GetMetadata(context);

                    if (metadata.Type == SourceType.AppPackage)
                    {
                        throw new InvalidOperationException("The package does not contain a tenant.");
                    }

                    if (string.IsNullOrEmpty(tenantName))
                    {
                        tenantName = metadata.Name;
                    }

                    if (string.IsNullOrEmpty(tenantName))
                    {
                        throw new ArgumentException("The package is corrupt.");
                    }

                    bool deleteExistingTenant = false;

                    if (TenantExists(tenantName))
                    {
                        if (overwrite)
                        {
                            deleteExistingTenant = true;
                        }
                        else
                        {
                            throw new InvalidOperationException(string.Format("The tenant '{0}' already exists.", tenantName));
                        }
                    }

                    long userId;
                    RequestContext.TryGetUserId(out userId);

                    /////
                    // Create target to write to SQLite database
                    /////
                    using (var target = new TenantCopyTarget( ))
                    {
                        Tenant tenant;

                        /////
                        // Create the tenant.
                        /////
                        using (new GlobalAdministratorContext( ))
                        {
                            if (deleteExistingTenant)
                            {
                                Tenant existingTenant = Entity.GetByName <Tenant>(tenantName).FirstOrDefault( );

                                if (existingTenant != null)
                                {
                                    using (DatabaseContextInfo.SetContextInfo("Delete existing tenant"))
                                        using (IDbCommand command = target.CreateCommand( ))
                                        {
                                            command.CommandText = "spDeleteTenant";
                                            command.CommandType = CommandType.StoredProcedure;
                                            command.Parameters.Add(new SqlParameter("@tenantId", existingTenant.Id));
                                            command.AddParameter("@context", DbType.AnsiString, DatabaseContextInfo.GetMessageChain(userId));
                                            command.ExecuteNonQuery( );
                                        }
                                }
                            }

                            tenant             = Entity.Create <Tenant>( );
                            tenant.Name        = tenantName;
                            tenant.Description = tenantName + " tenant";
                            tenant.Save( );

                            target.TenantId = tenant.Id;
                        }

                        /////
                        // Copy the data
                        /////
                        var processor = new CopyProcessor(source, target, context);
                        processor.MigrateData( );

                        /////
                        // Commit the changes.
                        /////
                        target.Commit( );

                        return(tenant.Id);
                    }
                }
            }
            finally
            {
                ForeignKeyHelper.Trust( );

                context.Report.EndTime = DateTime.Now;
            }
        }
Пример #3
0
        /// <summary>
        ///     Imports the tenant.
        /// </summary>
        /// <returns>the tenant id</returns>
        public static void InstallGlobalTenant( )
        {
            IProcessingContext context = new ProcessingContext( );

            context.Report.Action = AppLibraryAction.InstallGlobal;
            context.Report.Arguments.Add(new KeyValuePair <string, string>("Tenant Id", "Global"));

            IDictionary <Guid, Guid> appToAppVer = new Dictionary <Guid, Guid>( );

            // Get application versions
            // It is assumed that if there is no global tenant, then there is only one version of each of the core apps
            using (IDatabaseContext dbContext = DatabaseContext.GetContext(false))
                using (IDbCommand command = dbContext.CreateCommand())
                {
                    command.CommandText = "select FromUid AppUid, AppVerUid from AppRelationship where ToUid = @solution and TypeUid = @isOfType";
                    command.AddParameterWithValue("@solution", Guids.Solution);
                    command.AddParameterWithValue("@isOfType", Guids.IsOfType);

                    using (IDataReader reader = command.ExecuteReader( ))
                    {
                        // Load appVerId for apps from app library
                        while (reader.Read( ))
                        {
                            Guid appId    = reader.GetGuid(0);
                            Guid appVerId = reader.GetGuid(1);
                            appToAppVer[appId] = appVerId;
                        }
                    }
                }

            // Install apps
            Guid[] coreApps = new[]
            {
                Guids.CoreSolution,
                Guids.ConsoleSolution,
                Guids.CoreDataSolution,
                Guids.SystemSolution
            };

            // Copy system application content from the app library into the global tenant
            foreach (Guid appId in coreApps)
            {
                // Get the AppVerId
                Guid appVerId;
                if (!appToAppVer.TryGetValue(appId, out appVerId))
                {
                    throw new Exception($"Aborting: System app {0} was not present in app library.");
                }

                context.WriteInfo($"Installing app {appId} package {appVerId} to global tenant.");

                IDataSource empty  = new EmptySource( );
                IDataSource source = new LibraryAppSource
                {
                    AppId    = appId,
                    AppVerId = appVerId,
                    AppName  = appId.ToString( )
                };
                TenantMergeTarget target = new TenantMergeTarget
                {
                    TenantId = 0
                };

                using (empty)
                    using (source)
                        using ( target )
                        {
                            MergeProcessor processor = new MergeProcessor(context)
                            {
                                OldVersion = empty,
                                NewVersion = source,
                                Target     = target
                            };
                            processor.MergeData( );

                            target.Commit( );
                        }
            }


            // Copy metadata from the tenant back into the application library
            foreach (Guid appId in coreApps)
            {
                Guid appVerId = appToAppVer[appId];

                long        solutionEntityId = Entity.GetIdFromUpgradeId(appId);
                IDataSource metadataSource   = new TenantAppSource
                {
                    SolutionId = solutionEntityId,
                    TenantId   = 0
                };
                LibraryAppTarget metadataTarget = new LibraryAppTarget
                {
                    ApplicationVersionId = appVerId
                };
                using (metadataSource)
                    using ( metadataTarget )
                    {
                        CopyProcessor processor = new CopyProcessor(metadataSource, metadataTarget, context);
                        processor.CopyMetadataOnly = true;
                        processor.MigrateData( );

                        metadataTarget.Commit( );
                    }

                context.WriteInfo($"Installed app {appId} to global tenant.");
            }
        }