/* Copyright 2014 Danish Maritime Authority. * * 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 net.maritimecloud.serviceregistry.command.organization; import net.maritimecloud.serviceregistry.query.AliasRegistryEntry; import java.util.List; import javax.transaction.Transactional; import net.maritimecloud.serviceregistry.command.api.CreateOrganization; import net.maritimecloud.serviceregistry.command.api.ChangeOrganizationNameAndSummary; import net.maritimecloud.common.infrastructure.axon.AbstractAxonCqrsIT; import static net.maritimecloud.common.infrastructure.axon.CommonFixture.A_COVERAGE; import static net.maritimecloud.common.infrastructure.axon.CommonFixture.A_NAME; import static net.maritimecloud.common.infrastructure.axon.CommonFixture.A_SUMMARY; import static net.maritimecloud.common.infrastructure.axon.CommonFixture.aPrepareServiceSpecificationCommand; import static net.maritimecloud.common.infrastructure.axon.CommonFixture.generateServiceInstanceId; import static net.maritimecloud.common.infrastructure.axon.CommonFixture.generateServiceSpecificationId; import net.maritimecloud.portal.config.IntergrationTestDummyAuditDataProvider; import net.maritimecloud.serviceregistry.command.api.AcceptUsersMembershipApplication; import net.maritimecloud.serviceregistry.command.api.AddOrganizationAlias; import net.maritimecloud.serviceregistry.command.api.AddServiceInstanceAlias; import net.maritimecloud.serviceregistry.command.api.ApplyForMembershipToOrganization; import net.maritimecloud.serviceregistry.command.api.ChangeOrganizationWebsiteUrl; import net.maritimecloud.serviceregistry.command.api.InviteUserToOrganization; import net.maritimecloud.serviceregistry.command.api.PrepareServiceSpecification; import net.maritimecloud.serviceregistry.command.api.ProvideServiceInstance; import net.maritimecloud.serviceregistry.command.api.RemoveOrganizationAlias; import net.maritimecloud.serviceregistry.command.organization.membership.MembershipId; import net.maritimecloud.serviceregistry.command.serviceinstance.ServiceInstanceId; import net.maritimecloud.serviceregistry.command.servicespecification.ServiceSpecificationId; import net.maritimecloud.serviceregistry.domain.service.AliasGroups; import net.maritimecloud.serviceregistry.query.OrganizationEntry; import net.maritimecloud.serviceregistry.query.OrganizationMembershipEntry; import org.axonframework.commandhandling.CommandExecutionException; import org.axonframework.repository.AggregateNotFoundException; import org.junit.Assert; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.junit.Before; import org.junit.Test; /** * Integration test for Organization commands (run with 'mvn failsafe:integration-test') * <p> * @author Christoffer Børrild */ public class OrganizationIT extends AbstractAxonCqrsIT { private CreateOrganization createOrganizationCommand; private OrganizationId organizationId; private OrganizationId organizationId2; private ServiceSpecificationId serviceSpecificationId; private PrepareServiceSpecification prepareServiceSpecificationCommand; private ProvideServiceInstance provideServiceInstanceCommand; private ServiceInstanceId serviceInstanceId; @Before public void setUp() { // prepare an organization createOrganizationCommand = generateCreateOrganizationCommand(generateIdentity()); organizationId = createOrganizationCommand.getOrganizationId(); organizationId2 = generateOrganizationId(); // prepare a service specification serviceSpecificationId = generateServiceSpecificationId(); prepareServiceSpecificationCommand = aPrepareServiceSpecificationCommand(organizationId, serviceSpecificationId); // Prepare a service instance serviceInstanceId = generateServiceInstanceId(); provideServiceInstanceCommand = new ProvideServiceInstance( organizationId, serviceSpecificationId, serviceInstanceId, A_NAME, A_SUMMARY, A_COVERAGE); } @Test public void createOrganizationWithOwnerAndChangeName() { // When organization is created commandGateway().sendAndWait(createOrganizationCommand); // then the creator is assigned membership (as owner) OrganizationMembershipEntry membership = organizationMemberQueryRepository.findByOrganizationIdAndUsername( organizationId.identifier(), IntergrationTestDummyAuditDataProvider.INTEGRATION_TEST_USER ); assertNotNull(membership); Assert.assertTrue(membership.isAcceptedByOrganization()); Assert.assertTrue(membership.isAcceptedByUser()); Assert.assertTrue(membership.isActive()); // when organization name is changed commandGateway().sendAndWait(new ChangeOrganizationNameAndSummary(organizationId, ANOTHER_NAME, ANOTHER_SUMMARY)); OrganizationEntry entry = organizationQueryRepository.findOne(organizationId.identifier()); assertEquals(ANOTHER_NAME, entry.getName()); assertEquals(ANOTHER_SUMMARY, entry.getSummary()); // when we resend command to create organization try { commandGateway().sendAndWait(createOrganizationCommand); fail("Should fail as item already exist"); } catch (Exception e) { } // then we still have just one organization - nothing has changed assertEquals(1, organizationQueryRepository.count()); // when creating antoher organization commandGateway().send(new CreateOrganization(organizationId2, AN_ALIAS+organizationId2.identifier(), A_NAME, A_SUMMARY, A_URL)); // then we have two assertEquals(2, organizationQueryRepository.count()); } @Test(expected = AggregateNotFoundException.class) public void cannotChangeNonExistingOrganization() throws Throwable { try { commandGateway().sendAndWait(new ChangeOrganizationNameAndSummary(new OrganizationId("notCreated"), A_NAME, A_SUMMARY)); } catch (CommandExecutionException e) { throw e.getCause(); } } @Test public void changeOrganization() throws Throwable { commandGateway().sendAndWait(createOrganizationCommand); commandGateway().sendAndWait(new ChangeOrganizationNameAndSummary(organizationId, ANOTHER_NAME, ANOTHER_SUMMARY)); commandGateway().sendAndWait(new ChangeOrganizationWebsiteUrl(organizationId, ANOTHER_URL)); OrganizationEntry entry = organizationQueryRepository.findOne(organizationId.identifier()); assertEquals(ANOTHER_NAME, entry.getName()); assertEquals(ANOTHER_SUMMARY, entry.getSummary()); assertEquals(ANOTHER_URL, entry.getUrl()); } @Test public void inviteUser() throws Throwable { commandGateway().sendAndWait(createOrganizationCommand); commandGateway().sendAndWait(new InviteUserToOrganization(organizationId, new MembershipId("A_MEMBERSHIP_ID_"+generateIdentity()), "ANOTHER_USER")); OrganizationMembershipEntry entry = organizationMemberQueryRepository.findByOrganizationIdAndUsername(organizationId.identifier(), "ANOTHER_USER"); assertEquals(organizationId.identifier(), entry.getOrganizationId()); assertEquals("ANOTHER_USER", entry.getUsername()); assertTrue(entry.isAcceptedByOrganization()); assertFalse(entry.isAcceptedByUser()); assertFalse(entry.isActive()); } @Test public void requestMembership() throws Throwable { // given an organization commandGateway().sendAndWait(createOrganizationCommand); // when user request membership final MembershipId membershipId = new MembershipId("A_MEMBERSHIP_ID_"+generateIdentity()); commandGateway().sendAndWait(new ApplyForMembershipToOrganization(organizationId, membershipId, "ANOTHER_USER", "Let me in")); // then find membership in view OrganizationMembershipEntry entry = organizationMemberQueryRepository.findByOrganizationIdAndUsername(organizationId.identifier(), "ANOTHER_USER"); assertEquals(organizationId.identifier(), entry.getOrganizationId()); assertEquals("ANOTHER_USER", entry.getUsername()); assertTrue(entry.isAcceptedByUser()); assertFalse(entry.isAcceptedByOrganization()); assertFalse(entry.isActive()); // and membership is not yet active OrganizationMembershipEntry activeEntry = organizationMemberQueryRepository.findByOrganizationIdAndUsernameAndActiveTrue(organizationId.identifier(), "ANOTHER_USER"); assertNull(activeEntry); // when organization accept application for membership commandGateway().sendAndWait(new AcceptUsersMembershipApplication(membershipId)); activeEntry = organizationMemberQueryRepository.findByOrganizationIdAndUsernameAndActiveTrue(organizationId.identifier(), "ANOTHER_USER"); // then membership is activated assertNotNull(activeEntry); } @Test @Transactional public void addOrganizationAlias() { // TODO: clean up this terribly messy test some day // Given an organization (with a Service Specification and a provided Service Instance) commandGateway().sendAndWait(createOrganizationCommand); // NOTE: we expect the primary alias to have been denied, since it is used in another test, but we better check: (TODO) List<AliasRegistryEntry> aliasesAfterInit = aliasRegistryQueryRepository.findByGroupIdAndTypeNameAndTargetId( AliasGroups.USERS_AND_ORGANIZATIONS.name(), OrganizationId.class.getName(), organizationId.identifier()); int aliasCount = aliasesAfterInit.size(); System.out.println("aliasesAfterInit: \n"+aliasesAfterInit); // When commandGateway().sendAndWait(new AddOrganizationAlias(organizationId, AN_ALIAS+"_2_"+organizationId.identifier())); // Then AliasRegistryEntry instance = aliasRegistryQueryRepository.findByGroupIdAndTypeNameAndAlias( AliasGroups.USERS_AND_ORGANIZATIONS.name(), OrganizationId.class.getName(), AN_ALIAS+"_2_"+organizationId.identifier()); assertNotNull(instance); assertEquals(organizationId.identifier(), instance.getTargetId()); assertEquals(AN_ALIAS+"_2_"+organizationId.identifier(), instance.getAlias()); // And List<AliasRegistryEntry> instances = aliasRegistryQueryRepository.findByGroupIdAndTypeNameAndTargetId( AliasGroups.USERS_AND_ORGANIZATIONS.name(), OrganizationId.class.getName(), organizationId.identifier()); System.out.println("aliasesAfterInsert: \n"+instances); assertEquals(aliasCount + 1, instances.size()); // When add another commandGateway().sendAndWait(new AddOrganizationAlias(organizationId, ANOTHER_ALIAS+organizationId.identifier())); // then List<AliasRegistryEntry> instances2 = aliasRegistryQueryRepository.findByGroupIdAndTypeNameAndTargetId( AliasGroups.USERS_AND_ORGANIZATIONS.name(), OrganizationId.class.getName(), organizationId.identifier()); System.out.println("aliasesAfterAnotherInsert: \n"+instances2); assertEquals(aliasCount + 2, instances2.size()); // when add again commandGateway().sendAndWait(new AddOrganizationAlias(organizationId, ANOTHER_ALIAS+organizationId.identifier())); // then still instances = aliasRegistryQueryRepository.findByGroupIdAndTypeNameAndTargetId( AliasGroups.USERS_AND_ORGANIZATIONS.name(), OrganizationId.class.getName(), organizationId.identifier()); assertEquals(aliasCount + 2, instances.size()); // given another organization commandGateway().sendAndWait(generateCreateOrganizationCommand(organizationId2.identifier())); // when add same alias to another organization (it should be denied) commandGateway().sendAndWait(new AddOrganizationAlias(organizationId2, AN_ALIAS+organizationId.identifier())); // then still (...and an denied-event is emitted) instances = aliasRegistryQueryRepository.findByGroupIdAndTypeNameAndTargetId( AliasGroups.USERS_AND_ORGANIZATIONS.name(), OrganizationId.class.getName(), organizationId.identifier()); assertEquals(aliasCount + 2, instances.size()); // when remove alias commandGateway().sendAndWait(new RemoveOrganizationAlias(organizationId, AN_ALIAS+organizationId.identifier())); // then instances = aliasRegistryQueryRepository.findByGroupIdAndTypeNameAndTargetId( AliasGroups.USERS_AND_ORGANIZATIONS.name(), OrganizationId.class.getName(), organizationId.identifier()); assertEquals(aliasCount + 1, instances.size()); // Clean up - because otherwise we leave inconsistency in the eventstore // (this test did not replay all existing events, hence we might leave it // inconsistent) // when remove alias commandGateway().sendAndWait(new RemoveOrganizationAlias(organizationId, ANOTHER_ALIAS+organizationId.identifier())); // then instances = aliasRegistryQueryRepository.findByGroupIdAndTypeNameAndTargetId( AliasGroups.USERS_AND_ORGANIZATIONS.name(), OrganizationId.class.getName(), organizationId.identifier()); assertEquals(aliasCount + 0, instances.size()); } @Test public void addServiceInstanceAlias() { // Given an organization (with a Service Specification and a provided Service Instance) commandGateway().sendAndWait(createOrganizationCommand); commandGateway().sendAndWait(prepareServiceSpecificationCommand); commandGateway().sendAndWait(provideServiceInstanceCommand); // When commandGateway().sendAndWait(new AddServiceInstanceAlias(organizationId, serviceInstanceId, AN_ALIAS + serviceInstanceId.identifier())); // Then AliasRegistryEntry instance = aliasRegistryQueryRepository.findByGroupIdAndTypeNameAndAlias( organizationId.identifier(), ServiceInstanceId.class.getName(), AN_ALIAS + serviceInstanceId.identifier()); assertNotNull(instance); assertEquals(serviceInstanceId.identifier(), instance.getTargetId()); assertEquals(AN_ALIAS + serviceInstanceId.identifier(), instance.getAlias()); commandGateway().sendAndWait(new AddServiceInstanceAlias(organizationId, serviceInstanceId, ANOTHER_ALIAS + serviceInstanceId.identifier())); List<AliasRegistryEntry> instances = aliasRegistryQueryRepository.findByGroupIdAndTypeNameAndTargetId( organizationId.identifier(), ServiceInstanceId.class.getName(), serviceInstanceId.identifier()); assertEquals(2, instances.size()); } }