Deleting the topics module since its incomplete and additional cleanups
This commit is contained in:
committed by
Arnold Gálovics
parent
073b1b04b6
commit
6849f45bb8
@@ -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'
|
||||
|
||||
+17
-16
@@ -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<NotificationData> toApiJsonSerializer;
|
||||
|
||||
@Autowired
|
||||
public NotificationApiResource(PlatformSecurityContext context, NotificationReadPlatformService notificationReadPlatformService,
|
||||
ApiRequestParameterHelper apiRequestParameterHelper, ToApiJsonSerializer<NotificationData> 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> notificationData;
|
||||
|
||||
+68
@@ -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<Long> userIds;
|
||||
}
|
||||
|
||||
@Schema(example = "10")
|
||||
public int totalFilteredRecords;
|
||||
|
||||
public List<GetNotification> pageItems;
|
||||
}
|
||||
}
|
||||
+5
-99
@@ -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<Long> userIds;
|
||||
private Set<Long> userIds;
|
||||
|
||||
public NotificationData() {}
|
||||
|
||||
public NotificationData(String objectType, Long objectId, String action, Long actorId, String content, boolean isSystemGenerated,
|
||||
boolean isRead, String tenantIdentifier, Long officeId, List<Long> userIds) {
|
||||
boolean isRead, String tenantIdentifier, Long officeId, Set<Long> 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<Long> getUserIds() {
|
||||
return userIds;
|
||||
}
|
||||
|
||||
public void setUserId(List<Long> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
-61
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+6
-2
@@ -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;
|
||||
|
||||
+6
-2
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
-30
@@ -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<Topic, Long>, JpaSpecificationExecutor<Topic> {
|
||||
|
||||
List<Topic> findByEntityId(Long entityId);
|
||||
|
||||
List<Topic> findByMemberType(String memberType);
|
||||
}
|
||||
-77
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
-29
@@ -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<TopicSubscriber, Long>, JpaSpecificationExecutor<TopicSubscriber> {
|
||||
|
||||
List<TopicSubscriber> findBySubscriber(AppUser subscriber);
|
||||
}
|
||||
+45
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-20
@@ -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));
|
||||
}
|
||||
}
|
||||
+25
-42
@@ -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<Long> userIds = notificationData.getUserIds();
|
||||
|
||||
Long appUserId = notificationData.getActor();
|
||||
|
||||
List<Long> userIds = notificationData.getUserIds();
|
||||
|
||||
if (notificationData.getOfficeId() != null) {
|
||||
List<Long> 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<Long> 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());
|
||||
}
|
||||
}
|
||||
|
||||
+4
-5
@@ -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);
|
||||
}
|
||||
-84
@@ -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<SpringEvent> {
|
||||
|
||||
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<Long> userIds = notificationData.getUserIds();
|
||||
|
||||
if (notificationData.getOfficeId() != null) {
|
||||
List<Long> 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());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -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<SpringEvent> {
|
||||
|
||||
private final NotificationEventListener notificationEventListener;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(SpringEvent event) {
|
||||
log.debug("Processing Spring notification event {}", event);
|
||||
NotificationData notificationData = event.getNotificationData();
|
||||
notificationEventListener.receive(notificationData);
|
||||
}
|
||||
}
|
||||
+10
-4
@@ -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);
|
||||
}
|
||||
-37
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+18
-43
@@ -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<Long> userIds = retrieveSubscribers(officeId, permission);
|
||||
Set<Long> 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<Long> retrieveSubscribers(Long officeId, String permission) {
|
||||
|
||||
Set<TopicSubscriberData> topicSubscribers = new HashSet<>();
|
||||
List<Long> subscriberIds = new ArrayList<>();
|
||||
Long entityId = officeId;
|
||||
String entityType = "";
|
||||
if (officeRepository.findById(entityId).get().getParent() == null) {
|
||||
entityType = "OFFICE";
|
||||
} else {
|
||||
entityType = "BRANCH";
|
||||
}
|
||||
List<Role> 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<Long> getNotifiableUserIds(Long officeId, String permission) {
|
||||
Collection<AppUser> users = appUserRepository.findByOfficeId(officeId);
|
||||
Collection<AppUser> usersWithPermission = users.stream().filter(aU -> aU.hasAnyPermission(permission, "ALL_FUNCTIONS")).toList();
|
||||
return usersWithPermission.stream().map(AppUser::getId).collect(toSet());
|
||||
}
|
||||
}
|
||||
|
||||
+2
-6
@@ -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);
|
||||
|
||||
+9
-16
@@ -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<Long, HashMap<Long, CacheNotificationResponseHeader>> 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<Long, HashMap<Long, CacheNotificationResponseHeader>> 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);
|
||||
|
||||
+2
-2
@@ -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<Long> userIds, String objectType, Long objectId, String action, Long actorId, String notificationContent,
|
||||
Long notify(Collection<Long> userIds, String objectType, Long objectId, String action, Long actorId, String notificationContent,
|
||||
boolean isSystemGenerated);
|
||||
}
|
||||
|
||||
+12
-28
@@ -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<Long> userIds, String objectType, Long objectId, String action, Long actorId, String notificationContent,
|
||||
public Long notify(Collection<Long> 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<Long> insertIntoNotificationMapper(List<Long> userIds, Long generatedNotificationId) {
|
||||
private List<Long> insertIntoNotificationMapper(Collection<Long> userIds, Long generatedNotificationId) {
|
||||
List<Long> 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);
|
||||
}
|
||||
}
|
||||
|
||||
-44
@@ -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<String, Object> changes);
|
||||
|
||||
void updateTopic(String previousRolename, Role updatedRole, Map<String, Object> changes);
|
||||
|
||||
void deleteTopic(Role role);
|
||||
|
||||
void subscribeUserToTopic(AppUser newUser);
|
||||
|
||||
void updateUserSubscription(AppUser userToUpdate, Map<String, Object> changes);
|
||||
|
||||
void unsubcribeUserFromTopic(AppUser user);
|
||||
|
||||
}
|
||||
-248
@@ -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<Role> 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<Office> 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<String, Object> changes) {
|
||||
|
||||
List<Topic> 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<String, Object> changes) {
|
||||
|
||||
if (changes.containsKey("name")) {
|
||||
List<Topic> 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<Topic> topics = topicRepository.findByMemberType(role.getName().toUpperCase());
|
||||
for (Topic topic : topics) {
|
||||
topicRepository.delete(topic);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribeUserToTopic(AppUser newUser) {
|
||||
|
||||
List<Topic> possibleTopics = topicRepository.findByEntityId(newUser.getOffice().getId());
|
||||
|
||||
if (!possibleTopics.isEmpty()) {
|
||||
Set<Role> 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<String, Object> changes) {
|
||||
|
||||
List<TopicSubscriber> oldSubscriptions = topicSubscriberRepository.findBySubscriber(userToUpdate);
|
||||
if (changes.containsKey("officeId")) {
|
||||
final Long oldOfficeId = userToUpdate.getOffice().getId();
|
||||
final Long newOfficeId = (Long) changes.get("officeId");
|
||||
List<Topic> oldTopics = topicRepository.findByEntityId(oldOfficeId);
|
||||
List<Topic> newTopics = topicRepository.findByEntityId(newOfficeId);
|
||||
|
||||
for (TopicSubscriber subscriber : oldSubscriptions) {
|
||||
for (Topic topic : oldTopics) {
|
||||
if (subscriber.getTopic().getId().equals(topic.getId())) {
|
||||
topicSubscriberRepository.delete(subscriber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Set<Role> 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<Role> oldRoles = userToUpdate.getRoles();
|
||||
final Set<Role> tempOldRoles = new HashSet<>(oldRoles);
|
||||
|
||||
final String[] roleIds = (String[]) changes.get("roles");
|
||||
final Set<Role> updatedRoles = assembleSetOfRoles(roleIds);
|
||||
final Set<Role> 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<Topic> 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<TopicSubscriber> 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<Role> assembleSetOfRoles(final String[] rolesArray) {
|
||||
|
||||
final Set<Role> 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;
|
||||
}
|
||||
|
||||
}
|
||||
-32
@@ -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<TopicData> getAllTopics();
|
||||
|
||||
Collection<TopicData> getAllEnabledTopics();
|
||||
|
||||
TopicData findById(Long id);
|
||||
|
||||
}
|
||||
-96
@@ -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<TopicData> {
|
||||
|
||||
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<TopicData> getAllTopics() {
|
||||
final TopicMapper tm = new TopicMapper();
|
||||
String sql = "select " + tm.schema();
|
||||
return this.jdbcTemplate.query(sql, tm); // NOSONAR
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<TopicData> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
-28
@@ -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<TopicSubscriberData> getSubscribers(Long entityId, String entityType, String memberType);
|
||||
|
||||
}
|
||||
-77
@@ -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<TopicSubscriberData> {
|
||||
|
||||
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<TopicSubscriberData> 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
|
||||
}
|
||||
}
|
||||
-42
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
-27
@@ -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);
|
||||
|
||||
}
|
||||
-42
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
+5
-27
@@ -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.");
|
||||
}
|
||||
|
||||
+6
-1
@@ -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<String> roles;
|
||||
@Schema(example = "true")
|
||||
public Boolean sendPasswordToEmail;
|
||||
@Schema(example = "true")
|
||||
|
||||
+6
-1
@@ -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<String> permissions) {
|
||||
public boolean hasAnyPermission(String... permissions) {
|
||||
return hasAnyPermission(Arrays.asList(permissions));
|
||||
}
|
||||
|
||||
public boolean hasAnyPermission(final List<String> permissions) {
|
||||
boolean hasAtLeastOneOf = false;
|
||||
|
||||
for (final String permissionCode : permissions) {
|
||||
|
||||
+3
@@ -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<AppUser, Long>, JpaSpec
|
||||
|
||||
@Query("Select appUser from AppUser appUser where appUser.username = :username")
|
||||
AppUser findAppUserByName(@Param("username") String username);
|
||||
|
||||
Collection<AppUser> findByOfficeId(Long officeId);
|
||||
}
|
||||
|
||||
+8
-35
@@ -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<String, Object> 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.");
|
||||
}
|
||||
}
|
||||
|
||||
+6
-27
@@ -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<String, Object> 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) {
|
||||
|
||||
@@ -32,4 +32,5 @@
|
||||
<include file="parts/0010_lien_allowed_on_savings_account_products.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0011_add_credit_balance_refund_permission.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0012_add_merchantissuedrefund_payoutrefund_goodwillcredit_permissions.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0013_remove_topics.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
<changeSet author="fineract" id="1">
|
||||
<dropTable tableName="topic_subscriber"/>
|
||||
<dropTable tableName="topic"/>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
+66
-13
@@ -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<String, Object> response = (HashMap<String, Object>) 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<GetNotification> 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());
|
||||
}
|
||||
}
|
||||
|
||||
+27
-15
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -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<OfficeDomain>() {}.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,
|
||||
|
||||
+7
-2
@@ -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));
|
||||
|
||||
+2
@@ -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() {
|
||||
|
||||
}
|
||||
|
||||
+14
-4
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user