/* 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.query; import java.lang.reflect.InvocationTargetException; import javax.annotation.Resource; import net.maritimecloud.portal.audit.axon.UserMetaData; import net.maritimecloud.serviceregistry.command.api.OrganizationAliasAdded; import net.maritimecloud.serviceregistry.command.api.OrganizationAliasRegistrationDenied; import net.maritimecloud.serviceregistry.command.api.OrganizationAliasRemoved; import net.maritimecloud.serviceregistry.command.api.OrganizationCreated; import net.maritimecloud.serviceregistry.command.api.OrganizationNameAndSummaryChanged; import net.maritimecloud.serviceregistry.command.api.OrganizationPrimaryAliasAdded; import net.maritimecloud.serviceregistry.command.api.OrganizationRevokedUserMembership; import net.maritimecloud.serviceregistry.command.api.OrganizationWebsiteUrlChanged; import net.maritimecloud.serviceregistry.command.api.ServiceInstanceAliasAdded; import net.maritimecloud.serviceregistry.command.api.ServiceInstanceAliasRegistrationDenied; import net.maritimecloud.serviceregistry.command.api.ServiceInstanceAliasRemoved; import net.maritimecloud.serviceregistry.command.api.ServiceInstanceCreated; import net.maritimecloud.serviceregistry.command.api.ServiceInstanceEndpointAdded; import net.maritimecloud.serviceregistry.command.api.ServiceInstanceEndpointRemoved; import net.maritimecloud.serviceregistry.command.api.ServiceInstanceNameAndSummaryChanged; import net.maritimecloud.serviceregistry.command.api.ServiceInstancePrimaryAliasAdded; import net.maritimecloud.serviceregistry.command.api.ServiceSpecificationCreated; import net.maritimecloud.serviceregistry.command.api.ServiceSpecificationNameAndSummaryChanged; import net.maritimecloud.serviceregistry.command.api.UserInvitedToOrganization; import net.maritimecloud.serviceregistry.command.api.UserLeftOrganization; import net.maritimecloud.common.domain.DomainIdentifier; import net.maritimecloud.identityregistry.command.api.ResetPasswordKeyGenerated; import net.maritimecloud.identityregistry.command.api.UnconfirmedUserEmailAddressSupplied; import net.maritimecloud.identityregistry.command.api.UserAccountActivated; import net.maritimecloud.identityregistry.command.api.UserEmailAddressVerified; import net.maritimecloud.identityregistry.command.api.UserPasswordChanged; import net.maritimecloud.identityregistry.command.api.UserRegistered; import org.axonframework.common.annotation.MetaData; import org.axonframework.eventhandling.annotation.EventHandler; import org.axonframework.eventhandling.annotation.Timestamp; import org.joda.time.DateTime; import org.springframework.stereotype.Component; /** * This listener keeps a humanly formatted record of (selected/all?) events that has taken place in the context. The events are those difend * in the following Contracts: * <p> * @see net.maritimecloud.serviceregistry.command.ServiceRegistryContract * @see net.maritimecloud.identityregistry.command.IdentityRegistryContract#UserPasswordChanged * @author Christoffer Børrild * <p> */ @Component public class ActivityEntryListener { @Resource private ActivityEntryQueryRepository activityEntryQueryRepository; public ActivityEntryListener() { } public void setActivityEntryQueryRepository(ActivityEntryQueryRepository activityEntryQueryRepository) { this.activityEntryQueryRepository = activityEntryQueryRepository; } // ------------------------------------------- // ServiceRegistryContract // ------------------------------------------- @EventHandler public void on(OrganizationCreated event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { registerPublic(username, dateTime, event, "New Organization Created", "created organization", event.getOrganizationId()); } @EventHandler public void on(ServiceSpecificationNameAndSummaryChanged event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Service Specification name and summary changed", "changed name and summary of service specification", event.getServiceSpecificationId()); } @EventHandler public void on(OrganizationWebsiteUrlChanged event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Organization website URL changed", "changed website URL of organization", event.getOrganizationId()); } @EventHandler public void on(OrganizationNameAndSummaryChanged event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Organization name and summary changed", "changed name and summary of organization", event.getOrganizationId()); } @EventHandler public void on(OrganizationAliasAdded event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Organization Alias Added", "added alias '" + event.getAlias() + "' to organization", event.getOrganizationId()); } @EventHandler public void on(OrganizationPrimaryAliasAdded event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Organization Primary Alias Added", "added alias '" + event.getAlias() + "' to organization", event.getOrganizationId()); } @EventHandler public void on(OrganizationAliasRegistrationDenied event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Organization alias registration denied", "denied to create organization alias '" + event.getAlias() + "' as it is already in use", event.getOrganizationId()); } @EventHandler public void on(OrganizationAliasRemoved event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Organization Alias Removed", "removed alias '" + event.getAlias() + "' from ", event.getOrganizationId()); } @EventHandler public void on(UserInvitedToOrganization event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "User invited to Organization", "invited '" + event.getUsername() + "' to organization", event.getOrganizationId()); } @EventHandler public void on(UserLeftOrganization event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "User left Organization", "left organization", event.getOrganizationId()); } @EventHandler public void on(OrganizationRevokedUserMembership event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { if (username.equals(event.getUsername())) { register(username, dateTime, event, "Membership dropped", "dropped membership to organization", event.getOrganizationId()); } else { register(username, dateTime, event, "Membership revoked", "revoked '" + event.getUsername() + "s' membership to organization", event.getOrganizationId()); } } @EventHandler public void on(ServiceSpecificationCreated event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "New Service Specification created", "created service specification", event.getServiceSpecificationId()); } @EventHandler public void on(ServiceInstanceAliasAdded event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Service Alias Added", "added alias '" + event.getAlias() + "' to service", event.getServiceInstanceId()); } @EventHandler public void on(ServiceInstancePrimaryAliasAdded event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Service Primary Alias Added", "added primary alias '" + event.getAlias() + "' to service", event.getServiceInstanceId()); } @EventHandler public void on(ServiceInstanceAliasRegistrationDenied event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Service alias registration denied", "denied to create service alias '" + event.getAlias() + "' as it is already in use", event.getServiceInstanceId()); } @EventHandler public void on(ServiceInstanceAliasRemoved event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Service Alias Removed", "removed alias '" + event.getAlias() + "'", null); } @EventHandler public void on(ServiceInstanceCreated event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { registerPublic(username, dateTime, event, "Service Created", "created service instance", event.getServiceInstanceId()); } @EventHandler public void on(ServiceInstanceEndpointAdded event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Service endpoint Added", "added service endpoint '" + event.getServiceEndpoint().getUri() + "' to service", event.getServiceInstanceId()); } @EventHandler public void on(ServiceInstanceEndpointRemoved event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Service endpoint removed", "removed service endpoint '" + event.getServiceEndpoint().getUri() + "' from service", event.getServiceInstanceId()); } @EventHandler public void on(ServiceInstanceNameAndSummaryChanged event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Service name and summary changed", "changed name and summary of service", event.getServiceInstanceId()); } // ------------------------------------------- // IdentityRegistryContract // ------------------------------------------- @EventHandler public void on(UserRegistered event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(event.getPrefferedUsername(), dateTime, event, "User registered", "signed up", event.getUserId()); } @EventHandler public void on(UnconfirmedUserEmailAddressSupplied event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Change of e-mail address initiated", "supplied a new e-mail address", event.getUserId()); } @EventHandler public void on(UserEmailAddressVerified event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "E-mail address changed", "confirmed new e-mail address", event.getUserId()); } @EventHandler public void on(UserAccountActivated event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { registerPublic(event.getUsername(), dateTime, event, "User account activated", "confirmed user account registration", event.getUserId()); } @EventHandler public void on(ResetPasswordKeyGenerated event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Password reset requested", "requested a reset of password", event.getUserId()); } @EventHandler public void on(UserPasswordChanged event, @MetaData(UserMetaData.USERNAME) String username, @Timestamp DateTime dateTime) { register(username, dateTime, event, "Password changed", "changed password", event.getUserId()); } // ------------------------------------------- // Utilities // ------------------------------------------- private void register(String username, DateTime dateTime, Object event, String title, String summary, DomainIdentifier target) { ActivityEntry entry = create(username, dateTime, event); describe(entry, title, summary, target); save(entry); } private void registerPublic(String username, DateTime dateTime, Object event, String title, String summary, DomainIdentifier target) { ActivityEntry entry = create(username, dateTime, event); describe(entry, title, summary, target); entry.setIsPublic(true); save(entry); } private ActivityEntry create(String username, DateTime dateTime, Object event) { return new ActivityEntry( username, getOrganizationIdentifier(event), false, dateTime.toDate(), event.getClass().getName(), event.getClass().getSimpleName(), "", "", null, null ); } private void describe(ActivityEntry entry, String title, String summary, DomainIdentifier target) { entry.setTitle(title); entry.setSummary(summary); if (target != null) { entry.setTargetType(target.getClass().getSimpleName()); entry.setTargetId(target.identifier()); } } private String getOrganizationIdentifier(Object event) { if (event instanceof ServiceSpecificationCreated) { return ((ServiceSpecificationCreated) event).getOwnerId().identifier(); } if (event instanceof ServiceInstanceCreated) { return ((ServiceInstanceCreated) event).getProviderId().identifier(); } try { return getIdentifier("getOrganizationId", event); } catch (NoSuchMethodException ex) { return null; } } private String getIdentifier(String getOrganizationIdMethodName, Object event) throws NoSuchMethodException { try { return ((DomainIdentifier) event.getClass().getMethod(getOrganizationIdMethodName).invoke(event)).identifier(); } catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { throw new RuntimeException(ex); } } private void save(ActivityEntry entry) { //System.out.println("Activity: " + entry); activityEntryQueryRepository.save(entry); } }