From 6849f45bb84cef9ea207fd8092c429f685a33d7c Mon Sep 17 00:00:00 2001 From: Arnold Galovics Date: Tue, 17 May 2022 22:10:30 +0200 Subject: [PATCH] Deleting the topics module since its incomplete and additional cleanups --- .../org.apache.fineract.dependencies.gradle | 1 + .../api/NotificationApiResource.java | 33 +-- .../api/NotificationApiResourceSwagger.java | 68 +++++ .../notification/data/NotificationData.java | 104 +------- .../fineract/notification/data/TopicData.java | 74 ------ .../data/TopicSubscriberData.java | 61 ----- .../notification/domain/Notification.java | 8 +- .../domain/NotificationMapper.java | 8 +- .../fineract/notification/domain/Topic.java | 121 --------- .../notification/domain/TopicRepository.java | 30 --- .../notification/domain/TopicSubscriber.java | 77 ------ .../domain/TopicSubscriberRepository.java | 29 -- .../ActiveMQNotificationEventListener.java | 45 ++++ ...> ActiveMQNotificationEventPublisher.java} | 31 +-- .../NotificationEventListener.java | 67 ++--- .../NotificationEventPublisher.java} | 9 +- .../eventandlistener/SpringEventListener.java | 84 ------ .../SpringNotificationEventListener.java | 42 +++ ... => SpringNotificationEventPublisher.java} | 14 +- .../exception/TopicNotFoundException.java | 37 --- .../NotificationDomainServiceImpl.java | 61 ++--- ...tionGeneratorWritePlatformServiceImpl.java | 8 +- .../NotificationReadPlatformServiceImpl.java | 25 +- .../NotificationWritePlatformService.java | 4 +- .../NotificationWritePlatformServiceImpl.java | 40 +-- .../service/TopicDomainService.java | 44 ---- .../service/TopicDomainServiceImpl.java | 248 ------------------ .../service/TopicReadPlatformService.java | 32 --- .../service/TopicReadPlatformServiceImpl.java | 96 ------- .../TopicSubscriberReadPlatformService.java | 28 -- ...opicSubscriberReadPlatformServiceImpl.java | 77 ------ ...WritePlatformServiceJpaRepositoryImpl.java | 42 --- .../service/TopicWritePlatformService.java | 27 -- ...WritePlatformServiceJpaRepositoryImpl.java | 42 --- ...WritePlatformServiceJpaRepositoryImpl.java | 32 +-- .../api/UsersApiResourceSwagger.java | 7 +- .../useradministration/domain/AppUser.java | 7 +- .../domain/AppUserRepository.java | 3 + ...WritePlatformServiceJpaRepositoryImpl.java | 43 +-- ...WritePlatformServiceJpaRepositoryImpl.java | 33 +-- .../db/changelog/tenant/changelog-tenant.xml | 1 + .../tenant/parts/0013_remove_topics.xml | 27 ++ integration-tests/build.gradle | 4 +- integration-tests/dependencies.gradle | 1 + .../integrationtests/NotificationApiTest.java | 79 +++++- .../common/NotificationHelper.java | 42 +-- .../integrationtests/common/OfficeHelper.java | 11 + .../integrationtests/common/Utils.java | 9 +- .../useradministration/roles/RolesHelper.java | 2 + .../useradministration/users/UserHelper.java | 18 +- 50 files changed, 475 insertions(+), 1561 deletions(-) create mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/api/NotificationApiResourceSwagger.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/data/TopicData.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/data/TopicSubscriberData.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/domain/Topic.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/domain/TopicRepository.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/domain/TopicSubscriber.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/domain/TopicSubscriberRepository.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/ActiveMQNotificationEventListener.java rename fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/{NotificationEventService.java => ActiveMQNotificationEventPublisher.java} (58%) rename fineract-provider/src/main/java/org/apache/fineract/notification/{service/TopicSubscriberWritePlatformService.java => eventandlistener/NotificationEventPublisher.java} (77%) delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/SpringEventListener.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/SpringNotificationEventListener.java rename fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/{SpringEventPublisher.java => SpringNotificationEventPublisher.java} (74%) delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/exception/TopicNotFoundException.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicDomainService.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicDomainServiceImpl.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicReadPlatformService.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicReadPlatformServiceImpl.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicSubscriberReadPlatformService.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicSubscriberReadPlatformServiceImpl.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicSubscriberWritePlatformServiceJpaRepositoryImpl.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicWritePlatformService.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicWritePlatformServiceJpaRepositoryImpl.java create mode 100644 fineract-provider/src/main/resources/db/changelog/tenant/parts/0013_remove_topics.xml diff --git a/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle b/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle index cc01b28f8..0e82e6b66 100644 --- a/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle +++ b/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle @@ -166,6 +166,7 @@ dependencyManagement { } dependency 'org.owasp.esapi:esapi:2.4.0.0' + dependency 'org.awaitility:awaitility:4.2.0' dependencySet(group: 'org.apache.poi', version: '5.2.2') { entry 'poi' diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/api/NotificationApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/notification/api/NotificationApiResource.java index 5ae26807c..88f8cf94f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/api/NotificationApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/api/NotificationApiResource.java @@ -18,6 +18,12 @@ */ package org.apache.fineract.notification.api; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -28,6 +34,7 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; +import lombok.RequiredArgsConstructor; import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper; import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; import org.apache.fineract.infrastructure.core.serialization.ToApiJsonSerializer; @@ -36,15 +43,12 @@ import org.apache.fineract.infrastructure.core.service.SearchParameters; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.notification.data.NotificationData; import org.apache.fineract.notification.service.NotificationReadPlatformService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Path("/notifications") @Component -@Scope("singleton") - @Tag(name = "Notification", description = "") +@RequiredArgsConstructor public class NotificationApiResource { private final PlatformSecurityContext context; @@ -52,21 +56,18 @@ public class NotificationApiResource { private final ApiRequestParameterHelper apiRequestParameterHelper; private final ToApiJsonSerializer toApiJsonSerializer; - @Autowired - public NotificationApiResource(PlatformSecurityContext context, NotificationReadPlatformService notificationReadPlatformService, - ApiRequestParameterHelper apiRequestParameterHelper, ToApiJsonSerializer toApiJsonSerializer) { - this.context = context; - this.notificationReadPlatformService = notificationReadPlatformService; - this.apiRequestParameterHelper = apiRequestParameterHelper; - this.toApiJsonSerializer = toApiJsonSerializer; - } - @GET @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String getAllNotifications(@Context final UriInfo uriInfo, @QueryParam("orderBy") final String orderBy, - @QueryParam("limit") final Integer limit, @QueryParam("offset") final Integer offset, - @QueryParam("sortOrder") final String sortOrder, @QueryParam("isRead") final boolean isRead) { + @Operation + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = NotificationApiResourceSwagger.GetNotificationsResponse.class))) }) + public String getAllNotifications(@Context final UriInfo uriInfo, + @QueryParam("orderBy") @Parameter(description = "orderBy") final String orderBy, + @QueryParam("limit") @Parameter(description = "limit") final Integer limit, + @QueryParam("offset") @Parameter(description = "offset") final Integer offset, + @QueryParam("sortOrder") @Parameter(description = "sortOrder") final String sortOrder, + @QueryParam("isRead") @Parameter(description = "isRead") final boolean isRead) { this.context.authenticatedUser(); final Page notificationData; diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/api/NotificationApiResourceSwagger.java b/fineract-provider/src/main/java/org/apache/fineract/notification/api/NotificationApiResourceSwagger.java new file mode 100644 index 000000000..1036e0257 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/api/NotificationApiResourceSwagger.java @@ -0,0 +1,68 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.fineract.notification.api; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; + +final class NotificationApiResourceSwagger { + + private NotificationApiResourceSwagger() {} + + @Schema(description = "GetNotificationsResponse") + public static final class GetNotificationsResponse { + + private GetNotificationsResponse() {} + + static final class GetNotification { + + private GetNotification() {} + + @Schema(example = "1") + public Long id; + @Schema(example = "a") + public String objectType; + @Schema(example = "1") + public Long objectId; + @Schema(example = "a") + public String action; + @Schema(example = "1") + public Long actorId; + @Schema(example = "a") + public String content; + @Schema(example = "true") + public boolean isRead; + @Schema(example = "true") + public boolean isSystemGenerated; + @Schema(example = "a") + public String tenantIdentifier; + @Schema(example = "a") + public String createdAt; + @Schema(example = "1") + public Long officeId; + @Schema(example = "[]") + public List userIds; + } + + @Schema(example = "10") + public int totalFilteredRecords; + + public List pageItems; + } +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/data/NotificationData.java b/fineract-provider/src/main/java/org/apache/fineract/notification/data/NotificationData.java index 978970220..f67cc81a7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/data/NotificationData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/data/NotificationData.java @@ -19,8 +19,10 @@ package org.apache.fineract.notification.data; import java.io.Serializable; -import java.util.List; +import java.util.Set; +import lombok.Data; +@Data public class NotificationData implements Serializable { private Long id; @@ -34,12 +36,12 @@ public class NotificationData implements Serializable { private String tenantIdentifier; private String createdAt; private Long officeId; - private List userIds; + private Set userIds; public NotificationData() {} public NotificationData(String objectType, Long objectId, String action, Long actorId, String content, boolean isSystemGenerated, - boolean isRead, String tenantIdentifier, Long officeId, List userIds) { + boolean isRead, String tenantIdentifier, Long officeId, Set userIds) { this.objectType = objectType; this.objectId = objectId; this.action = action; @@ -51,100 +53,4 @@ public class NotificationData implements Serializable { this.officeId = officeId; this.userIds = userIds; } - - public Long getOfficeId() { - return officeId; - } - - public void setOfficeId(Long officeId) { - this.officeId = officeId; - } - - public List getUserIds() { - return userIds; - } - - public void setUserId(List userIds) { - this.userIds = userIds; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(String createdAt) { - this.createdAt = createdAt; - } - - public String getObjectType() { - return objectType; - } - - public void setObjectType(String objectType) { - this.objectType = objectType; - } - - public Long getObjectIdentfier() { - return objectId; - } - - public void entifier(Long objectIdentifier) { - this.objectId = objectIdentifier; - } - - public String getAction() { - return action; - } - - public void setAction(String action) { - this.action = action; - } - - public Long getActor() { - return actorId; - } - - public void setActor(Long actorId) { - this.actorId = actorId; - } - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - - public boolean isRead() { - return this.isRead; - } - - public void setRead(boolean isRead) { - this.isRead = isRead; - } - - public boolean isSystemGenerated() { - return isSystemGenerated; - } - - public void setSystemGenerated(boolean systemGenerated) { - isSystemGenerated = systemGenerated; - } - - public String getTenantIdentifier() { - return tenantIdentifier; - } - - public void setTenantIdentifier(String tenantIdentifier) { - this.tenantIdentifier = tenantIdentifier; - } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/data/TopicData.java b/fineract-provider/src/main/java/org/apache/fineract/notification/data/TopicData.java deleted file mode 100644 index 9ab2ced60..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/data/TopicData.java +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.data; - -import java.io.Serializable; - -public class TopicData implements Serializable { - - private final Long id; - private final String title; - private final boolean enabled; - private final Long entityId; - private final String entityType; - private final String memberType; - - public TopicData(Long id, String title, boolean enabled, Long entityId, String entityType, String memberType) { - this.id = id; - this.title = title; - this.enabled = enabled; - this.entityId = entityId; - this.entityType = entityType; - this.memberType = memberType; - } - - public TopicData(Long id, String title, Long entityId, String entityType, String memberType) { - this.id = id; - this.title = title; - this.enabled = true; - this.entityId = entityId; - this.entityType = entityType; - this.memberType = memberType; - } - - public Long getId() { - return this.id; - } - - public String getTitle() { - return this.title; - } - - public boolean isEnabled() { - return this.enabled; - } - - public Long getEntityId() { - return this.entityId; - } - - public String getEntityType() { - return this.entityType; - } - - public String getMemberType() { - return this.memberType; - } - -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/data/TopicSubscriberData.java b/fineract-provider/src/main/java/org/apache/fineract/notification/data/TopicSubscriberData.java deleted file mode 100644 index 5607a21a0..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/data/TopicSubscriberData.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.data; - -import java.time.LocalDate; -import org.apache.fineract.infrastructure.core.service.DateUtils; - -public class TopicSubscriberData { - - private final Long id; - private final Long topicId; - private final Long userId; - private final LocalDate subscriptionDate; - - public TopicSubscriberData(Long id, Long topicId, Long userId, LocalDate subscriptionDate) { - this.id = id; - this.topicId = topicId; - this.userId = userId; - this.subscriptionDate = subscriptionDate; - } - - public TopicSubscriberData(Long id, Long topicId, Long userId) { - this.id = id; - this.topicId = topicId; - this.userId = userId; - this.subscriptionDate = LocalDate.now(DateUtils.getDateTimeZoneOfTenant()); - } - - public Long getId() { - return this.id; - } - - public Long getTopicId() { - return this.topicId; - } - - public Long getUserId() { - return this.userId; - } - - public LocalDate getSubscriptionDate() { - return this.subscriptionDate; - } - -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/Notification.java b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/Notification.java index fcc403c7d..66e3c052f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/Notification.java +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/Notification.java @@ -18,9 +18,12 @@ */ package org.apache.fineract.notification.domain; +import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @@ -46,12 +49,13 @@ public class Notification extends AbstractPersistableCustom { private String notificationContent; @Column(name = "created_at") - private String createdAt; + @Temporal(TemporalType.TIMESTAMP) + private Date createdAt; public Notification() {} public Notification(String objectType, Long objectIdentifier, String action, Long actorId, boolean isSystemGenerated, - String notificationContent, String createdAt) { + String notificationContent, Date createdAt) { this.objectType = objectType; this.objectIdentifier = objectIdentifier; this.action = action; diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationMapper.java b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationMapper.java index 670a58bdb..a75b8d1a8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationMapper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationMapper.java @@ -18,11 +18,14 @@ */ package org.apache.fineract.notification.domain; +import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.useradministration.domain.AppUser; @@ -42,11 +45,12 @@ public class NotificationMapper extends AbstractPersistableCustom { private boolean isRead; @Column(name = "created_at") - private String createdAt; + @Temporal(TemporalType.TIMESTAMP) + private Date createdAt; public NotificationMapper() {} - public NotificationMapper(Notification notification, AppUser userId, boolean isRead, String createdAt) { + public NotificationMapper(Notification notification, AppUser userId, boolean isRead, Date createdAt) { this.notification = notification; this.userId = userId; this.isRead = isRead; diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/Topic.java b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/Topic.java deleted file mode 100644 index 80a530069..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/Topic.java +++ /dev/null @@ -1,121 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.domain; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; -import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; - -@Entity -@Table(name = "topic") -public class Topic extends AbstractPersistableCustom { - - @Column(name = "title", unique = true, nullable = false, length = 100) - private String title; - - @Column(name = "enabled", nullable = false) - private Boolean enabled; - - @Column(name = "entity_id", nullable = false) - private Long entityId; - - @Column(name = "entity_type") - private String entityType; - - @Column(name = "member_type") - private String memberType; - - public Topic() {} - - public Topic(String title, Boolean enabled, Long entityId, String entityType, String memberType) { - this.title = title.trim(); - this.enabled = enabled; - this.entityId = entityId; - this.entityType = entityType.trim(); - this.memberType = memberType.trim(); - } - - public static Topic fromJson(final JsonCommand command) { - String title = ""; - Boolean enabled = null; - Long entityId = 0L; - String entityType = ""; - String memberType = ""; - - if (command.hasParameter("title")) { - title = command.stringValueOfParameterNamed("title"); - } - if (command.hasParameter("enabled")) { - enabled = command.booleanPrimitiveValueOfParameterNamed("enabled"); - } - if (command.hasParameter("entityId")) { - entityId = command.longValueOfParameterNamed("entityId"); - } - if (command.hasParameter("entityType")) { - entityType = command.stringValueOfParameterNamed("entityType"); - } - if (command.hasParameter("memberType")) { - memberType = command.stringValueOfParameterNamed("memberType"); - } - return new Topic(title, enabled, entityId, entityType, memberType); - } - - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public Boolean getEnabled() { - return this.enabled; - } - - public void setEnabled(Boolean enabled) { - this.enabled = enabled; - } - - public Long getEntityId() { - return this.entityId; - } - - public void setEntityId(Long entityId) { - this.entityId = entityId; - } - - public String getEntityType() { - return this.entityType; - } - - public void setEntityType(String entityType) { - this.entityType = entityType; - } - - public String getMemberType() { - return this.memberType; - } - - public void setMemberType(String memberType) { - this.memberType = memberType; - } - -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/TopicRepository.java b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/TopicRepository.java deleted file mode 100644 index c3b3edb76..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/TopicRepository.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.domain; - -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; - -public interface TopicRepository extends JpaRepository, JpaSpecificationExecutor { - - List findByEntityId(Long entityId); - - List findByMemberType(String memberType); -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/TopicSubscriber.java b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/TopicSubscriber.java deleted file mode 100644 index 918d4a047..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/TopicSubscriber.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.domain; - -import java.util.Date; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; -import org.apache.fineract.useradministration.domain.AppUser; - -@Entity -@Table(name = "topic_subscriber") -public class TopicSubscriber extends AbstractPersistableCustom { - - @ManyToOne - @JoinColumn(name = "topic_id") - private Topic topic; - - @ManyToOne - @JoinColumn(name = "user_id") - private AppUser subscriber; - - @Column(name = "subscription_date") - private Date subscriptionDate; - - public TopicSubscriber() {} - - public TopicSubscriber(Topic topic, AppUser subscriber, Date subscriptionDate) { - this.topic = topic; - this.subscriber = subscriber; - this.subscriptionDate = subscriptionDate; - } - - public Topic getTopic() { - return this.topic; - } - - public void setTopic(Topic topic) { - this.topic = topic; - } - - public AppUser getSubscriber() { - return this.subscriber; - } - - public void setSubscriber(AppUser subscriber) { - this.subscriber = subscriber; - } - - public Date getSubscriptionDate() { - return this.subscriptionDate; - } - - public void setSubscriptionDate(Date subscriptionDate) { - this.subscriptionDate = subscriptionDate; - } - -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/TopicSubscriberRepository.java b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/TopicSubscriberRepository.java deleted file mode 100644 index 09a75de6c..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/TopicSubscriberRepository.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.domain; - -import java.util.List; -import org.apache.fineract.useradministration.domain.AppUser; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; - -public interface TopicSubscriberRepository extends JpaRepository, JpaSpecificationExecutor { - - List findBySubscriber(AppUser subscriber); -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/ActiveMQNotificationEventListener.java b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/ActiveMQNotificationEventListener.java new file mode 100644 index 000000000..1798082f4 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/ActiveMQNotificationEventListener.java @@ -0,0 +1,45 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.fineract.notification.eventandlistener; + +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.ObjectMessage; +import javax.jms.Session; +import lombok.RequiredArgsConstructor; +import org.apache.fineract.notification.data.NotificationData; +import org.springframework.context.annotation.Profile; +import org.springframework.jms.listener.SessionAwareMessageListener; +import org.springframework.stereotype.Component; + +@Component +@Profile("activeMqEnabled") +@RequiredArgsConstructor +public class ActiveMQNotificationEventListener implements SessionAwareMessageListener { + + private final NotificationEventListener notificationEventListener; + + @Override + public void onMessage(Message message, Session session) throws JMSException { + if (message instanceof ObjectMessage) { + NotificationData notificationData = (NotificationData) ((ObjectMessage) message).getObject(); + notificationEventListener.receive(notificationData); + } + } +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventService.java b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/ActiveMQNotificationEventPublisher.java similarity index 58% rename from fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventService.java rename to fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/ActiveMQNotificationEventPublisher.java index 801754121..66830f49b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/ActiveMQNotificationEventPublisher.java @@ -18,33 +18,24 @@ */ package org.apache.fineract.notification.eventandlistener; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.Session; +import javax.jms.Queue; +import lombok.RequiredArgsConstructor; +import org.apache.activemq.command.ActiveMQQueue; import org.apache.fineract.notification.data.NotificationData; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; import org.springframework.jms.core.JmsTemplate; -import org.springframework.jms.core.MessageCreator; import org.springframework.stereotype.Service; @Service -public class NotificationEventService { +@Profile("activeMqEnabled") +@RequiredArgsConstructor +public class ActiveMQNotificationEventPublisher implements NotificationEventPublisher { private final JmsTemplate jmsTemplate; - @Autowired - public NotificationEventService(JmsTemplate jmsTemplate) { - this.jmsTemplate = jmsTemplate; - } - - public void broadcastNotification(final Destination destination, final NotificationData notificationData) { - this.jmsTemplate.send(destination, new MessageCreator() { - - @Override - public Message createMessage(Session session) throws JMSException { - return session.createObjectMessage(notificationData); - } - }); + @Override + public void broadcastNotification(NotificationData notificationData) { + Queue queue = new ActiveMQQueue("NotificationQueue"); + this.jmsTemplate.send(queue, session -> session.createObjectMessage(notificationData)); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventListener.java b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventListener.java index 84fbc5fca..f6946eea1 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventListener.java +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventListener.java @@ -21,10 +21,8 @@ package org.apache.fineract.notification.eventandlistener; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.ObjectMessage; -import javax.jms.Session; +import java.util.Set; +import lombok.RequiredArgsConstructor; import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant; import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil; import org.apache.fineract.infrastructure.security.service.BasicAuthTenantDetailsService; @@ -32,57 +30,42 @@ import org.apache.fineract.notification.data.NotificationData; import org.apache.fineract.notification.service.NotificationWritePlatformService; import org.apache.fineract.useradministration.domain.AppUser; import org.apache.fineract.useradministration.domain.AppUserRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jms.listener.SessionAwareMessageListener; import org.springframework.stereotype.Service; @Service -public class NotificationEventListener implements SessionAwareMessageListener { +@RequiredArgsConstructor +public class NotificationEventListener { private final BasicAuthTenantDetailsService basicAuthTenantDetailsService; - private final NotificationWritePlatformService notificationWritePlatformService; - private final AppUserRepository appUserRepository; - @Autowired - public NotificationEventListener(BasicAuthTenantDetailsService basicAuthTenantDetailsService, - NotificationWritePlatformService notificationWritePlatformService, AppUserRepository appUserRepository) { - this.basicAuthTenantDetailsService = basicAuthTenantDetailsService; - this.notificationWritePlatformService = notificationWritePlatformService; - this.appUserRepository = appUserRepository; - } + public void receive(NotificationData notificationData) { + final FineractPlatformTenant tenant = this.basicAuthTenantDetailsService.loadTenantById(notificationData.getTenantIdentifier(), + false); + ThreadLocalContextUtil.setTenant(tenant); - @Override - public void onMessage(Message message, Session session) throws JMSException { - if (message instanceof ObjectMessage) { - NotificationData notificationData = (NotificationData) ((ObjectMessage) message).getObject(); + Long appUserId = notificationData.getActorId(); - final FineractPlatformTenant tenant = this.basicAuthTenantDetailsService.loadTenantById(notificationData.getTenantIdentifier(), - false); - ThreadLocalContextUtil.setTenant(tenant); + Set userIds = notificationData.getUserIds(); - Long appUserId = notificationData.getActor(); - - List userIds = notificationData.getUserIds(); - - if (notificationData.getOfficeId() != null) { - List tempUserIds = new ArrayList<>(userIds); - for (Long userId : tempUserIds) { - AppUser appUser = appUserRepository.findById(userId).get(); - if (!Objects.equals(appUser.getOffice().getId(), notificationData.getOfficeId())) { - userIds.remove(userId); - } + if (notificationData.getOfficeId() != null) { + List tempUserIds = new ArrayList<>(userIds); + for (Long userId : tempUserIds) { + AppUser appUser = appUserRepository.findById(userId).get(); + if (!Objects.equals(appUser.getOffice().getId(), notificationData.getOfficeId())) { + userIds.remove(userId); } } - - if (userIds.contains(appUserId)) { - userIds.remove(appUserId); - } - - notificationWritePlatformService.notify(userIds, notificationData.getObjectType(), notificationData.getObjectIdentfier(), - notificationData.getAction(), notificationData.getActor(), notificationData.getContent(), - notificationData.isSystemGenerated()); } + + // Don't notify the same user who triggered the event + if (userIds.contains(appUserId)) { + userIds.remove(appUserId); + } + + notificationWritePlatformService.notify(userIds, notificationData.getObjectType(), notificationData.getObjectId(), + notificationData.getAction(), notificationData.getActorId(), notificationData.getContent(), + notificationData.isSystemGenerated()); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicSubscriberWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventPublisher.java similarity index 77% rename from fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicSubscriberWritePlatformService.java rename to fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventPublisher.java index 4cca2cd46..7a2af40cb 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicSubscriberWritePlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventPublisher.java @@ -16,12 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.fineract.notification.service; +package org.apache.fineract.notification.eventandlistener; -import org.apache.fineract.notification.domain.TopicSubscriber; +import org.apache.fineract.notification.data.NotificationData; -public interface TopicSubscriberWritePlatformService { - - Long create(TopicSubscriber topicSubscriber); +public interface NotificationEventPublisher { + void broadcastNotification(NotificationData notificationData); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/SpringEventListener.java b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/SpringEventListener.java deleted file mode 100644 index 942ebe82b..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/SpringEventListener.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.eventandlistener; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant; -import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil; -import org.apache.fineract.infrastructure.security.service.BasicAuthTenantDetailsService; -import org.apache.fineract.notification.data.NotificationData; -import org.apache.fineract.notification.service.NotificationWritePlatformService; -import org.apache.fineract.useradministration.domain.AppUser; -import org.apache.fineract.useradministration.domain.AppUserRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; -import org.springframework.stereotype.Component; - -@Component -public class SpringEventListener implements ApplicationListener { - - private final BasicAuthTenantDetailsService basicAuthTenantDetailsService; - - private final NotificationWritePlatformService notificationWritePlatformService; - - private final AppUserRepository appUserRepository; - - @Autowired - public SpringEventListener(BasicAuthTenantDetailsService basicAuthTenantDetailsService, - NotificationWritePlatformService notificationWritePlatformService, AppUserRepository appUserRepository) { - this.basicAuthTenantDetailsService = basicAuthTenantDetailsService; - this.notificationWritePlatformService = notificationWritePlatformService; - this.appUserRepository = appUserRepository; - } - - @Override - public void onApplicationEvent(SpringEvent event) { - NotificationData notificationData = event.getNotificationData(); - - final FineractPlatformTenant tenant = this.basicAuthTenantDetailsService.loadTenantById(notificationData.getTenantIdentifier(), - false); - ThreadLocalContextUtil.setTenant(tenant); - - Long appUserId = notificationData.getActor(); - - List userIds = notificationData.getUserIds(); - - if (notificationData.getOfficeId() != null) { - List tempUserIds = new ArrayList<>(userIds); - for (Long userId : tempUserIds) { - AppUser appUser = appUserRepository.findById(userId).get(); - if (!Objects.equals(appUser.getOffice().getId(), notificationData.getOfficeId())) { - userIds.remove(userId); - } - } - } - - if (userIds.contains(appUserId)) { - userIds.remove(appUserId); - } - - notificationWritePlatformService.notify(userIds, notificationData.getObjectType(), notificationData.getObjectIdentfier(), - notificationData.getAction(), notificationData.getActor(), notificationData.getContent(), - notificationData.isSystemGenerated()); - - } - -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/SpringNotificationEventListener.java b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/SpringNotificationEventListener.java new file mode 100644 index 000000000..e57be9a06 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/SpringNotificationEventListener.java @@ -0,0 +1,42 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.fineract.notification.eventandlistener; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.notification.data.NotificationData; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; + +@Component +@Profile("!activeMqEnabled") +@RequiredArgsConstructor +@Slf4j +public class SpringNotificationEventListener implements ApplicationListener { + + private final NotificationEventListener notificationEventListener; + + @Override + public void onApplicationEvent(SpringEvent event) { + log.debug("Processing Spring notification event {}", event); + NotificationData notificationData = event.getNotificationData(); + notificationEventListener.receive(notificationData); + } +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/SpringEventPublisher.java b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/SpringNotificationEventPublisher.java similarity index 74% rename from fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/SpringEventPublisher.java rename to fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/SpringNotificationEventPublisher.java index 3de0f1758..15547e3cf 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/SpringEventPublisher.java +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/SpringNotificationEventPublisher.java @@ -18,18 +18,24 @@ */ package org.apache.fineract.notification.eventandlistener; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.fineract.notification.data.NotificationData; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; @Service -public class SpringEventPublisher { +@Profile("!activeMqEnabled") +@RequiredArgsConstructor +@Slf4j +public class SpringNotificationEventPublisher implements NotificationEventPublisher { - @Autowired - private ApplicationEventPublisher applicationEventPublisher; + private final ApplicationEventPublisher applicationEventPublisher; + @Override public void broadcastNotification(final NotificationData notificationData) { + log.debug("Sending Spring notification event: {}", notificationData); SpringEvent event = new SpringEvent(this, notificationData); applicationEventPublisher.publishEvent(event); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/exception/TopicNotFoundException.java b/fineract-provider/src/main/java/org/apache/fineract/notification/exception/TopicNotFoundException.java deleted file mode 100644 index 4d02d0327..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/exception/TopicNotFoundException.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.exception; - -import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; -import org.springframework.dao.EmptyResultDataAccessException; - -/** - * A {@link RuntimeException} thrown when topic resources are not found. - */ -public class TopicNotFoundException extends AbstractPlatformResourceNotFoundException { - - public TopicNotFoundException(final Long id) { - super("error.msg.topic.id.invalid", "Topic with identifier " + id + " does not exist", id); - } - - public TopicNotFoundException(Long id, EmptyResultDataAccessException e) { - super("error.msg.topic.id.invalid", "Topic with identifier " + id + " does not exist", id, e); - } - -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationDomainServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationDomainServiceImpl.java index 793d51c7c..1e703bdd7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationDomainServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationDomainServiceImpl.java @@ -18,23 +18,19 @@ */ package org.apache.fineract.notification.service; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; +import static java.util.stream.Collectors.toSet; + +import java.util.Collection; import java.util.Map; import java.util.Set; import javax.annotation.PostConstruct; -import javax.jms.Queue; import lombok.RequiredArgsConstructor; -import org.apache.activemq.command.ActiveMQQueue; +import lombok.extern.slf4j.Slf4j; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.notification.data.NotificationData; -import org.apache.fineract.notification.data.TopicSubscriberData; -import org.apache.fineract.notification.eventandlistener.NotificationEventService; -import org.apache.fineract.notification.eventandlistener.SpringEventPublisher; -import org.apache.fineract.organisation.office.domain.OfficeRepository; +import org.apache.fineract.notification.eventandlistener.NotificationEventPublisher; import org.apache.fineract.portfolio.client.domain.Client; import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants; import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BusinessEntity; @@ -49,21 +45,19 @@ import org.apache.fineract.portfolio.savings.domain.RecurringDepositAccount; import org.apache.fineract.portfolio.savings.domain.SavingsAccount; import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction; import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccount; -import org.apache.fineract.useradministration.domain.Role; -import org.apache.fineract.useradministration.domain.RoleRepository; +import org.apache.fineract.useradministration.domain.AppUser; +import org.apache.fineract.useradministration.domain.AppUserRepository; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor +@Slf4j public class NotificationDomainServiceImpl implements NotificationDomainService { private final BusinessEventNotifierService businessEventNotifierService; private final PlatformSecurityContext context; - private final RoleRepository roleRepository; - private final OfficeRepository officeRepository; - private final TopicSubscriberReadPlatformService topicSubscriberReadPlatformService; - private final NotificationEventService notificationEvent; - private final SpringEventPublisher springEventPublisher; + private final NotificationEventPublisher notificationEventPublisher; + private final AppUserRepository appUserRepository; @PostConstruct public void addListeners() { @@ -387,39 +381,20 @@ public class NotificationDomainServiceImpl implements NotificationDomainService String eventType, Long appUserId, Long officeId) { String tenantIdentifier = ThreadLocalContextUtil.getTenant().getTenantIdentifier(); - Queue queue = new ActiveMQQueue("NotificationQueue"); - List userIds = retrieveSubscribers(officeId, permission); + Set userIds = getNotifiableUserIds(officeId, permission); NotificationData notificationData = new NotificationData(objectType, objectIdentifier, eventType, appUserId, notificationContent, false, false, tenantIdentifier, officeId, userIds); try { - this.notificationEvent.broadcastNotification(queue, notificationData); + notificationEventPublisher.broadcastNotification(notificationData); } catch (Exception e) { - this.springEventPublisher.broadcastNotification(notificationData); + // We want to avoid rethrowing the exception to stop the business transaction from rolling back + log.error("Error while broadcasting notification event", e); } } - private List retrieveSubscribers(Long officeId, String permission) { - - Set topicSubscribers = new HashSet<>(); - List subscriberIds = new ArrayList<>(); - Long entityId = officeId; - String entityType = ""; - if (officeRepository.findById(entityId).get().getParent() == null) { - entityType = "OFFICE"; - } else { - entityType = "BRANCH"; - } - List allRoles = roleRepository.findAll(); - for (Role curRole : allRoles) { - if (curRole.hasPermissionTo(permission) || curRole.hasPermissionTo("ALL_FUNCTIONS")) { - String memberType = curRole.getName(); - topicSubscribers.addAll(topicSubscriberReadPlatformService.getSubscribers(entityId, entityType, memberType)); - } - } - - for (TopicSubscriberData topicSubscriber : topicSubscribers) { - subscriberIds.add(topicSubscriber.getUserId()); - } - return subscriberIds; + private Set getNotifiableUserIds(Long officeId, String permission) { + Collection users = appUserRepository.findByOfficeId(officeId); + Collection usersWithPermission = users.stream().filter(aU -> aU.hasAnyPermission(permission, "ALL_FUNCTIONS")).toList(); + return usersWithPermission.stream().map(AppUser::getId).collect(toSet()); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorWritePlatformServiceImpl.java index 3cad192e0..8824e6be3 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorWritePlatformServiceImpl.java @@ -18,21 +18,17 @@ */ package org.apache.fineract.notification.service; +import lombok.RequiredArgsConstructor; import org.apache.fineract.notification.domain.Notification; import org.apache.fineract.notification.domain.NotificationRepository; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service +@RequiredArgsConstructor public class NotificationGeneratorWritePlatformServiceImpl implements NotificationGeneratorWritePlatformService { private final NotificationRepository notificationRepository; - @Autowired - public NotificationGeneratorWritePlatformServiceImpl(NotificationRepository notificationRepository) { - this.notificationRepository = notificationRepository; - } - @Override public Long create(Notification notification) { this.notificationRepository.saveAndFlush(notification); diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationReadPlatformServiceImpl.java index a780cb75d..ae19bad6a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationReadPlatformServiceImpl.java @@ -22,6 +22,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.List; +import lombok.RequiredArgsConstructor; import org.apache.fineract.infrastructure.core.service.Page; import org.apache.fineract.infrastructure.core.service.PaginationHelper; import org.apache.fineract.infrastructure.core.service.SearchParameters; @@ -32,32 +33,24 @@ import org.apache.fineract.infrastructure.security.utils.ColumnValidator; import org.apache.fineract.notification.cache.CacheNotificationResponseHeader; import org.apache.fineract.notification.data.NotificationData; import org.apache.fineract.notification.data.NotificationMapperData; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Service; @Service +@RequiredArgsConstructor public class NotificationReadPlatformServiceImpl implements NotificationReadPlatformService { + private HashMap> tenantNotificationResponseHeaderCache = new HashMap<>(); + + private final NotificationDataRow notificationDataRow = new NotificationDataRow(); + private final NotificationMapperRow notificationMapperRow = new NotificationMapperRow(); + private final JdbcTemplate jdbcTemplate; private final PlatformSecurityContext context; private final ColumnValidator columnValidator; private final PaginationHelper paginationHelper; private final DatabaseSpecificSQLGenerator sqlGenerator; - private final NotificationDataRow notificationDataRow = new NotificationDataRow(); - private final NotificationMapperRow notificationMapperRow = new NotificationMapperRow(); - private HashMap> tenantNotificationResponseHeaderCache = new HashMap<>(); - - @Autowired - public NotificationReadPlatformServiceImpl(final JdbcTemplate jdbcTemplate, final PlatformSecurityContext context, - final ColumnValidator columnValidator, DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) { - this.jdbcTemplate = jdbcTemplate; - this.context = context; - this.columnValidator = columnValidator; - this.paginationHelper = paginationHelper; - this.sqlGenerator = sqlGenerator; - } @Override public boolean hasUnreadNotifications(Long appUserId) { @@ -204,10 +197,10 @@ public class NotificationReadPlatformServiceImpl implements NotificationReadPlat notificationData.setObjectType(objectType); final Long objectId = rs.getLong("objectId"); - notificationData.entifier(objectId); + notificationData.setObjectId(objectId); final Long actorId = rs.getLong("actor"); - notificationData.setActor(actorId); + notificationData.setActorId(actorId); final String action = rs.getString("action"); notificationData.setAction(action); diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationWritePlatformService.java index e2a51d441..d0999baf6 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationWritePlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationWritePlatformService.java @@ -18,13 +18,13 @@ */ package org.apache.fineract.notification.service; -import java.util.List; +import java.util.Collection; public interface NotificationWritePlatformService { Long notify(Long userId, String objectType, Long objectId, String action, Long actorId, String notificationContent, boolean isSystemGenerated); - Long notify(List userIds, String objectType, Long objectId, String action, Long actorId, String notificationContent, + Long notify(Collection userIds, String objectType, Long objectId, String action, Long actorId, String notificationContent, boolean isSystemGenerated); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationWritePlatformServiceImpl.java index 3318bdc5b..a70e8408f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationWritePlatformServiceImpl.java @@ -18,39 +18,28 @@ */ package org.apache.fineract.notification.service; -import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Date; +import java.util.Collection; import java.util.List; +import lombok.RequiredArgsConstructor; +import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.notification.domain.Notification; import org.apache.fineract.notification.domain.NotificationMapper; import org.apache.fineract.useradministration.domain.AppUser; import org.apache.fineract.useradministration.domain.AppUserRepository; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service +@Transactional +@RequiredArgsConstructor public class NotificationWritePlatformServiceImpl implements NotificationWritePlatformService { private final NotificationGeneratorWritePlatformService notificationGeneratorWritePlatformService; - private final NotificationGeneratorReadRepositoryWrapper notificationGeneratorReadRepositoryWrapper; - private final AppUserRepository appUserRepository; - private final NotificationMapperWritePlatformService notificationMapperWritePlatformService; - @Autowired - public NotificationWritePlatformServiceImpl(final NotificationGeneratorWritePlatformService notificationGeneratorWritePlatformService, - final NotificationGeneratorReadRepositoryWrapper notificationGeneratorReadRepositoryWrapper, - final AppUserRepository appUserRepository, - final NotificationMapperWritePlatformService notificationMapperWritePlatformService) { - this.notificationGeneratorWritePlatformService = notificationGeneratorWritePlatformService; - this.notificationGeneratorReadRepositoryWrapper = notificationGeneratorReadRepositoryWrapper; - this.appUserRepository = appUserRepository; - this.notificationMapperWritePlatformService = notificationMapperWritePlatformService; - } - @Override public Long notify(Long userId, String objectType, Long objectIdentifier, String action, Long actorId, String notificationContent, boolean isSystemGenerated) { @@ -64,7 +53,8 @@ public class NotificationWritePlatformServiceImpl implements NotificationWritePl private Long insertIntoNotificationMapper(Long userId, Long generatedNotificationId) { AppUser appUser = this.appUserRepository.findById(userId).orElse(null); NotificationMapper notificationMapper = new NotificationMapper( - this.notificationGeneratorReadRepositoryWrapper.findById(generatedNotificationId), appUser, false, getCurrentDateTime()); + this.notificationGeneratorReadRepositoryWrapper.findById(generatedNotificationId), appUser, false, + DateUtils.getDateOfTenant()); this.notificationMapperWritePlatformService.create(notificationMapper); return notificationMapper.getId(); @@ -74,13 +64,13 @@ public class NotificationWritePlatformServiceImpl implements NotificationWritePl String notificationContent, boolean isSystemGenerated) { Notification notification = new Notification(objectType, objectIdentifier, action, actorId, isSystemGenerated, notificationContent, - getCurrentDateTime()); + DateUtils.getDateOfTenant()); return this.notificationGeneratorWritePlatformService.create(notification); } @Override - public Long notify(List userIds, String objectType, Long objectId, String action, Long actorId, String notificationContent, + public Long notify(Collection userIds, String objectType, Long objectId, String action, Long actorId, String notificationContent, boolean isSystemGenerated) { Long generatedNotificationId = insertIntoNotificationGenerator(objectType, objectId, action, actorId, notificationContent, @@ -90,22 +80,16 @@ public class NotificationWritePlatformServiceImpl implements NotificationWritePl return generatedNotificationId; } - private List insertIntoNotificationMapper(List userIds, Long generatedNotificationId) { + private List insertIntoNotificationMapper(Collection userIds, Long generatedNotificationId) { List mappedIds = new ArrayList<>(); for (Long userId : userIds) { AppUser appUser = this.appUserRepository.findById(userId).get(); NotificationMapper notificationMapper = new NotificationMapper( this.notificationGeneratorReadRepositoryWrapper.findById(generatedNotificationId), appUser, false, - getCurrentDateTime()); + DateUtils.getDateOfTenant()); this.notificationMapperWritePlatformService.create(notificationMapper); mappedIds.add(notificationMapper.getId()); } return mappedIds; } - - private String getCurrentDateTime() { - Date date = new Date(); - SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - return formatter.format(date); - } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicDomainService.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicDomainService.java deleted file mode 100644 index 1379b8e34..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicDomainService.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.service; - -import java.util.Map; -import org.apache.fineract.organisation.office.domain.Office; -import org.apache.fineract.useradministration.domain.AppUser; -import org.apache.fineract.useradministration.domain.Role; - -public interface TopicDomainService { - - void createTopic(Office newOffice); - - void createTopic(Role newRole); - - void updateTopic(Office updatedOffice, Map changes); - - void updateTopic(String previousRolename, Role updatedRole, Map changes); - - void deleteTopic(Role role); - - void subscribeUserToTopic(AppUser newUser); - - void updateUserSubscription(AppUser userToUpdate, Map changes); - - void unsubcribeUserFromTopic(AppUser user); - -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicDomainServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicDomainServiceImpl.java deleted file mode 100644 index 7122bcfa6..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicDomainServiceImpl.java +++ /dev/null @@ -1,248 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.service; - -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.apache.fineract.notification.domain.Topic; -import org.apache.fineract.notification.domain.TopicRepository; -import org.apache.fineract.notification.domain.TopicSubscriber; -import org.apache.fineract.notification.domain.TopicSubscriberRepository; -import org.apache.fineract.organisation.office.domain.Office; -import org.apache.fineract.organisation.office.domain.OfficeRepository; -import org.apache.fineract.useradministration.domain.AppUser; -import org.apache.fineract.useradministration.domain.Role; -import org.apache.fineract.useradministration.domain.RoleRepository; -import org.apache.fineract.useradministration.exception.RoleNotFoundException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.ObjectUtils; - -@Service -@Transactional -public class TopicDomainServiceImpl implements TopicDomainService { - - private final RoleRepository roleRepository; - private final TopicRepository topicRepository; - private final OfficeRepository officeRepository; - private final TopicSubscriberRepository topicSubscriberRepository; - - @Autowired - public TopicDomainServiceImpl(RoleRepository roleRepository, TopicRepository topicRepository, OfficeRepository officeRepository, - TopicSubscriberRepository topicSubscriberRepository) { - - this.roleRepository = roleRepository; - this.topicRepository = topicRepository; - this.officeRepository = officeRepository; - this.topicSubscriberRepository = topicSubscriberRepository; - } - - @Override - public void createTopic(Office newOffice) { - - Long entityId = newOffice.getId(); - String entityType = this.getEntityType(newOffice); - - List allRoles = roleRepository.findAll(); - for (Role role : allRoles) { - String memberType = role.getName().toUpperCase(); - String title = role.getName() + " of " + newOffice.getName(); - Topic newTopic = new Topic(title, true, entityId, entityType, memberType); - topicRepository.save(newTopic); - } - } - - @Override - public void createTopic(Role newRole) { - - List offices = officeRepository.findAll(); - - for (Office office : offices) { - String entityType = this.getEntityType(office); - String title = newRole.getName() + " of " + office.getName(); - Topic newTopic = new Topic(title, true, office.getId(), entityType, newRole.getName().toUpperCase()); - topicRepository.save(newTopic); - } - } - - @Override - public void updateTopic(Office updatedOffice, Map changes) { - - List entityTopics = topicRepository.findByEntityId(updatedOffice.getId()); - - if (changes.containsKey("parentId")) { - - String entityType = this.getEntityType(updatedOffice); - for (Topic topic : entityTopics) { - topic.setEntityType(entityType); - topicRepository.save(topic); - } - } - if (changes.containsKey("name")) { - - for (Topic topic : entityTopics) { - Role role = roleRepository.getRoleByName(topic.getMemberType()); - String title = role.getName() + " of " + updatedOffice.getName(); - topic.setTitle(title); - topicRepository.save(topic); - } - } - } - - @Override - public void updateTopic(String previousRolename, Role updatedRole, Map changes) { - - if (changes.containsKey("name")) { - List entityTopics = topicRepository.findByMemberType(previousRolename); - for (Topic topic : entityTopics) { - Office office = officeRepository.findById(topic.getEntityId()).get(); - String title = updatedRole.getName() + " of " + office.getName(); - topic.setTitle(title); - topic.setMemberType(updatedRole.getName().toUpperCase()); - topicRepository.save(topic); - } - } - } - - @Override - public void deleteTopic(Role role) { - - List topics = topicRepository.findByMemberType(role.getName().toUpperCase()); - for (Topic topic : topics) { - topicRepository.delete(topic); - } - } - - @Override - public void subscribeUserToTopic(AppUser newUser) { - - List possibleTopics = topicRepository.findByEntityId(newUser.getOffice().getId()); - - if (!possibleTopics.isEmpty()) { - Set userRoles = newUser.getRoles(); - for (Role role : userRoles) { - for (Topic topic : possibleTopics) { - if (role.getName().compareToIgnoreCase(topic.getMemberType()) == 0) { - TopicSubscriber topicSubscriber = new TopicSubscriber(topic, newUser, new Date()); - topicSubscriberRepository.save(topicSubscriber); - } - } - } - } - } - - @Override - public void updateUserSubscription(AppUser userToUpdate, Map changes) { - - List oldSubscriptions = topicSubscriberRepository.findBySubscriber(userToUpdate); - if (changes.containsKey("officeId")) { - final Long oldOfficeId = userToUpdate.getOffice().getId(); - final Long newOfficeId = (Long) changes.get("officeId"); - List oldTopics = topicRepository.findByEntityId(oldOfficeId); - List newTopics = topicRepository.findByEntityId(newOfficeId); - - for (TopicSubscriber subscriber : oldSubscriptions) { - for (Topic topic : oldTopics) { - if (subscriber.getTopic().getId().equals(topic.getId())) { - topicSubscriberRepository.delete(subscriber); - } - } - } - - Set userRoles = userToUpdate.getRoles(); - for (Role role : userRoles) { - for (Topic topic : newTopics) { - if (role.getName().compareToIgnoreCase(topic.getMemberType()) == 0) { - TopicSubscriber newSubscription = new TopicSubscriber(topic, userToUpdate, new Date()); - topicSubscriberRepository.save(newSubscription); - } - } - } - } - - if (changes.containsKey("roles")) { - - final Set oldRoles = userToUpdate.getRoles(); - final Set tempOldRoles = new HashSet<>(oldRoles); - - final String[] roleIds = (String[]) changes.get("roles"); - final Set updatedRoles = assembleSetOfRoles(roleIds); - final Set tempUpdatedRoles = new HashSet<>(updatedRoles); - - tempOldRoles.removeAll(updatedRoles); - for (TopicSubscriber subscriber : oldSubscriptions) { - Topic topic = subscriber.getTopic(); - for (Role role : tempOldRoles) { - if (role.getName().compareToIgnoreCase(topic.getMemberType()) == 0) { - topicSubscriberRepository.delete(subscriber); - } - } - } - - tempUpdatedRoles.removeAll(oldRoles); - List newTopics = topicRepository.findByEntityId(userToUpdate.getOffice().getId()); - for (Topic topic : newTopics) { - for (Role role : tempUpdatedRoles) { - if (role.getName().compareToIgnoreCase(topic.getMemberType()) == 0) { - TopicSubscriber topicSubscriber = new TopicSubscriber(topic, userToUpdate, new Date()); - topicSubscriberRepository.save(topicSubscriber); - } - } - } - } - } - - @Override - public void unsubcribeUserFromTopic(AppUser user) { - - List subscriptions = topicSubscriberRepository.findBySubscriber(user); - for (TopicSubscriber subscription : subscriptions) { - topicSubscriberRepository.delete(subscription); - } - } - - private String getEntityType(Office office) { - - if (office.getParent() == null) { - return "OFFICE"; - } else { - return "BRANCH"; - } - } - - private Set assembleSetOfRoles(final String[] rolesArray) { - - final Set allRoles = new HashSet<>(); - - if (!ObjectUtils.isEmpty(rolesArray)) { - for (final String roleId : rolesArray) { - final Long id = Long.valueOf(roleId); - final Role role = this.roleRepository.findById(id).orElseThrow(() -> new RoleNotFoundException(id)); - allRoles.add(role); - } - } - - return allRoles; - } - -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicReadPlatformService.java deleted file mode 100644 index 616cb8036..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicReadPlatformService.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.service; - -import java.util.Collection; -import org.apache.fineract.notification.data.TopicData; - -public interface TopicReadPlatformService { - - Collection getAllTopics(); - - Collection getAllEnabledTopics(); - - TopicData findById(Long id); - -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicReadPlatformServiceImpl.java deleted file mode 100644 index a27d8a666..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicReadPlatformServiceImpl.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.service; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Collection; -import org.apache.fineract.notification.data.TopicData; -import org.apache.fineract.notification.exception.TopicNotFoundException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Service; - -@Service -public class TopicReadPlatformServiceImpl implements TopicReadPlatformService { - - private final JdbcTemplate jdbcTemplate; - - @Autowired - public TopicReadPlatformServiceImpl(final JdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } - - private static final class TopicMapper implements RowMapper { - - private final String schema; - - TopicMapper() { - final StringBuilder sqlBuilder = new StringBuilder(200); - sqlBuilder.append("t.id as id, t.title as title, t.enabled as enabled, "); - sqlBuilder.append("t.entity_id as entityId, t.entity_type as entityType, "); - sqlBuilder.append("t.member_type as memberType, from topic t"); - this.schema = sqlBuilder.toString(); - } - - public String schema() { - return this.schema; - } - - @Override - public TopicData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { - final Long id = rs.getLong("id"); - final String title = rs.getString("title"); - final Boolean enabled = rs.getBoolean("enabled"); - final Long entityId = rs.getLong("entityId"); - final String entityType = rs.getString("entityType"); - final String memberType = rs.getString("memberType"); - - return new TopicData(id, title, enabled, entityId, entityType, memberType); - } - - } - - @Override - public Collection getAllTopics() { - final TopicMapper tm = new TopicMapper(); - String sql = "select " + tm.schema(); - return this.jdbcTemplate.query(sql, tm); // NOSONAR - } - - @Override - public Collection getAllEnabledTopics() { - final TopicMapper tm = new TopicMapper(); - final String sql = "select " + tm.schema() + " where t.is_active = ?"; - return this.jdbcTemplate.query(sql, tm, new Object[] { true }); // NOSONAR - } - - @Override - public TopicData findById(Long topicId) { - try { - final TopicMapper tm = new TopicMapper(); - final String sql = "select " + tm.schema() + " where t.id = ?"; - return this.jdbcTemplate.queryForObject(sql, tm, new Object[] { topicId }); // NOSONAR - } catch (final EmptyResultDataAccessException e) { - throw new TopicNotFoundException(topicId, e); - } - } -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicSubscriberReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicSubscriberReadPlatformService.java deleted file mode 100644 index 1bfdfc699..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicSubscriberReadPlatformService.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.service; - -import java.util.Collection; -import org.apache.fineract.notification.data.TopicSubscriberData; - -public interface TopicSubscriberReadPlatformService { - - Collection getSubscribers(Long entityId, String entityType, String memberType); - -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicSubscriberReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicSubscriberReadPlatformServiceImpl.java deleted file mode 100644 index b34535e84..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicSubscriberReadPlatformServiceImpl.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.service; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.time.LocalDate; -import java.util.Collection; -import org.apache.fineract.infrastructure.core.domain.JdbcSupport; -import org.apache.fineract.notification.data.TopicSubscriberData; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Service; - -@Service -public class TopicSubscriberReadPlatformServiceImpl implements TopicSubscriberReadPlatformService { - - private final JdbcTemplate jdbcTemplate; - - @Autowired - public TopicSubscriberReadPlatformServiceImpl(final JdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } - - private static final class TopicSubscriberMapper implements RowMapper { - - private final String schema; - - TopicSubscriberMapper() { - final StringBuilder sqlBuilder = new StringBuilder(200); - sqlBuilder.append("ts.id as id, ts.topic_id as topicId, ts.user_id as userId, "); - sqlBuilder.append("ts.subscription_date as subscriptionDate from topic_subscriber ts "); - sqlBuilder.append("WHERE ts.topic_id = ( SELECT id from topic WHERE entity_id = ? "); - sqlBuilder.append("AND entity_type = ? AND member_type = ? )"); - this.schema = sqlBuilder.toString(); - } - - public String schema() { - return this.schema; - } - - @Override - public TopicSubscriberData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { - final Long id = rs.getLong("id"); - final Long topicId = rs.getLong("topicId"); - final Long userId = rs.getLong("userId"); - final LocalDate subscriptionDate = JdbcSupport.getLocalDate(rs, "subscriptionDate"); - - return new TopicSubscriberData(id, topicId, userId, subscriptionDate); - } - - } - - @Override - public Collection getSubscribers(Long entityId, String entityType, String memberType) { - final TopicSubscriberMapper tsm = new TopicSubscriberMapper(); - final String sql = "SELECT " + tsm.schema(); - return this.jdbcTemplate.query(sql, tsm, new Object[] { entityId, entityType, memberType }); // NOSONAR - } -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicSubscriberWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicSubscriberWritePlatformServiceJpaRepositoryImpl.java deleted file mode 100644 index 8d1bcf407..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicSubscriberWritePlatformServiceJpaRepositoryImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.service; - -import org.apache.fineract.notification.domain.TopicSubscriber; -import org.apache.fineract.notification.domain.TopicSubscriberRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class TopicSubscriberWritePlatformServiceJpaRepositoryImpl implements TopicSubscriberWritePlatformService { - - private final TopicSubscriberRepository topicSubscriberRepository; - - @Autowired - public TopicSubscriberWritePlatformServiceJpaRepositoryImpl(TopicSubscriberRepository topicSubscriberRepository) { - this.topicSubscriberRepository = topicSubscriberRepository; - } - - @Override - public Long create(TopicSubscriber topicSubscriber) { - topicSubscriberRepository.saveAndFlush(topicSubscriber); - return topicSubscriber.getId(); - } - -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicWritePlatformService.java deleted file mode 100644 index dfc09e611..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicWritePlatformService.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.service; - -import org.apache.fineract.notification.domain.Topic; - -public interface TopicWritePlatformService { - - Long create(Topic topic); - -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicWritePlatformServiceJpaRepositoryImpl.java deleted file mode 100644 index 73c0d656c..000000000 --- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicWritePlatformServiceJpaRepositoryImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.fineract.notification.service; - -import org.apache.fineract.notification.domain.Topic; -import org.apache.fineract.notification.domain.TopicRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class TopicWritePlatformServiceJpaRepositoryImpl implements TopicWritePlatformService { - - private final TopicRepository topicRepository; - - @Autowired - public TopicWritePlatformServiceJpaRepositoryImpl(TopicRepository topicRepository) { - this.topicRepository = topicRepository; - } - - @Override - public Long create(Topic topic) { - topicRepository.saveAndFlush(topic); - return topic.getId(); - } - -} diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeWritePlatformServiceJpaRepositoryImpl.java index 995432259..ebdb2ebe6 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeWritePlatformServiceJpaRepositoryImpl.java @@ -20,6 +20,8 @@ package org.apache.fineract.organisation.office.service; import java.util.Map; import javax.persistence.PersistenceException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; @@ -27,7 +29,6 @@ import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuild import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException; import org.apache.fineract.infrastructure.security.exception.NoAuthorizationException; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; -import org.apache.fineract.notification.service.TopicDomainService; import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency; import org.apache.fineract.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; @@ -39,9 +40,6 @@ import org.apache.fineract.organisation.office.domain.OfficeTransactionRepositor import org.apache.fineract.organisation.office.serialization.OfficeCommandFromApiJsonDeserializer; import org.apache.fineract.organisation.office.serialization.OfficeTransactionCommandFromApiJsonDeserializer; import org.apache.fineract.useradministration.domain.AppUser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Caching; import org.springframework.dao.DataIntegrityViolationException; @@ -50,32 +48,16 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service +@Slf4j +@RequiredArgsConstructor public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWritePlatformService { - private static final Logger LOG = LoggerFactory.getLogger(OfficeWritePlatformServiceJpaRepositoryImpl.class); - private final PlatformSecurityContext context; private final OfficeCommandFromApiJsonDeserializer fromApiJsonDeserializer; private final OfficeTransactionCommandFromApiJsonDeserializer moneyTransferCommandFromApiJsonDeserializer; private final OfficeRepositoryWrapper officeRepositoryWrapper; private final OfficeTransactionRepository officeTransactionRepository; private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository; - private final TopicDomainService topicDomainService; - - @Autowired - public OfficeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, - final OfficeCommandFromApiJsonDeserializer fromApiJsonDeserializer, - final OfficeTransactionCommandFromApiJsonDeserializer moneyTransferCommandFromApiJsonDeserializer, - final OfficeRepositoryWrapper officeRepositoryWrapper, final OfficeTransactionRepository officeMonetaryTransferRepository, - final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository, final TopicDomainService topicDomainService) { - this.context = context; - this.fromApiJsonDeserializer = fromApiJsonDeserializer; - this.moneyTransferCommandFromApiJsonDeserializer = moneyTransferCommandFromApiJsonDeserializer; - this.officeRepositoryWrapper = officeRepositoryWrapper; - this.officeTransactionRepository = officeMonetaryTransferRepository; - this.applicationCurrencyRepository = applicationCurrencyRepository; - this.topicDomainService = topicDomainService; - } @Transactional @Override @@ -104,8 +86,6 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP this.officeRepositoryWrapper.save(office); - this.topicDomainService.createTopic(office); - return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withEntityId(office.getId()) // @@ -150,8 +130,6 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP if (!changes.isEmpty()) { this.officeRepositoryWrapper.saveAndFlush(office); - - this.topicDomainService.updateTopic(office, changes); } return new CommandProcessingResultBuilder() // @@ -239,7 +217,7 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP "name", name); } - LOG.error("Error occured.", dve); + log.error("Error occured.", dve); throw new PlatformDataIntegrityException("error.msg.office.unknown.data.integrity.issue", "Unknown data integrity issue with resource."); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/api/UsersApiResourceSwagger.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/api/UsersApiResourceSwagger.java index 4d53e1da1..f1564222f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/api/UsersApiResourceSwagger.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/api/UsersApiResourceSwagger.java @@ -20,6 +20,7 @@ package org.apache.fineract.useradministration.api; import io.swagger.v3.oas.annotations.media.Schema; import java.util.Collection; +import java.util.List; import org.apache.fineract.organisation.office.data.OfficeData; import org.apache.fineract.organisation.staff.data.StaffData; import org.apache.fineract.useradministration.data.RoleData; @@ -111,6 +112,10 @@ final class UsersApiResourceSwagger { @Schema(example = "newuser") public String username; + @Schema(example = "password") + public String password; + @Schema(example = "repeatPassword") + public String repeatPassword; @Schema(example = "Test") public String firstname; @Schema(example = "User") @@ -122,7 +127,7 @@ final class UsersApiResourceSwagger { @Schema(example = "1") public Long staffId; @Schema(example = "[2,3]") - public String roles; + public List roles; @Schema(example = "true") public Boolean sendPasswordToEmail; @Schema(example = "true") diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java index 9f076e2bd..6fce5360b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java @@ -19,6 +19,7 @@ package org.apache.fineract.useradministration.domain; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.HashSet; @@ -598,7 +599,11 @@ public class AppUser extends AbstractPersistableCustom implements PlatformUser { return !hasAnyPermission(permissions); } - private boolean hasAnyPermission(final List permissions) { + public boolean hasAnyPermission(String... permissions) { + return hasAnyPermission(Arrays.asList(permissions)); + } + + public boolean hasAnyPermission(final List permissions) { boolean hasAtLeastOneOf = false; for (final String permissionCode : permissions) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUserRepository.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUserRepository.java index 48d3479ca..f7481d7bb 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUserRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUserRepository.java @@ -18,6 +18,7 @@ */ package org.apache.fineract.useradministration.domain; +import java.util.Collection; import org.apache.fineract.infrastructure.security.domain.PlatformUserRepository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; @@ -28,4 +29,6 @@ public interface AppUserRepository extends JpaRepository, JpaSpec @Query("Select appUser from AppUser appUser where appUser.username = :username") AppUser findAppUserByName(@Param("username") String username); + + Collection findByOfficeId(Long officeId); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserWritePlatformServiceJpaRepositoryImpl.java index 607ac06e3..8dd4ee836 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserWritePlatformServiceJpaRepositoryImpl.java @@ -26,6 +26,8 @@ import java.util.List; import java.util.Map; import java.util.Set; import javax.persistence.PersistenceException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.fineract.commands.service.CommandWrapperBuilder; import org.apache.fineract.infrastructure.core.api.JsonCommand; @@ -37,7 +39,6 @@ import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityEx import org.apache.fineract.infrastructure.core.service.PlatformEmailSendException; import org.apache.fineract.infrastructure.security.service.PlatformPasswordEncoder; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; -import org.apache.fineract.notification.service.TopicDomainService; import org.apache.fineract.organisation.office.domain.Office; import org.apache.fineract.organisation.office.domain.OfficeRepositoryWrapper; import org.apache.fineract.organisation.staff.domain.Staff; @@ -55,9 +56,6 @@ import org.apache.fineract.useradministration.domain.UserDomainService; import org.apache.fineract.useradministration.exception.PasswordPreviouslyUsedException; import org.apache.fineract.useradministration.exception.RoleNotFoundException; import org.apache.fineract.useradministration.exception.UserNotFoundException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Caching; import org.springframework.dao.DataIntegrityViolationException; @@ -70,10 +68,10 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.ObjectUtils; @Service +@Slf4j +@RequiredArgsConstructor public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWritePlatformService { - private static final Logger LOG = LoggerFactory.getLogger(AppUserWritePlatformServiceJpaRepositoryImpl.class); - private final PlatformSecurityContext context; private final UserDomainService userDomainService; private final PlatformPasswordEncoder platformPasswordEncoder; @@ -84,27 +82,6 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit private final AppUserPreviousPasswordRepository appUserPreviewPasswordRepository; private final StaffRepositoryWrapper staffRepositoryWrapper; private final ClientRepositoryWrapper clientRepositoryWrapper; - private final TopicDomainService topicDomainService; - - @Autowired - public AppUserWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final AppUserRepository appUserRepository, - final UserDomainService userDomainService, final OfficeRepositoryWrapper officeRepositoryWrapper, - final RoleRepository roleRepository, final PlatformPasswordEncoder platformPasswordEncoder, - final UserDataValidator fromApiJsonDeserializer, final AppUserPreviousPasswordRepository appUserPreviewPasswordRepository, - final StaffRepositoryWrapper staffRepositoryWrapper, final ClientRepositoryWrapper clientRepositoryWrapper, - final TopicDomainService topicDomainService) { - this.context = context; - this.appUserRepository = appUserRepository; - this.userDomainService = userDomainService; - this.officeRepositoryWrapper = officeRepositoryWrapper; - this.roleRepository = roleRepository; - this.platformPasswordEncoder = platformPasswordEncoder; - this.fromApiJsonDeserializer = fromApiJsonDeserializer; - this.appUserPreviewPasswordRepository = appUserPreviewPasswordRepository; - this.staffRepositoryWrapper = staffRepositoryWrapper; - this.clientRepositoryWrapper = clientRepositoryWrapper; - this.topicDomainService = topicDomainService; - } @Override @Transactional @@ -152,8 +129,6 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit final Boolean sendPasswordToEmail = command.booleanObjectValueOfParameterNamed("sendPasswordToEmail"); this.userDomainService.create(appUser, sendPasswordToEmail); - this.topicDomainService.subscribeUserToTopic(appUser); - return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withEntityId(appUser.getId()) // @@ -162,11 +137,11 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit } catch (final DataIntegrityViolationException dve) { throw handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); } catch (final JpaSystemException | PersistenceException | AuthenticationServiceException dve) { - LOG.error("createUser: JpaSystemException | PersistenceException | AuthenticationServiceException", dve); + log.error("createUser: JpaSystemException | PersistenceException | AuthenticationServiceException", dve); Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()); throw handleDataIntegrityIssues(command, throwable, dve); } catch (final PlatformEmailSendException e) { - LOG.error("createUser: PlatformEmailSendException", e); + log.error("createUser: PlatformEmailSendException", e); final String email = command.stringValueOfParameterNamed("email"); final ApiParameterError error = ApiParameterError.parameterError("error.msg.user.email.invalid", @@ -208,7 +183,6 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit final Map changes = userToUpdate.update(command, this.platformPasswordEncoder, clients); - this.topicDomainService.updateUserSubscription(userToUpdate, changes); if (changes.containsKey("officeId")) { final Long officeId = (Long) changes.get("officeId"); final Office office = this.officeRepositoryWrapper.findOneWithNotFoundDetection(officeId); @@ -248,7 +222,7 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit } catch (final DataIntegrityViolationException dve) { throw handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); } catch (final JpaSystemException | PersistenceException | AuthenticationServiceException dve) { - LOG.error("updateUser: JpaSystemException | PersistenceException | AuthenticationServiceException", dve); + log.error("updateUser: JpaSystemException | PersistenceException | AuthenticationServiceException", dve); Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()); throw handleDataIntegrityIssues(command, throwable, dve); } @@ -303,7 +277,6 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit } user.delete(); - this.topicDomainService.unsubcribeUserFromTopic(user); this.appUserRepository.save(user); return new CommandProcessingResultBuilder().withEntityId(userId).withOfficeId(user.getOffice().getId()).build(); @@ -333,7 +306,7 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit "Self Service User Id is already created. Go to Admin->Users to edit or delete the self-service user."); } - LOG.error("handleDataIntegrityIssues: Neither duplicate username nor existing user; unknown error occured", dve); + log.error("handleDataIntegrityIssues: Neither duplicate username nor existing user; unknown error occured", dve); return new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue", "Unknown data integrity issue with resource."); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/RoleWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/RoleWritePlatformServiceJpaRepositoryImpl.java index a35bc5740..0a7148482 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/RoleWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/RoleWritePlatformServiceJpaRepositoryImpl.java @@ -22,13 +22,14 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; import javax.persistence.PersistenceException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; -import org.apache.fineract.notification.service.TopicDomainService; import org.apache.fineract.useradministration.command.PermissionsCommand; import org.apache.fineract.useradministration.domain.Permission; import org.apache.fineract.useradministration.domain.PermissionRepository; @@ -38,9 +39,6 @@ import org.apache.fineract.useradministration.exception.PermissionNotFoundExcept import org.apache.fineract.useradministration.exception.RoleAssociatedException; import org.apache.fineract.useradministration.exception.RoleNotFoundException; import org.apache.fineract.useradministration.serialization.PermissionsCommandFromApiJsonDeserializer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Caching; import org.springframework.dao.DataIntegrityViolationException; @@ -49,27 +47,15 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service +@Slf4j +@RequiredArgsConstructor public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatformService { - private static final Logger LOG = LoggerFactory.getLogger(RoleWritePlatformServiceJpaRepositoryImpl.class); private final PlatformSecurityContext context; private final RoleRepository roleRepository; private final PermissionRepository permissionRepository; private final RoleDataValidator roleCommandFromApiJsonDeserializer; private final PermissionsCommandFromApiJsonDeserializer permissionsFromApiJsonDeserializer; - private final TopicDomainService topicDomainService; - - @Autowired - public RoleWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final RoleRepository roleRepository, - final PermissionRepository permissionRepository, final RoleDataValidator roleCommandFromApiJsonDeserializer, - final PermissionsCommandFromApiJsonDeserializer fromApiJsonDeserializer, final TopicDomainService topicDomainService) { - this.context = context; - this.roleRepository = roleRepository; - this.permissionRepository = permissionRepository; - this.roleCommandFromApiJsonDeserializer = roleCommandFromApiJsonDeserializer; - this.permissionsFromApiJsonDeserializer = fromApiJsonDeserializer; - this.topicDomainService = topicDomainService; - } @Transactional @Override @@ -81,9 +67,7 @@ public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatf this.roleCommandFromApiJsonDeserializer.validateForCreate(command.json()); final Role entity = Role.fromJson(command); - this.roleRepository.save(entity); - - this.topicDomainService.createTopic(entity); + this.roleRepository.saveAndFlush(entity); return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(entity.getId()).build(); } catch (final JpaSystemException | DataIntegrityViolationException dve) { @@ -118,7 +102,7 @@ public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatf } private void logAsErrorUnexpectedDataIntegrityException(final Exception dve) { - LOG.error("Error occured.", dve); + log.error("Error occured.", dve); } @Caching(evict = { @CacheEvict(value = "users", allEntries = true), @CacheEvict(value = "usersByUsername", allEntries = true) }) @@ -136,9 +120,6 @@ public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatf final Map changes = role.update(command); if (!changes.isEmpty()) { this.roleRepository.saveAndFlush(role); - if (changes.containsKey("name")) { - this.topicDomainService.updateTopic(previousRoleName, role, changes); - } } return new CommandProcessingResultBuilder() // @@ -230,8 +211,6 @@ public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatf throw new RoleAssociatedException("error.msg.role.associated.with.users.deleted", roleId); } - this.topicDomainService.deleteTopic(role); - this.roleRepository.delete(role); return new CommandProcessingResultBuilder().withEntityId(roleId).build(); } catch (final JpaSystemException | DataIntegrityViolationException e) { diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml index 0eed83638..079c5e474 100644 --- a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml +++ b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml @@ -32,4 +32,5 @@ + diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0013_remove_topics.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0013_remove_topics.xml new file mode 100644 index 000000000..32a1f6727 --- /dev/null +++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0013_remove_topics.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/integration-tests/build.gradle b/integration-tests/build.gradle index 320ff5d83..486299f29 100644 --- a/integration-tests/build.gradle +++ b/integration-tests/build.gradle @@ -29,7 +29,7 @@ configurations { apply from: 'dependencies.gradle' // enable when all tests are migrated -tasks.cucumber.onlyIf {false} +tasks.cucumber.onlyIf { false } // Allow external drivers to be used for the tests without packaging it // mainly due to license incompatibilities @@ -92,7 +92,7 @@ cargoStartLocal.dependsOn ':fineract-war:war' cargoStartLocal.mustRunAfter 'testClasses' test { - dependsOn (cargoStartLocal) + dependsOn(cargoStartLocal) finalizedBy cargoStopLocal } diff --git a/integration-tests/dependencies.gradle b/integration-tests/dependencies.gradle index da8ed8507..8067dae52 100644 --- a/integration-tests/dependencies.gradle +++ b/integration-tests/dependencies.gradle @@ -38,6 +38,7 @@ dependencies { exclude group: 'org.apache.sling' exclude group: 'com.sun.xml.bind' } + testImplementation 'org.awaitility:awaitility' testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/NotificationApiTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/NotificationApiTest.java index efcb9e174..def1ca8b0 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/NotificationApiTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/NotificationApiTest.java @@ -18,40 +18,93 @@ */ package org.apache.fineract.integrationtests; +import static org.apache.fineract.integrationtests.useradministration.roles.RolesHelper.SUPER_USER_ROLE_ID; + import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; -import java.util.HashMap; +import java.util.List; +import org.apache.fineract.client.models.GetNotification; +import org.apache.fineract.client.models.GetNotificationsResponse; +import org.apache.fineract.client.models.GetOfficesResponse; +import org.apache.fineract.client.models.PostClientsRequest; +import org.apache.fineract.client.models.PostUsersRequest; +import org.apache.fineract.client.models.PostUsersResponse; +import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.NotificationHelper; +import org.apache.fineract.integrationtests.common.OfficeHelper; import org.apache.fineract.integrationtests.common.Utils; +import org.apache.fineract.integrationtests.useradministration.users.UserHelper; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class NotificationApiTest { - private static final Logger LOG = LoggerFactory.getLogger(NotificationApiTest.class); - private ResponseSpecification responseSpec; + public static final int SUPER_USER_ID = 1; + public static final String CLIENT_OBJECT_TYPE = "client"; + public static final String CREATED_ACTION_TYPE = "created"; private RequestSpecification requestSpec; + private ResponseSpecification responseSpec; + + private RequestSpecification newUserRequestSpec; + private ResponseSpecification newUserResponseSpec; @BeforeEach public void setUp() { Utils.initializeRESTAssured(); - this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); - this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey()); - this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); + requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); + requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey()); + responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); + + GetOfficesResponse headOffice = OfficeHelper.getHeadOffice(requestSpec, responseSpec); + String username = Utils.randomNameGenerator("NotificationUser", 4); + String password = Utils.randomStringGenerator("aA1", 10); // prefix is to conform with the password rules + PostUsersRequest createUserRequest = new PostUsersRequest().username(username) + .firstname(Utils.randomNameGenerator("NotificationFN", 4)).lastname(Utils.randomNameGenerator("NotificationLN", 4)) + .email("whatever@mifos.org").password(password).repeatPassword(password).sendPasswordToEmail(false) + .roles(List.of(Long.toString(SUPER_USER_ROLE_ID))).officeId(headOffice.getId()); + + PostUsersResponse userCreationResponse = UserHelper.createUser(requestSpec, responseSpec, createUserRequest); + Assertions.assertNotNull(userCreationResponse.getResourceId()); + + newUserRequestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); + newUserRequestSpec.header("Authorization", + "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey(username, password)); + newUserResponseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); + } @Test - @SuppressWarnings("unchecked") - public void testNotificationRetrieval() { - HashMap response = (HashMap) NotificationHelper.getNotifications(this.requestSpec, - this.responseSpec, ""); - LOG.info("Response : {}", response.toString()); + public void testNotificationRetrievalWorksWhenNoNotificationsAreAvailable() { + // given + // when + GetNotificationsResponse response = NotificationHelper.getNotifications(requestSpec, responseSpec); + // then Assertions.assertNotNull(response); } + + @Test + public void testNotificationRetrievalWorksWhenOneNotificationIsAvailable() { + // given + PostClientsRequest clientRequest = ClientHelper.defaultClientCreationRequest(); + Integer clientId = ClientHelper.createClient(requestSpec, responseSpec, clientRequest); + Assertions.assertNotNull(clientId); + + // when + NotificationHelper.waitUntilNotificationsAreAvailable(newUserRequestSpec, newUserResponseSpec); + GetNotificationsResponse response = NotificationHelper.getNotifications(newUserRequestSpec, newUserResponseSpec); + // then + Assertions.assertNotNull(response); + List pageItems = response.getPageItems(); + Assertions.assertEquals(1, pageItems.size()); + GetNotification firstNotification = pageItems.get(0); + Assertions.assertEquals(SUPER_USER_ID, firstNotification.getActorId()); + Assertions.assertEquals(false, firstNotification.getIsRead()); + Assertions.assertEquals(CREATED_ACTION_TYPE, firstNotification.getAction()); + Assertions.assertEquals(clientId.longValue(), firstNotification.getObjectId()); + Assertions.assertEquals(CLIENT_OBJECT_TYPE, firstNotification.getObjectType()); + } } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/NotificationHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/NotificationHelper.java index e375059f2..9c6487d16 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/NotificationHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/NotificationHelper.java @@ -18,28 +18,40 @@ */ package org.apache.fineract.integrationtests.common; +import static org.awaitility.Awaitility.await; + +import com.google.gson.Gson; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import java.time.Duration; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.client.models.GetNotificationsResponse; +import org.apache.fineract.client.util.JSON; -public class NotificationHelper { - - private static final Logger LOG = LoggerFactory.getLogger(NotificationHelper.class); - private final RequestSpecification requestSpec; - private final ResponseSpecification responseSpec; +@Slf4j +public final class NotificationHelper { private static final String NOTIFICATION_API_URL = "/fineract-provider/api/v1/notifications?" + Utils.TENANT_IDENTIFIER; + private static final Gson GSON = new JSON().getGson(); - public NotificationHelper(RequestSpecification requestSpec, ResponseSpecification responseSpec) { - this.requestSpec = requestSpec; - this.responseSpec = responseSpec; + private NotificationHelper() {} + + public static GetNotificationsResponse getNotifications(final RequestSpecification requestSpec, + final ResponseSpecification responseSpec) { + final String GET_NOTIFICATIONS_URL = NOTIFICATION_API_URL; + log.info("-----------------------------GET NOTIFICATIONS-----------------------------------"); + String response = Utils.performServerGet(requestSpec, responseSpec, GET_NOTIFICATIONS_URL); + return GSON.fromJson(response, GetNotificationsResponse.class); } - public static Object getNotifications(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, - final String jsonReturn) { - final String GET_NOTIFICATIONS_URL = NOTIFICATION_API_URL; - LOG.info("-----------------------------GET NOTIFICATIONS-----------------------------------"); - return Utils.performServerGet(requestSpec, responseSpec, GET_NOTIFICATIONS_URL, ""); + public static boolean areNotificationsAvailable(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) { + return getNotifications(requestSpec, responseSpec).getPageItems().size() > 0; + } + + // Waiting for notifications to be available is needed due to the asynchronous event processing + public static void waitUntilNotificationsAreAvailable(final RequestSpecification requestSpec, + final ResponseSpecification responseSpec) { + await().atMost(Duration.ofSeconds(30)).pollInterval(Duration.ofMillis(250)) + .until(() -> NotificationHelper.areNotificationsAvailable(requestSpec, responseSpec)); } } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/OfficeHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/OfficeHelper.java index f6f5faf1c..3c4cb6d70 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/OfficeHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/OfficeHelper.java @@ -29,6 +29,8 @@ import java.io.InputStream; import java.util.HashMap; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; +import org.apache.fineract.client.models.GetOfficesResponse; +import org.apache.fineract.client.util.JSON; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Workbook; import org.slf4j.Logger; @@ -36,8 +38,11 @@ import org.slf4j.LoggerFactory; public class OfficeHelper { + public static final long HEAD_OFFICE_ID = 1L; // The ID is hardcoded in the initial Liquibase migration script + private static final Logger LOG = LoggerFactory.getLogger(OfficeHelper.class); private static final String OFFICE_URL = "/fineract-provider/api/v1/offices"; + private static final Gson GSON = new JSON().getGson(); private final RequestSpecification requestSpec; private final ResponseSpecification responseSpec; @@ -52,6 +57,12 @@ public class OfficeHelper { return new Gson().fromJson(json, new TypeToken() {}.getType()); } + public static GetOfficesResponse getHeadOffice(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) { + String response = Utils.performServerGet(requestSpec, responseSpec, + OFFICE_URL + "/" + HEAD_OFFICE_ID + "?" + Utils.TENANT_IDENTIFIER); + return GSON.fromJson(response, GetOfficesResponse.class); + } + public Integer createOffice(final String openingDate) { String json = getAsJSON(openingDate); return Utils.performServerPost(this.requestSpec, this.responseSpec, OFFICE_URL + "?" + Utils.TENANT_IDENTIFIER, json, diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/Utils.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/Utils.java index 4f6bef4a0..9d7bb3b4f 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/Utils.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/Utils.java @@ -118,12 +118,17 @@ public final class Utils { } public static String loginIntoServerAndGetBase64EncodedAuthenticationKey() { + return loginIntoServerAndGetBase64EncodedAuthenticationKey("mifos", "password"); + } + + public static String loginIntoServerAndGetBase64EncodedAuthenticationKey(String username, String password) { awaitSpringBootActuatorHealthyUp(); try { LOG.info("Logging in, for integration test..."); // system.out.println("-----------------------------------LOGIN-----------------------------------------"); - String json = RestAssured.given().contentType(ContentType.JSON).body("{\"username\":\"mifos\", \"password\":\"password\"}") - .expect().log().ifError().when().post(LOGIN_URL).asString(); + String json = RestAssured.given().contentType(ContentType.JSON) + .body("{\"username\":\"" + username + "\", \"password\":\"" + password + "\"}").expect().log().ifError().when() + .post(LOGIN_URL).asString(); assertThat("Failed to login into fineract platform", StringUtils.isBlank(json), is(false)); String key = JsonPath.with(json).get("base64EncodedAuthenticationKey"); assertThat("Failed to obtain key: " + json, StringUtils.isBlank(key), is(false)); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/useradministration/roles/RolesHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/useradministration/roles/RolesHelper.java index def8c7601..024957173 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/useradministration/roles/RolesHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/useradministration/roles/RolesHelper.java @@ -26,6 +26,8 @@ import org.apache.fineract.integrationtests.common.Utils; public final class RolesHelper { + public static final long SUPER_USER_ROLE_ID = 1L; // This is hardcoded into the initial Liquibase migration + private RolesHelper() { } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/useradministration/users/UserHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/useradministration/users/UserHelper.java index f00797586..1a86dca53 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/useradministration/users/UserHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/useradministration/users/UserHelper.java @@ -18,22 +18,25 @@ */ package org.apache.fineract.integrationtests.useradministration.users; +import com.google.gson.Gson; import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.util.HashMap; import java.util.List; +import org.apache.fineract.client.models.PostUsersRequest; +import org.apache.fineract.client.models.PostUsersResponse; +import org.apache.fineract.client.util.JSON; import org.apache.fineract.integrationtests.common.Utils; import org.junit.jupiter.api.Assertions; public final class UserHelper { - private UserHelper() { - - } - private static final String CREATE_USER_URL = "/fineract-provider/api/v1/users?" + Utils.TENANT_IDENTIFIER; private static final String USER_URL = "/fineract-provider/api/v1/users"; + private static final Gson GSON = new JSON().getGson(); + + private UserHelper() {} public static Integer createUser(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, int roleId, int staffId) { @@ -46,6 +49,13 @@ public final class UserHelper { attribute); } + public static PostUsersResponse createUser(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + PostUsersRequest request) { + String requestBody = GSON.toJson(request); + String response = Utils.performServerPost(requestSpec, responseSpec, CREATE_USER_URL, requestBody); + return GSON.fromJson(response, PostUsersResponse.class); + } + public static Object createUserForSelfService(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, int roleId, int staffId, int clientId, String attribute) { return Utils.performServerPost(requestSpec, responseSpec, CREATE_USER_URL,