Ejemplo n.º 1
0
        public async Task ThenTheTenancyProviderContainsTenantsAsChildrenOfTheRootTenant(int expectedTenantCount)
        {
            ITenantStore           tenantStore        = ContainerBindings.GetServiceProvider(this.scenarioContext).GetRequiredService <ITenantStore>();
            TenantCollectionResult rootTenantChildren = await tenantStore.GetChildrenAsync(tenantStore.Root.Id).ConfigureAwait(false);

            Assert.AreEqual(expectedTenantCount, rootTenantChildren.Tenants.Count);
        }
        public async Task WhenIGetTheChildrenOfTheTenantWithTheIdCalledWithMaxItemsAndCallThem(string tenantIdName, int maxItems, string childrenName)
        {
            string tenantId = this.scenarioContext.Get <string>(tenantIdName);
            TenantCollectionResult children = await this.store.GetChildrenAsync(tenantId, maxItems).ConfigureAwait(false);

            this.scenarioContext.Set(children, childrenName);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Executes the command.
        /// </summary>
        /// <param name="app">The current <c>CommandLineApplication</c>.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        public async Task OnExecute(CommandLineApplication app)
        {
            if (string.IsNullOrEmpty(this.TenantId))
            {
                this.TenantId = this.tenantStore.Root.Id;
            }

            string?continuationToken = null;

            var childTenantIds = new List <string>();

            do
            {
                TenantCollectionResult children = await this.tenantStore.GetChildrenAsync(
                    this.TenantId,
                    20,
                    continuationToken).ConfigureAwait(false);

                childTenantIds.AddRange(children.Tenants);

                continuationToken = children.ContinuationToken;
            }while (!string.IsNullOrEmpty(continuationToken));

            if (this.Name || this.IncludeProperties?.Length > 0)
            {
                await this.LoadAndOutputTenantDetailsAsync(childTenantIds, app.Out).ConfigureAwait(false);
            }
            else
            {
                OutputTenantIds(childTenantIds, app.Out);
            }
        }
Ejemplo n.º 4
0
        public async Task <OpenApiResult> GetChildrenAsync(
            string tenantId,
            int?maxItems,
            string continuationToken,
            IOpenApiContext context)
        {
            if (string.IsNullOrEmpty(tenantId))
            {
                throw new OpenApiBadRequestException("Bad request");
            }

            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            try
            {
                TenantCollectionResult result = await this.tenantStore.GetChildrenAsync(tenantId, maxItems ?? 20, continuationToken).ConfigureAwait(false);

                HalDocument document = await this.tenantCollectionResultMapper.MapAsync(result).ConfigureAwait(false);

                if (result.ContinuationToken != null)
                {
                    OpenApiWebLink link = maxItems.HasValue
                        ? this.linkResolver.ResolveByOperationIdAndRelationType(GetChildrenOperationId, "next", ("tenantId", tenantId), ("continuationToken", result.ContinuationToken), ("maxItems", maxItems))
                        : this.linkResolver.ResolveByOperationIdAndRelationType(GetChildrenOperationId, "next", ("tenantId", tenantId), ("continuationToken", result.ContinuationToken));
                    document.AddLink("next", link);
                }

                var values = new List <(string, object?)> {
                    ("tenantId", tenantId)
                };
                if (maxItems.HasValue)
                {
                    values.Add(("maxItems", maxItems));
                }

                if (!string.IsNullOrEmpty(continuationToken))
                {
                    values.Add(("continuationToken", continuationToken));
                }

                OpenApiWebLink selfLink = this.linkResolver.ResolveByOperationIdAndRelationType(GetChildrenOperationId, "self", values.ToArray());
                document.AddLink("self", selfLink);

                return(this.OkResult(document, "application/json"));
            }
            catch (TenantNotFoundException)
            {
                return(this.NotFoundResult());
            }
            catch (TenantConflictException)
            {
                return(this.ConflictResult());
            }
        }
        public void ThenTheIdsOfTheChildrenCalledShouldMatchTheIdsOfTheTenantsCalled(string childrenName, Table table)
        {
            TenantCollectionResult children = this.scenarioContext.Get <TenantCollectionResult>(childrenName);

            Assert.AreEqual(table.Rows.Count, children.Tenants.Count);
            var expected = table.Rows.Select(r => this.scenarioContext.Get <ITenant>(r[0]).Id).ToList();

            CollectionAssert.AreEquivalent(expected, children.Tenants);
        }
Ejemplo n.º 6
0
        public async Task ThenThereIsNoTenantCalledAsAChildOfTheRootTenant(string tenantName)
        {
            ITenantStore           tenantStore        = ContainerBindings.GetServiceProvider(this.scenarioContext).GetRequiredService <ITenantStore>();
            TenantCollectionResult rootTenantChildren = await tenantStore.GetChildrenAsync(tenantStore.Root.Id).ConfigureAwait(false);

            ITenant[] tenants = await Task.WhenAll(rootTenantChildren.Tenants.Select(x => tenantStore.GetTenantAsync(x))).ConfigureAwait(false);

            ITenant?matchingTenant = Array.Find(tenants, x => x.Name == tenantName);

            Assert.IsNull(matchingTenant, $"Could not find a child of the root tenant with the name '{tenantName}'");
        }
        public void ThenTheIdsOfTheChildrenCalledAndShouldEachMatchOfTheIdsOfTheTenantsCalled(string childrenName1, string childrenName2, int count, Table table)
        {
            TenantCollectionResult children1 = this.scenarioContext.Get <TenantCollectionResult>(childrenName1);
            TenantCollectionResult children2 = this.scenarioContext.Get <TenantCollectionResult>(childrenName2);

            Assert.AreEqual(count, children1.Tenants.Count);
            Assert.AreEqual(count, children2.Tenants.Count);
            var expected = table.Rows.Select(r => this.scenarioContext.Get <ITenant>(r[0]).Id).ToList();

            CollectionAssert.AreEquivalent(expected, children1.Tenants.Union(children2.Tenants));
        }
Ejemplo n.º 8
0
        private async Task <ITenant?> GetChildTenantOfServiceTenant(string childTenantName, string serviceTenantName)
        {
            ITenantStore tenantStore = ContainerBindings.GetServiceProvider(this.scenarioContext).GetRequiredService <ITenantStore>();

            ITenant serviceTenant = await tenantStore.GetTenantAsync(this.scenarioContext.Get <string>(serviceTenantName)).ConfigureAwait(false);

            // Normally would have to care about pagination, but under test we only expect a small number of items.
            TenantCollectionResult getChildrenResult = await tenantStore.GetChildrenAsync(serviceTenant.Id).ConfigureAwait(false);

            ITenant[] children = await tenantStore.GetTenantsAsync(getChildrenResult.Tenants).ConfigureAwait(false);

            return(Array.Find(children, x => x.Name == childTenantName));
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Executes the command.
        /// </summary>
        /// <param name="app">The current <c>CommandLineApplication</c>.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        public async Task OnExecute(CommandLineApplication app)
        {
            if (string.IsNullOrEmpty(this.TenantId))
            {
                throw new ArgumentException("Tenant Id must be provided.");
            }

            TenantCollectionResult children = await this.tenantStore.GetChildrenAsync(this.TenantId, 1).ConfigureAwait(false);

            if (children.Tenants.Count > 0)
            {
                app.Error.WriteLine(
                    $"Cannot delete tenant with Id {this.TenantId} as it has children. Remove the child tenants first.");

                return;
            }

            await this.tenantStore.DeleteTenantAsync(this.TenantId).ConfigureAwait(false);

            app.Out.WriteLine("Deleted tenant with Id " + this.TenantId);
        }
        /// <summary>
        /// Initialises a tenancy provider to prepare it for use with Marain.
        /// </summary>
        /// <param name="tenantStore">The tenant store.</param>
        /// <param name="force">
        /// If <c>false</c> and the tenant provider contains top-level tenants (other than the expected Client and Service
        /// tenant parents) then an <see cref="InvalidOperationException"/> will be thrown. If <c>true</c>, no exception will
        /// be thrown and the parent tenants will be created regardless.
        /// </param>
        /// <param name="logger">Optional logger.</param>
        /// <remarks>
        /// Invoking this method ensures that the two top-level parent tenants are in place to act as containers for the
        /// Client and Service tenants.
        /// </remarks>
        /// <returns>A <see cref="Task"/> representing the initialisation operation.</returns>
        public static async Task InitialiseTenancyProviderAsync(this ITenantStore tenantStore, bool force = false, ILogger?logger = null)
        {
            ITenant?existingClientTenantParent = null;

            try
            {
                existingClientTenantParent = await tenantStore.GetClientTenantParentAsync().ConfigureAwait(false);
            }
            catch (InvalidOperationException)
            {
                // No-op - this is expected if the provider isn't yet initialised.
            }

            ITenant?existingServiceTenantParent = null;

            try
            {
                existingServiceTenantParent = await tenantStore.GetServiceTenantParentAsync().ConfigureAwait(false);
            }
            catch (InvalidOperationException)
            {
                // No-op - this is expected if the provider isn't yet initialised.
            }

            if (existingClientTenantParent != null && existingServiceTenantParent != null)
            {
                // All done - both parent tenants exist.
                return;
            }

            // At least one of the parent tenants don't exist. If there are other tenants, we're being asked to initialise
            // into a non-empty tenant provider, which we shouldn't do by default. To check this, we only need to retrieve
            // 2 tenants.
            TenantCollectionResult existingTopLevelTenantIds = await tenantStore.GetChildrenAsync(
                tenantStore.Root.Id,
                2,
                null).ConfigureAwait(false);

            if (existingTopLevelTenantIds.Tenants.Count > 1 && !force)
            {
                throw new InvalidOperationException("Cannot initialise the tenancy provider for use with Marain because it already contains non-Marain tenants at the root level. If you wish to initialise anyway, re-invoke the method with the 'force' parameter set to true.");
            }

            // Create the tenants
            if (existingClientTenantParent == null)
            {
                await tenantStore.CreateWellKnownChildTenantAsync(
                    tenantStore.Root.Id,
                    WellKnownTenantIds.ClientTenantParentGuid,
                    TenantNames.ClientTenantParent).ConfigureAwait(false);

                logger?.LogInformation("Created well known client tenant parent");
            }

            if (existingServiceTenantParent == null)
            {
                await tenantStore.CreateWellKnownChildTenantAsync(
                    tenantStore.Root.Id,
                    WellKnownTenantIds.ServiceTenantParentGuid,
                    TenantNames.ServiceTenantParent).ConfigureAwait(false);

                logger?.LogInformation("Created well known service tenant parent");
            }
        }
        public void ThenThereShouldBeTenantsIn(int count, string childrenName)
        {
            TenantCollectionResult children = this.scenarioContext.Get <TenantCollectionResult>(childrenName);

            Assert.AreEqual(count, children.Tenants.Count);
        }
        public void ThenThereShouldBeNoIdsInTheChildrenCalled(string childrenName)
        {
            TenantCollectionResult children = this.scenarioContext.Get <TenantCollectionResult>(childrenName);

            Assert.AreEqual(0, children.Tenants.Count);
        }