/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.cloudfoundry.operations.organizations;
import org.cloudfoundry.client.CloudFoundryClient;
import org.cloudfoundry.client.v2.ClientV2Exception;
import org.cloudfoundry.client.v2.Metadata;
import org.cloudfoundry.client.v2.featureflags.GetFeatureFlagRequest;
import org.cloudfoundry.client.v2.featureflags.GetFeatureFlagResponse;
import org.cloudfoundry.client.v2.jobs.ErrorDetails;
import org.cloudfoundry.client.v2.jobs.GetJobRequest;
import org.cloudfoundry.client.v2.jobs.GetJobResponse;
import org.cloudfoundry.client.v2.jobs.JobEntity;
import org.cloudfoundry.client.v2.organizationquotadefinitions.GetOrganizationQuotaDefinitionRequest;
import org.cloudfoundry.client.v2.organizationquotadefinitions.GetOrganizationQuotaDefinitionResponse;
import org.cloudfoundry.client.v2.organizationquotadefinitions.ListOrganizationQuotaDefinitionsRequest;
import org.cloudfoundry.client.v2.organizationquotadefinitions.ListOrganizationQuotaDefinitionsResponse;
import org.cloudfoundry.client.v2.organizationquotadefinitions.OrganizationQuotaDefinitionEntity;
import org.cloudfoundry.client.v2.organizationquotadefinitions.OrganizationQuotaDefinitionResource;
import org.cloudfoundry.client.v2.organizations.AssociateOrganizationManagerByUsernameRequest;
import org.cloudfoundry.client.v2.organizations.AssociateOrganizationManagerByUsernameResponse;
import org.cloudfoundry.client.v2.organizations.AssociateOrganizationUserByUsernameRequest;
import org.cloudfoundry.client.v2.organizations.AssociateOrganizationUserByUsernameResponse;
import org.cloudfoundry.client.v2.organizations.CreateOrganizationResponse;
import org.cloudfoundry.client.v2.organizations.DeleteOrganizationResponse;
import org.cloudfoundry.client.v2.organizations.ListOrganizationPrivateDomainsRequest;
import org.cloudfoundry.client.v2.organizations.ListOrganizationPrivateDomainsResponse;
import org.cloudfoundry.client.v2.organizations.ListOrganizationSpaceQuotaDefinitionsRequest;
import org.cloudfoundry.client.v2.organizations.ListOrganizationSpaceQuotaDefinitionsResponse;
import org.cloudfoundry.client.v2.organizations.ListOrganizationSpacesRequest;
import org.cloudfoundry.client.v2.organizations.ListOrganizationSpacesResponse;
import org.cloudfoundry.client.v2.organizations.ListOrganizationsRequest;
import org.cloudfoundry.client.v2.organizations.ListOrganizationsResponse;
import org.cloudfoundry.client.v2.organizations.OrganizationEntity;
import org.cloudfoundry.client.v2.organizations.OrganizationResource;
import org.cloudfoundry.client.v2.organizations.UpdateOrganizationRequest;
import org.cloudfoundry.client.v2.privatedomains.PrivateDomainEntity;
import org.cloudfoundry.client.v2.privatedomains.PrivateDomainResource;
import org.cloudfoundry.client.v2.shareddomains.ListSharedDomainsRequest;
import org.cloudfoundry.client.v2.shareddomains.ListSharedDomainsResponse;
import org.cloudfoundry.client.v2.shareddomains.SharedDomainEntity;
import org.cloudfoundry.client.v2.shareddomains.SharedDomainResource;
import org.cloudfoundry.client.v2.spacequotadefinitions.SpaceQuotaDefinitionResource;
import org.cloudfoundry.client.v2.spaces.SpaceResource;
import org.cloudfoundry.operations.AbstractOperationsTest;
import org.cloudfoundry.operations.spaceadmin.SpaceQuota;
import org.junit.Test;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.time.Duration;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.function.Supplier;
import static org.assertj.core.api.Assertions.assertThat;
import static org.cloudfoundry.operations.TestObjects.fill;
import static org.mockito.Mockito.when;
public final class DefaultOrganizationsTest extends AbstractOperationsTest {
private final DefaultOrganizations organizations = new DefaultOrganizations(Mono.just(this.cloudFoundryClient), Mono.just(TEST_USERNAME));
@Test
public void create() {
requestCreateOrganization(this.cloudFoundryClient, TEST_ORGANIZATION_NAME, null);
requestGetFeatureFlagEnabled(this.cloudFoundryClient, "set_roles_by_username");
requestAssociateOrganizationManagerByUsername(this.cloudFoundryClient, TEST_USERNAME);
requestAssociateOrganizationUserByUsername(this.cloudFoundryClient, TEST_USERNAME);
this.organizations
.create(CreateOrganizationRequest.builder()
.organizationName(TEST_ORGANIZATION_NAME)
.build())
.as(StepVerifier::create)
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void createSetRolesByUsernameDisabled() {
requestCreateOrganization(this.cloudFoundryClient, TEST_ORGANIZATION_NAME, null);
requestGetFeatureFlagDisabled(this.cloudFoundryClient, "set_roles_by_username");
this.organizations
.create(CreateOrganizationRequest.builder()
.organizationName(TEST_ORGANIZATION_NAME)
.build())
.as(StepVerifier::create)
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void createWithQuota() {
requestOrganizationQuotaDefinitions(this.cloudFoundryClient, "test-quota-definition-name");
requestCreateOrganization(this.cloudFoundryClient, TEST_ORGANIZATION_NAME, "test-organization-quota-definition-id");
requestGetFeatureFlagEnabled(this.cloudFoundryClient, "set_roles_by_username");
requestAssociateOrganizationManagerByUsername(this.cloudFoundryClient, TEST_USERNAME);
requestAssociateOrganizationUserByUsername(this.cloudFoundryClient, TEST_USERNAME);
this.organizations.create(CreateOrganizationRequest.builder()
.organizationName(TEST_ORGANIZATION_NAME)
.quotaDefinitionName("test-quota-definition-name")
.build())
.as(StepVerifier::create)
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void delete() {
requestOrganizations(this.cloudFoundryClient, TEST_ORGANIZATION_NAME);
requestDeleteOrganization(this.cloudFoundryClient, TEST_ORGANIZATION_ID);
requestJobSuccess(this.cloudFoundryClient, "test-id");
this.organizations
.delete(DeleteOrganizationRequest.builder()
.name(TEST_ORGANIZATION_NAME)
.build())
.as(StepVerifier::create)
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void deleteFailure() {
requestOrganizations(this.cloudFoundryClient, TEST_ORGANIZATION_NAME);
requestDeleteOrganization(this.cloudFoundryClient, TEST_ORGANIZATION_ID);
requestJobFailure(this.cloudFoundryClient, "test-id");
this.organizations
.delete(DeleteOrganizationRequest.builder()
.name(TEST_ORGANIZATION_NAME)
.build())
.as(StepVerifier::create)
.consumeErrorWith(t -> assertThat(t).isInstanceOf(ClientV2Exception.class).hasMessage("test-error-details-errorCode(1): test-error-details-description"))
.verify(Duration.ofSeconds(5));
}
@Test
public void info() {
requestOrganizations(this.cloudFoundryClient, TEST_ORGANIZATION_NAME);
requestPrivateDomains(this.cloudFoundryClient, TEST_ORGANIZATION_ID);
requestSharedDomains(this.cloudFoundryClient);
requestOrganizationQuotaDefinition(this.cloudFoundryClient, "test-organization-entity-quotaDefinitionId");
requestSpaceQuotaDefinitions(this.cloudFoundryClient, TEST_ORGANIZATION_ID);
requestSpaces(this.cloudFoundryClient, TEST_ORGANIZATION_ID);
this.organizations
.get(OrganizationInfoRequest.builder()
.name(TEST_ORGANIZATION_NAME)
.build())
.as(StepVerifier::create)
.expectNext(fill(OrganizationDetail.builder())
.domain("test-private-domain-name", "test-shared-domain-name")
.id(TEST_ORGANIZATION_ID)
.name(TEST_ORGANIZATION_NAME)
.quota(fill(OrganizationQuota.builder())
.organizationId(TEST_ORGANIZATION_ID)
.build())
.space("test-name")
.spaceQuota(fill(SpaceQuota.builder())
.build())
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void list() {
requestOrganizations(this.cloudFoundryClient);
this.organizations
.list()
.as(StepVerifier::create)
.expectNext(fill(OrganizationSummary.builder(), "organization-")
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void rename() {
requestOrganizations(this.cloudFoundryClient, TEST_ORGANIZATION_NAME);
requestUpdateOrganization(this.cloudFoundryClient, TEST_ORGANIZATION_ID, "test-new-organization-name");
this.organizations
.rename(RenameOrganizationRequest.builder()
.name(TEST_ORGANIZATION_NAME)
.newName("test-new-organization-name")
.build())
.as(StepVerifier::create)
.expectComplete()
.verify(Duration.ofSeconds(5));
}
private static void requestAssociateOrganizationManagerByUsername(CloudFoundryClient cloudFoundryClient, String username) {
when(cloudFoundryClient.organizations()
.associateManagerByUsername(AssociateOrganizationManagerByUsernameRequest.builder()
.organizationId("test-id")
.username(username)
.build()))
.thenReturn(Mono
.just(fill(AssociateOrganizationManagerByUsernameResponse.builder())
.build()));
}
private static void requestAssociateOrganizationUserByUsername(CloudFoundryClient cloudFoundryClient, String username) {
when(cloudFoundryClient.organizations()
.associateUserByUsername(AssociateOrganizationUserByUsernameRequest.builder()
.organizationId("test-id")
.username(username)
.build()))
.thenReturn(Mono
.just(fill(AssociateOrganizationUserByUsernameResponse.builder())
.build()));
}
private static void requestCreateOrganization(CloudFoundryClient cloudFoundryClient, String organization, String organizationQuotaDefinitionId) {
when(cloudFoundryClient.organizations()
.create(org.cloudfoundry.client.v2.organizations.CreateOrganizationRequest.builder()
.name(organization)
.quotaDefinitionId(organizationQuotaDefinitionId)
.build()))
.thenReturn(Mono
.just(fill(CreateOrganizationResponse.builder())
.build()));
}
private static void requestDeleteOrganization(CloudFoundryClient cloudFoundryClient, String organizationId) {
when(cloudFoundryClient.organizations()
.delete(org.cloudfoundry.client.v2.organizations.DeleteOrganizationRequest.builder()
.organizationId(organizationId)
.async(true)
.build()))
.thenReturn(Mono
.just(fill(DeleteOrganizationResponse.builder())
.build()));
}
private static void requestGetFeatureFlagDisabled(CloudFoundryClient cloudFoundryClient, String featureFlag) {
when(cloudFoundryClient.featureFlags()
.get(GetFeatureFlagRequest.builder()
.name(featureFlag)
.build()))
.thenReturn(Mono.just(GetFeatureFlagResponse.builder()
.enabled(false)
.build()));
}
private static void requestGetFeatureFlagEnabled(CloudFoundryClient cloudFoundryClient, String featureFlag) {
when(cloudFoundryClient.featureFlags()
.get(GetFeatureFlagRequest.builder()
.name(featureFlag)
.build()))
.thenReturn(Mono.just(GetFeatureFlagResponse.builder()
.enabled(true)
.build()));
}
private static void requestJobFailure(CloudFoundryClient cloudFoundryClient, String jobId) {
when(cloudFoundryClient.jobs()
.get(GetJobRequest.builder()
.jobId(jobId)
.build()))
.thenReturn(Mono
.defer(new Supplier<Mono<GetJobResponse>>() {
private final Queue<GetJobResponse> responses = new LinkedList<>(Arrays.asList(
GetJobResponse.builder()
.metadata(fill(Metadata.builder()).build())
.entity(fill(JobEntity.builder())
.status("running")
.build())
.build(),
GetJobResponse.builder()
.metadata(fill(Metadata.builder()).build())
.entity(fill(JobEntity.builder())
.errorDetails(fill(ErrorDetails.builder(), "error-details-")
.build())
.status("failed")
.build())
.build()
));
@Override
public Mono<GetJobResponse> get() {
return Mono.just(this.responses.poll());
}
}));
}
private static void requestJobSuccess(CloudFoundryClient cloudFoundryClient, String jobId) {
when(cloudFoundryClient.jobs()
.get(GetJobRequest.builder()
.jobId(jobId)
.build()))
.thenReturn(Mono
.defer(new Supplier<Mono<GetJobResponse>>() {
private final Queue<GetJobResponse> responses = new LinkedList<>(Arrays.asList(
GetJobResponse.builder()
.metadata(fill(Metadata.builder()).build())
.entity(fill(JobEntity.builder())
.status("running")
.build())
.build(),
GetJobResponse.builder()
.metadata(fill(Metadata.builder()).build())
.entity(fill(JobEntity.builder())
.status("finished")
.build())
.build()
));
@Override
public Mono<GetJobResponse> get() {
return Mono.just(this.responses.poll());
}
}));
}
private static void requestOrganizationQuotaDefinition(CloudFoundryClient cloudFoundryClient, String quotaDefinitionId) {
when(cloudFoundryClient.organizationQuotaDefinitions()
.get(GetOrganizationQuotaDefinitionRequest.builder()
.organizationQuotaDefinitionId(quotaDefinitionId)
.build()))
.thenReturn(Mono
.just(fill(GetOrganizationQuotaDefinitionResponse.builder())
.entity(fill(OrganizationQuotaDefinitionEntity.builder())
.build())
.build()));
}
private static void requestOrganizationQuotaDefinitions(CloudFoundryClient cloudFoundryClient, String organizationQuotaDefinition) {
when(cloudFoundryClient.organizationQuotaDefinitions()
.list(ListOrganizationQuotaDefinitionsRequest.builder()
.name(organizationQuotaDefinition)
.page(1)
.build()))
.thenReturn(Mono
.just(fill(ListOrganizationQuotaDefinitionsResponse.builder())
.resource(fill(OrganizationQuotaDefinitionResource.builder(), "organization-quota-definition-")
.entity(fill(OrganizationQuotaDefinitionEntity.builder(), "organization-quota-definition-entity-")
.build())
.build())
.build()));
}
private static void requestOrganizations(CloudFoundryClient cloudFoundryClient, String organizationName) {
when(cloudFoundryClient.organizations()
.list(ListOrganizationsRequest.builder()
.name(organizationName)
.page(1)
.build()))
.thenReturn(Mono
.just(fill(ListOrganizationsResponse.builder())
.resource(fill(OrganizationResource.builder(), "organization-")
.entity(fill(OrganizationEntity.builder(), "organization-entity-")
.build())
.build())
.build()));
}
private static void requestOrganizations(CloudFoundryClient cloudFoundryClient) {
when(cloudFoundryClient.organizations()
.list(ListOrganizationsRequest.builder()
.page(1)
.build()))
.thenReturn(Mono
.just(fill(ListOrganizationsResponse.builder())
.resource(fill(OrganizationResource.builder(), "organization-")
.build())
.build()));
}
private static void requestPrivateDomains(CloudFoundryClient cloudFoundryClient, String organizationId) {
when(cloudFoundryClient.organizations()
.listPrivateDomains(ListOrganizationPrivateDomainsRequest.builder()
.organizationId(organizationId)
.page(1)
.build()))
.thenReturn(Mono
.just(fill(ListOrganizationPrivateDomainsResponse.builder())
.resource(fill(PrivateDomainResource.builder())
.entity(fill(PrivateDomainEntity.builder())
.name("test-private-domain-name")
.build())
.build())
.build()));
}
private static void requestSharedDomains(CloudFoundryClient cloudFoundryClient) {
when(cloudFoundryClient.sharedDomains()
.list(ListSharedDomainsRequest.builder()
.page(1)
.build()))
.thenReturn(Mono
.just(ListSharedDomainsResponse.builder()
.resource(fill(SharedDomainResource.builder())
.entity(fill(SharedDomainEntity.builder())
.name("test-shared-domain-name")
.build())
.build())
.build()));
}
private static void requestSpaceQuotaDefinitions(CloudFoundryClient cloudFoundryClient, String organizationId) {
when(cloudFoundryClient.organizations()
.listSpaceQuotaDefinitions(ListOrganizationSpaceQuotaDefinitionsRequest.builder()
.organizationId(organizationId)
.page(1)
.build()))
.thenReturn(Mono
.just(fill(ListOrganizationSpaceQuotaDefinitionsResponse.builder())
.resource(fill(SpaceQuotaDefinitionResource.builder())
.build())
.build()));
}
private static void requestSpaces(CloudFoundryClient cloudFoundryClient, String organizationId) {
when(cloudFoundryClient.organizations()
.listSpaces(ListOrganizationSpacesRequest.builder()
.organizationId(organizationId)
.page(1)
.build()))
.thenReturn(Mono
.just(fill(ListOrganizationSpacesResponse.builder())
.resource(fill(SpaceResource.builder())
.build())
.build()));
}
private static void requestUpdateOrganization(CloudFoundryClient cloudFoundryClient, String organizationId, String newName) {
when(cloudFoundryClient.organizations()
.update(UpdateOrganizationRequest.builder()
.name(newName)
.organizationId(organizationId)
.build()))
.thenReturn(Mono.empty());
}
}