You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by na...@apache.org on 2017/08/21 10:49:26 UTC
[3/4] fineract git commit: Added Notification Module
Added Notification Module
Added Notification Module
Added Notification Module
Added Notification Module
Added license file for jar analyzer
Added entry into LICENSE_RELEASE file
Added gradle wrapper
Project: http://git-wip-us.apache.org/repos/asf/fineract/repo
Commit: http://git-wip-us.apache.org/repos/asf/fineract/commit/c60c6601
Tree: http://git-wip-us.apache.org/repos/asf/fineract/tree/c60c6601
Diff: http://git-wip-us.apache.org/repos/asf/fineract/diff/c60c6601
Branch: refs/heads/develop
Commit: c60c6601c07df7903214fcfbbb1145741fc0ef42
Parents: 455ef98
Author: Adhyan <ad...@yahoo.com>
Authored: Tue Jan 3 14:24:30 2017 +0530
Committer: Adhyan <ad...@yahoo.com>
Committed: Sun Aug 20 21:21:24 2017 +0530
----------------------------------------------------------------------
LICENSE_RELEASE | 4 +
fineract-provider/.gitignore | 1 +
fineract-provider/dependencies.gradle | 7 +-
fineract-provider/dev-dependencies.gradle | 6 +-
.../integrationtests/NotificationApiTest.java | 57 ++
.../common/NotificationHelper.java | 43 ++
.../TenantAwareBasicAuthenticationFilter.java | 13 +-
.../api/NotificationApiResource.java | 89 +++
.../cache/CacheNotificationResponseHeader.java | 50 ++
.../notification/data/NotificationData.java | 143 +++++
.../data/NotificationMapperData.java | 78 +++
.../notification/domain/Notification.java | 112 ++++
.../notification/domain/NotificationMapper.java | 78 +++
.../domain/NotificationMapperRepository.java | 24 +
.../domain/NotificationRepository.java | 24 +
.../NotificationEventListener.java | 96 +++
.../NotificationEventService.java | 50 ++
.../service/NotificationDomainService.java | 23 +
.../service/NotificationDomainServiceImpl.java | 590 +++++++++++++++++++
...ificationGeneratorReadRepositoryWrapper.java | 35 ++
...ationGeneratorReadRepositoryWrapperImpl.java | 53 ++
...tificationGeneratorWritePlatformService.java | 27 +
...cationGeneratorWritePlatformServiceImpl.java | 41 ++
...NotificationMapperReadRepositoryWrapper.java | 34 ++
...ficationMapperReadRepositoryWrapperImpl.java | 53 ++
.../NotificationMapperWritePlatformService.java | 27 +
...ificationMapperWritePlatformServiceImpl.java | 41 ++
.../NotificationReadPlatformService.java | 34 ++
.../NotificationReadPlatformServiceImpl.java | 219 +++++++
.../NotificationWritePlatformService.java | 29 +
.../NotificationWritePlatformServiceImpl.java | 129 ++++
...ntWritePlatformServiceJpaRepositoryImpl.java | 3 +
.../BusinessEventNotificationConstants.java | 14 +-
...esWritePlatformServiceJpaRepositoryImpl.java | 30 +-
...onWritePlatformServiceJpaRepositoryImpl.java | 2 +
...anWritePlatformServiceJpaRepositoryImpl.java | 3 +-
...ctWritePlatformServiceJpaRepositoryImpl.java | 19 +-
...ssWritePlatformServiceJpaRepositoryImpl.java | 27 +-
...ntWritePlatformServiceJpaRepositoryImpl.java | 8 +-
...ssWritePlatformServiceJpaRepositoryImpl.java | 6 +
...ntWritePlatformServiceJpaRepositoryImpl.java | 26 +-
...ctWritePlatformServiceJpaRepositoryImpl.java | 20 +-
.../resources/META-INF/spring/appContext.xml | 4 +
.../META-INF/spring/notificationContext.xml | 44 ++
.../V334__notification_module_tables.sql | 48 ++
.../apache/fineract/notification/Listener.java | 33 ++
.../fineract/notification/ListenerTest.java | 52 ++
.../fineract/notification/SenderTest.java | 77 +++
.../fineract/notification/StorageTest.java | 130 ++++
.../META-INF/testNotificationContext.xml | 52 ++
licenses/binary/JarAnalyzer.BSD | 26 +
51 files changed, 2810 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/LICENSE_RELEASE
----------------------------------------------------------------------
diff --git a/LICENSE_RELEASE b/LICENSE_RELEASE
index 8acc951..2c50915 100644
--- a/LICENSE_RELEASE
+++ b/LICENSE_RELEASE
@@ -300,4 +300,8 @@ This product bundles Backport Util Concurrent v3.1 written by Dawid Kurzyniec,
which is avilable under Public Domain license.
For details see licenses/binary/Backport.PL
+This product bundles JarAnalyzer v1.2 written by Kirk Knoernschild,
+which is available under BSD license.
+For details see licences/binary/JarAnalyzer.BSD
+
******************************************
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/.gitignore
----------------------------------------------------------------------
diff --git a/fineract-provider/.gitignore b/fineract-provider/.gitignore
index 8e9e830..e4bae86 100644
--- a/fineract-provider/.gitignore
+++ b/fineract-provider/.gitignore
@@ -7,5 +7,6 @@ repos
.settings
.gradle
*.log
+.idea
!gradle/wrapper/gradle-wrapper.jar
/gradle
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/dependencies.gradle
----------------------------------------------------------------------
diff --git a/fineract-provider/dependencies.gradle b/fineract-provider/dependencies.gradle
index f331016..562e767 100644
--- a/fineract-provider/dependencies.gradle
+++ b/fineract-provider/dependencies.gradle
@@ -91,11 +91,16 @@ dependencies {
[group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3.5'],
// Once we've switched to Java 8 this dep can be removed.
//[group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.0']
+ [group: 'org.springframework', name:'spring-jms'],
+ [group: 'org.apache.activemq', name: 'activemq-broker']
+
)
testCompile 'junit:junit:4.11',
'junit:junit-dep:4.11',
'org.mockito:mockito-core:1.9.5',
'com.jayway.restassured:rest-assured:2.3.3',
- [group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: springBootVersion]
+ [group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: springBootVersion],
+ [group: 'com.mockrunner', name: 'mockrunner-jms', version: '1.0.6'],
+ [group: 'com.mockrunner', name: 'mockrunner-jdbc', version: '1.0.6']
}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/dev-dependencies.gradle
----------------------------------------------------------------------
diff --git a/fineract-provider/dev-dependencies.gradle b/fineract-provider/dev-dependencies.gradle
index 949b678..80c8f49 100644
--- a/fineract-provider/dev-dependencies.gradle
+++ b/fineract-provider/dev-dependencies.gradle
@@ -90,11 +90,15 @@ dependencies {
[group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3.5'],
// Once we've switched to Java 8 this dep can be removed.
//[group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.0']
+ [group: 'org.springframework', name:'spring-jms'],
+ [group: 'org.apache.activemq', name: 'activemq-broker']
)
testCompile 'junit:junit:4.11',
'junit:junit-dep:4.11',
'org.mockito:mockito-core:1.9.5',
'com.jayway.restassured:rest-assured:2.3.3',
- [group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: springBootVersion]
+ [group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: springBootVersion],
+ [group: 'com.mockrunner', name: 'mockrunner-jms', version: '1.0.6'],
+ [group: 'com.mockrunner', name: 'mockrunner-jdbc', version: '1.0.6']
}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/NotificationApiTest.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/NotificationApiTest.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/NotificationApiTest.java
new file mode 100644
index 0000000..c516502
--- /dev/null
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/NotificationApiTest.java
@@ -0,0 +1,57 @@
+package org.apache.fineract.integrationtests;
+
+/**
+ * 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.
+ */
+
+
+import com.jayway.restassured.builder.RequestSpecBuilder;
+import com.jayway.restassured.builder.ResponseSpecBuilder;
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.specification.RequestSpecification;
+import com.jayway.restassured.specification.ResponseSpecification;
+import org.apache.fineract.integrationtests.common.NotificationHelper;
+import org.apache.fineract.integrationtests.common.Utils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.HashMap;
+
+public class NotificationApiTest {
+
+ private ResponseSpecification responseSpec;
+ private RequestSpecification requestSpec;
+
+ @Before
+ 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();
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testNotificationRetrieval() {
+ HashMap<String, Object> response = (HashMap<String, Object>) NotificationHelper.getNotifications(this.requestSpec,
+ this.responseSpec, "");
+ System.out.println("Response : " + response.toString());
+ Assert.assertNotNull(response);
+ }
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/NotificationHelper.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/NotificationHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/NotificationHelper.java
new file mode 100644
index 0000000..efac104
--- /dev/null
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/NotificationHelper.java
@@ -0,0 +1,43 @@
+package org.apache.fineract.integrationtests.common;
+
+/**
+ * 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.
+ */
+
+import com.jayway.restassured.specification.RequestSpecification;
+import com.jayway.restassured.specification.ResponseSpecification;
+
+public class NotificationHelper {
+
+ private final RequestSpecification requestSpec;
+ private final ResponseSpecification responseSpec;
+
+ private static final String NOTIFICATION_API_URL = "/fineract-provider/api/v1/notifications?" + Utils.TENANT_IDENTIFIER;
+
+ public NotificationHelper(RequestSpecification requestSpec, ResponseSpecification responseSpec) {
+ this.requestSpec = requestSpec;
+ this.responseSpec = responseSpec;
+ }
+
+ public static Object getNotifications(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
+ final String jsonReturn) {
+ final String GET_NOTIFICATIONS_URL = NOTIFICATION_API_URL;
+ System.out.println("-----------------------------GET NOTIFICATIONS-----------------------------------");
+ return Utils.performServerGet(requestSpec, responseSpec, GET_NOTIFICATIONS_URL, "");
+ }
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java
index abe243e..a36079d 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java
@@ -37,6 +37,7 @@ import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
import org.apache.fineract.infrastructure.security.data.PlatformRequestLog;
import org.apache.fineract.infrastructure.security.exception.InvalidTenantIdentiferException;
import org.apache.fineract.infrastructure.security.service.BasicAuthTenantDetailsService;
+import org.apache.fineract.notification.service.NotificationReadPlatformService;
import org.apache.fineract.useradministration.domain.AppUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -77,7 +78,7 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
private final ToApiJsonSerializer<PlatformRequestLog> toApiJsonSerializer;
private final ConfigurationDomainService configurationDomainService;
private final CacheWritePlatformService cacheWritePlatformService;
-
+ private final NotificationReadPlatformService notificationReadPlatformService;
private final String tenantRequestHeader = "Fineract-Platform-TenantId";
private final boolean exceptionIfHeaderMissing = true;
@@ -85,12 +86,14 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
public TenantAwareBasicAuthenticationFilter(final AuthenticationManager authenticationManager,
final AuthenticationEntryPoint authenticationEntryPoint, final BasicAuthTenantDetailsService basicAuthTenantDetailsService,
final ToApiJsonSerializer<PlatformRequestLog> toApiJsonSerializer, final ConfigurationDomainService configurationDomainService,
- final CacheWritePlatformService cacheWritePlatformService) {
+ final CacheWritePlatformService cacheWritePlatformService,
+ final NotificationReadPlatformService notificationReadPlatformService) {
super(authenticationManager, authenticationEntryPoint);
this.basicAuthTenantDetailsService = basicAuthTenantDetailsService;
this.toApiJsonSerializer = toApiJsonSerializer;
this.configurationDomainService = configurationDomainService;
this.cacheWritePlatformService = cacheWritePlatformService;
+ this.notificationReadPlatformService = notificationReadPlatformService;
}
@Override
@@ -167,6 +170,12 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
throws IOException {
super.onSuccessfulAuthentication(request, response, authResult);
AppUser user = (AppUser) authResult.getPrincipal();
+
+ if (notificationReadPlatformService.hasUnreadNotifications(user.getId())) {
+ response.addHeader("X-Notification-Refresh", "true");
+ } else {
+ response.addHeader("X-Notification-Refresh", "false");
+ }
String pathURL = request.getRequestURI();
boolean isSelfServiceRequest = (pathURL != null && pathURL.contains("/self/"));
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/api/NotificationApiResource.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/api/NotificationApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/notification/api/NotificationApiResource.java
new file mode 100644
index 0000000..065d7cb
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/api/NotificationApiResource.java
@@ -0,0 +1,89 @@
+/**
+ * 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 org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
+import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
+import org.apache.fineract.infrastructure.core.serialization.ToApiJsonSerializer;
+import org.apache.fineract.infrastructure.core.service.Page;
+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;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+
+@Path("/notifications")
+@Component
+@Scope("singleton")
+public class NotificationApiResource {
+
+ private final PlatformSecurityContext context;
+ private final NotificationReadPlatformService notificationReadPlatformService;
+ 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) {
+
+ this.context.authenticatedUser();
+ final Page<NotificationData> notificationData;
+ final SearchParameters searchParameters = SearchParameters.forPagination(offset, limit, orderBy, sortOrder);
+ if (!isRead) {
+ notificationData = this.notificationReadPlatformService.getAllUnreadNotifications(searchParameters);
+ } else {
+ notificationData = this.notificationReadPlatformService.getAllNotifications(searchParameters);
+ }
+ final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper
+ .process(uriInfo.getQueryParameters());
+ return this.toApiJsonSerializer.serialize(settings, notificationData);
+ }
+
+ @PUT
+ @Consumes({MediaType.APPLICATION_JSON})
+ @Produces({MediaType.APPLICATION_JSON})
+ public void update() {
+ this.context.authenticatedUser();
+ this.notificationReadPlatformService.updateNotificationReadStatus();
+ }
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/cache/CacheNotificationResponseHeader.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/cache/CacheNotificationResponseHeader.java b/fineract-provider/src/main/java/org/apache/fineract/notification/cache/CacheNotificationResponseHeader.java
new file mode 100644
index 0000000..205050b
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/cache/CacheNotificationResponseHeader.java
@@ -0,0 +1,50 @@
+/**
+ * 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.cache;
+
+
+public class CacheNotificationResponseHeader {
+
+ private boolean hasNotifications;
+ private Long lastFetch;
+
+ public CacheNotificationResponseHeader() {
+ }
+
+ public CacheNotificationResponseHeader(boolean hasNotifications, Long lastFetch) {
+ this.hasNotifications = hasNotifications;
+ this.lastFetch = lastFetch;
+ }
+
+ public boolean hasNotifications() {
+ return hasNotifications;
+ }
+
+ public void setHasNotifications(boolean hasNotifications) {
+ this.hasNotifications = hasNotifications;
+ }
+
+ public Long getLastFetch() {
+ return lastFetch;
+ }
+
+ public void setLastFetch(Long lastFetch) {
+ this.lastFetch = lastFetch;
+ }
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/data/NotificationData.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/data/NotificationData.java b/fineract-provider/src/main/java/org/apache/fineract/notification/data/NotificationData.java
new file mode 100644
index 0000000..63dab1a
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/data/NotificationData.java
@@ -0,0 +1,143 @@
+/**
+ * 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;
+import java.util.List;
+
+public class NotificationData implements Serializable {
+
+ private Long id;
+ private String objectType;
+ private Long objectId;
+ private String action;
+ private Long actorId;
+ private String content;
+ private boolean isSystemGenerated;
+ private String tenantIdentifier;
+ private String createdAt;
+ private Long officeId;
+ private List<Long> userIds;
+
+ public NotificationData() {
+
+ }
+
+ public NotificationData(String objectType, Long objectId, String action, Long actorId, String content, boolean isSystemGenerated,
+ String tenantIdentifier, Long officeId, List<Long> userIds) {
+ this.objectType = objectType;
+ this.objectId = objectId;
+ this.action = action;
+ this.actorId = actorId;
+ this.content = content;
+ this.isSystemGenerated = isSystemGenerated;
+ this.tenantIdentifier = tenantIdentifier;
+ 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 isSystemGenerated() {
+ return isSystemGenerated;
+ }
+
+ public void setSystemGenerated(boolean systemGenerated) {
+ isSystemGenerated = systemGenerated;
+ }
+
+ public String getTenantIdentifier() {
+ return tenantIdentifier;
+ }
+
+ public void setTenantIdentifier(String tenantIdentifier) {
+ this.tenantIdentifier = tenantIdentifier;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/data/NotificationMapperData.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/data/NotificationMapperData.java b/fineract-provider/src/main/java/org/apache/fineract/notification/data/NotificationMapperData.java
new file mode 100644
index 0000000..659fb5f
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/data/NotificationMapperData.java
@@ -0,0 +1,78 @@
+/**
+ * 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;
+
+public class NotificationMapperData {
+
+ private Long id;
+ private Long notificationId;
+ private Long userId;
+ private boolean isRead;
+ private String createdAt;
+
+ public NotificationMapperData(Long id, Long notificationId, Long userId, boolean isRead, String createdAt) {
+ this.id = id;
+ this.notificationId = notificationId;
+ this.userId = userId;
+ this.isRead = isRead;
+ this.createdAt = createdAt;
+ }
+
+ public NotificationMapperData() {}
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getNotificationId() {
+ return notificationId;
+ }
+
+ public void setNotificationId(Long notificationId) {
+ this.notificationId = notificationId;
+ }
+
+ public Long getUserId() {
+ return userId;
+ }
+
+ public void setUserId(Long userId) {
+ this.userId = userId;
+ }
+
+ public boolean isRead() {
+ return isRead;
+ }
+
+ public void setRead(boolean read) {
+ isRead = read;
+ }
+
+ public String getCreatedAt() {
+ return createdAt;
+ }
+
+ public void setCreatedAt(String createdAt) {
+ this.createdAt = createdAt;
+ }
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/domain/Notification.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/Notification.java b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/Notification.java
new file mode 100644
index 0000000..cf7d41e
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/Notification.java
@@ -0,0 +1,112 @@
+/**
+ * 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 org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "notification_generator")
+public class Notification extends AbstractPersistableCustom<Long> {
+
+ @Column(name = "object_type")
+ private String objectType;
+
+ @Column(name = "object_identifier")
+ private Long objectIdentifier;
+
+ @Column(name = "action")
+ private String action;
+
+ @Column(name = "actor")
+ private Long actorId;
+
+ @Column(name = "is_system_generated")
+ private boolean isSystemGenerated;
+
+ @Column(name = "notification_content")
+ private String notificationContent;
+
+ @Column(name = "created_at")
+ private String createdAt;
+
+ public Notification() {}
+
+ public Notification(String objectType, Long objectIdentifier, String action, Long actorId, boolean isSystemGenerated,
+ String notificationContent, String createdAt) {
+ this.objectType = objectType;
+ this.objectIdentifier = objectIdentifier;
+ this.action = action;
+ this.actorId = actorId;
+ this.isSystemGenerated = isSystemGenerated;
+ this.notificationContent = notificationContent;
+ this.createdAt = createdAt;
+ }
+
+ public String getObjectType() {
+ return objectType;
+ }
+
+ public void setObjectType(String objectType) {
+ this.objectType = objectType;
+ }
+
+ public Long getObjectIdentifier() {
+ return objectIdentifier;
+ }
+
+ public void setObjectIdentifier(Long objectIdentifier) {
+ this.objectIdentifier = objectIdentifier;
+ }
+
+ public String getAction() {
+ return action;
+ }
+
+ public void setAction(String action) {
+ this.action = action;
+ }
+
+ public Long getActor() {
+ return actorId;
+ }
+
+ public void setActor(Long actor) {
+ this.actorId = actorId;
+ }
+
+ public boolean isSystemGenerated() {
+ return isSystemGenerated;
+ }
+
+ public void setSystemGenerated(boolean systemGenerated) {
+ isSystemGenerated = systemGenerated;
+ }
+
+ public String getNotificationContent() {
+ return notificationContent;
+ }
+
+ public void setNotificationContent(String notificationContent) {
+ this.notificationContent = notificationContent;
+ }
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationMapper.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationMapper.java b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationMapper.java
new file mode 100644
index 0000000..5297d23
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationMapper.java
@@ -0,0 +1,78 @@
+/**
+ * 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 org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
+import org.apache.fineract.useradministration.domain.AppUser;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "notification_mapper")
+public class NotificationMapper extends AbstractPersistableCustom<Long> {
+
+ @ManyToOne
+ @JoinColumn(name = "notification_id")
+ private Notification notification;
+
+ @ManyToOne
+ @JoinColumn(name = "user_id")
+ private AppUser userId;
+
+ @Column(name = "is_read")
+ private boolean isRead;
+
+ @Column(name = "created_at")
+ private String createdAt;
+
+ public NotificationMapper() {}
+
+ public NotificationMapper(Notification notification, AppUser userId, boolean isRead, String createdAt) {
+ this.notification = notification;
+ this.userId = userId;
+ this.isRead = isRead;
+ this.createdAt = createdAt;
+ }
+
+ public Notification getNotification() {
+ return notification;
+ }
+
+ public void setNotification(Notification notification) {
+ this.notification = notification;
+ }
+
+ public AppUser getUserId() {
+ return userId;
+ }
+
+ public void setUserId(AppUser userId) {
+ this.userId = userId;
+ }
+
+ public boolean isRead() {
+ return isRead;
+ }
+
+ public void setRead(boolean read) {
+ isRead = read;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationMapperRepository.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationMapperRepository.java b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationMapperRepository.java
new file mode 100644
index 0000000..fb88509
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationMapperRepository.java
@@ -0,0 +1,24 @@
+/**
+ * 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 org.springframework.data.jpa.repository.JpaRepository;
+
+
+public interface NotificationMapperRepository extends JpaRepository<NotificationMapper, Long> {}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationRepository.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationRepository.java b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationRepository.java
new file mode 100644
index 0000000..ed0675d
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/domain/NotificationRepository.java
@@ -0,0 +1,24 @@
+/**
+ * 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 org.springframework.data.jpa.repository.JpaRepository;
+
+
+public interface NotificationRepository extends JpaRepository<Notification, Long> {}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventListener.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventListener.java b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventListener.java
new file mode 100644
index 0000000..bf80437
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventListener.java
@@ -0,0 +1,96 @@
+/**
+ * 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 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.jms.listener.SessionAwareMessageListener;
+import org.springframework.stereotype.Service;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.ObjectMessage;
+import javax.jms.Session;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+@Service
+public class NotificationEventListener implements SessionAwareMessageListener {
+
+ 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;
+ }
+
+ @Override
+ public void onMessage(Message message, Session session) throws JMSException {
+ if (message instanceof ObjectMessage) {
+ NotificationData notificationData = (NotificationData) ((ObjectMessage) message).getObject();
+
+ 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.findOne(userId);
+ 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()
+ );
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventService.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventService.java b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventService.java
new file mode 100644
index 0000000..a2f32df
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/eventandlistener/NotificationEventService.java
@@ -0,0 +1,50 @@
+/**
+ * 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 org.apache.fineract.notification.data.NotificationData;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jms.core.JmsTemplate;
+import org.springframework.jms.core.MessageCreator;
+import org.springframework.stereotype.Service;
+
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.Session;
+
+@Service
+public class NotificationEventService {
+
+ 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);
+ }
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationDomainService.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationDomainService.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationDomainService.java
new file mode 100644
index 0000000..7044aa9
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationDomainService.java
@@ -0,0 +1,23 @@
+/**
+ * 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;
+
+public interface NotificationDomainService {
+
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationDomainServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationDomainServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationDomainServiceImpl.java
new file mode 100644
index 0000000..e8becbe
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationDomainServiceImpl.java
@@ -0,0 +1,590 @@
+/**
+ * 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.activemq.command.ActiveMQQueue;
+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.eventandlistener.NotificationEventService;
+import org.apache.fineract.portfolio.client.domain.Client;
+import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants;
+import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_ENTITY;
+import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_EVENTS;
+import org.apache.fineract.portfolio.common.service.BusinessEventListner;
+import org.apache.fineract.portfolio.common.service.BusinessEventNotifierService;
+import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
+import org.apache.fineract.portfolio.savings.DepositAccountType;
+import org.apache.fineract.portfolio.savings.domain.FixedDepositAccount;
+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.AppUser;
+import org.apache.fineract.useradministration.domain.AppUserRepository;
+import org.apache.fineract.useradministration.domain.Role;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.jms.Queue;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+@Service
+public class NotificationDomainServiceImpl implements NotificationDomainService {
+
+ private final BusinessEventNotifierService businessEventNotifierService;
+ private final NotificationEventService notificationEventService;
+ private final AppUserRepository appUserRepository;
+ private final PlatformSecurityContext context;
+
+
+ @Autowired
+ public NotificationDomainServiceImpl(final BusinessEventNotifierService businessEventNotifierService,
+ final NotificationEventService notificationEventService,
+ final AppUserRepository appUserRepository,
+ final PlatformSecurityContext context) {
+ this.businessEventNotifierService = businessEventNotifierService;
+ this.notificationEventService = notificationEventService;
+ this.appUserRepository = appUserRepository;
+ this.context = context;
+ }
+
+ @PostConstruct
+ public void addListeners() {
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.CLIENTS_CREATE,
+ new ClientCreatedListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SAVINGS_APPROVE,
+ new SavingsAccountApprovedListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.CENTERS_CREATE,
+ new CenterCreatedListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.GROUPS_CREATE,
+ new GroupCreatedListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SAVINGS_DEPOSIT,
+ new SavingsAccountDepositListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SHARE_PRODUCT_DIVIDENDS_CREATE,
+ new ShareProductDividendCreatedListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.FIXED_DEPOSIT_ACCOUNT_CREATE,
+ new FixedDepositAccountCreatedListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.RECURRING_DEPOSIT_ACCOUNT_CREATE,
+ new RecurringDepositAccountCreatedListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SAVINGS_POST_INTEREST,
+ new SavingsPostInterestListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.LOAN_CREATE,
+ new LoanCreatedListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.LOAN_APPROVED,
+ new LoanApprovedListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.LOAN_CLOSE,
+ new LoanClosedListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.LOAN_CLOSE_AS_RESCHEDULE,
+ new LoanCloseAsRescheduledListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.LOAN_MAKE_REPAYMENT,
+ new LoanMakeRepaymentListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.LOAN_PRODUCT_CREATE,
+ new LoanProductCreatedListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SAVINGS_CREATE,
+ new SavingsAccountCreatedListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SAVINGS_CLOSE,
+ new SavingsAccountClosedListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SHARE_ACCOUNT_CREATE,
+ new ShareAccountCreatedListener());
+ businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SHARE_ACCOUNT_APPROVE,
+ new ShareAccountApprovedListener());
+ }
+
+ private abstract class NotificationBusinessEventAdapter implements BusinessEventListner {
+
+ @Override
+ public void businessEventToBeExecuted(Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> businessEventEntity) {
+ //Nothing to do
+ }
+ }
+
+ private class ClientCreatedListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> businessEventEntity) {
+ Client client;
+ Object entity = businessEventEntity.get(BusinessEventNotificationConstants.BUSINESS_ENTITY.CLIENT);
+ if (entity != null) {
+ client = (Client) entity;
+ buildNotification(
+ "ACTIVATE_CLIENT",
+ "client",
+ client.getId(),
+ "New client created",
+ "created",
+ context.authenticatedUser().getId(),
+ client.getOffice().getId()
+ );
+ }
+ }
+ }
+
+ private class CenterCreatedListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> businessEventEntity) {
+ CommandProcessingResult commandProcessingResult;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.GROUP);
+ if (entity != null) {
+ commandProcessingResult = (CommandProcessingResult) entity;
+ buildNotification(
+ "ACTIVATE_CENTER",
+ "center",
+ commandProcessingResult.getGroupId(),
+ "New center created",
+ "created",
+ context.authenticatedUser().getId(),
+ commandProcessingResult.getOfficeId()
+ );
+ }
+ }
+ }
+
+ private class GroupCreatedListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> businessEventEntity) {
+ CommandProcessingResult commandProcessingResult;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.GROUP);
+ if (entity != null) {
+ commandProcessingResult = (CommandProcessingResult) entity;
+ buildNotification(
+ "ACTIVATE_GROUP",
+ "group",
+ commandProcessingResult.getGroupId(),
+ "New group created",
+ "created",
+ context.authenticatedUser().getId(),
+ commandProcessingResult.getOfficeId()
+ );
+ }
+ }
+ }
+
+ private class SavingsAccountDepositListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+ SavingsAccountTransaction savingsAccountTransaction;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.SAVINGS_TRANSACTION);
+ if (entity != null) {
+ savingsAccountTransaction = (SavingsAccountTransaction) entity;
+ buildNotification(
+ "READ_SAVINGSACCOUNT",
+ "savingsAccount",
+ savingsAccountTransaction.getSavingsAccount().getId(),
+ "Deposit made",
+ "depositMade",
+ context.authenticatedUser().getId(),
+ savingsAccountTransaction.getSavingsAccount().officeId()
+ );
+ }
+ }
+ }
+
+ private class ShareProductDividendCreatedListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+ Long shareProductId;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.SHARE_PRODUCT);
+ if (entity != null) {
+ shareProductId = (Long) entity;
+ buildNotification(
+ "READ_DIVIDEND_SHAREPRODUCT",
+ "shareProduct",
+ shareProductId,
+ "Dividend posted to account",
+ "dividendPosted",
+ context.authenticatedUser().getId(),
+ context.authenticatedUser().getOffice().getId()
+ );
+ }
+ }
+ }
+
+ private class FixedDepositAccountCreatedListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+ FixedDepositAccount fixedDepositAccount;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.DEPOSIT_ACCOUNT);
+ if (entity != null) {
+ fixedDepositAccount = (FixedDepositAccount) entity;
+ buildNotification(
+ "APPROVE_FIXEDDEPOSITACCOUNT",
+ "fixedDeposit",
+ fixedDepositAccount.getId(),
+ "New fixed deposit account created",
+ "created",
+ context.authenticatedUser().getId(),
+ fixedDepositAccount.officeId()
+ );
+ }
+ }
+ }
+
+ private class RecurringDepositAccountCreatedListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+ RecurringDepositAccount recurringDepositAccount;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.DEPOSIT_ACCOUNT);
+ if (entity != null) {
+ recurringDepositAccount = (RecurringDepositAccount) entity;
+ buildNotification(
+ "APPROVE_RECURRINGDEPOSITACCOUNT",
+ "recurringDepositAccount",
+ recurringDepositAccount.getId(),
+ "New recurring deposit account created",
+ "created",
+ context.authenticatedUser().getId(),
+ recurringDepositAccount.officeId()
+ );
+ }
+ }
+ }
+
+
+ private class SavingsAccountApprovedListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+ SavingsAccount savingsAccount;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.SAVING);
+ if (entity != null) {
+ savingsAccount = (SavingsAccount) entity;
+ if (savingsAccount.depositAccountType().equals(DepositAccountType.FIXED_DEPOSIT)) {
+
+ buildNotification(
+ "ACTIVATE_FIXEDDEPOSITACCOUNT",
+ "fixedDeposit",
+ savingsAccount.getId(),
+ "Fixed deposit account approved",
+ "approved",
+ context.authenticatedUser().getId(),
+ savingsAccount.officeId()
+ );
+
+ } else if (savingsAccount.depositAccountType().equals(DepositAccountType.RECURRING_DEPOSIT)) {
+
+ buildNotification(
+ "ACTIVATE_RECURRINGDEPOSITACCOUNT",
+ "recurringDepositAccount",
+ savingsAccount.getId(),
+ "Recurring deposit account approved",
+ "approved",
+ context.authenticatedUser().getId(),
+ savingsAccount.officeId()
+ );
+
+ } else if (savingsAccount.depositAccountType().equals(DepositAccountType.SAVINGS_DEPOSIT)) {
+
+ buildNotification(
+ "ACTIVATE_SAVINGSACCOUNT",
+ "savingsAccount",
+ savingsAccount.getId(),
+ "Savings account approved",
+ "approved",
+ context.authenticatedUser().getId(),
+ savingsAccount.officeId()
+ );
+ }
+ }
+ }
+ }
+
+ private class SavingsPostInterestListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+ SavingsAccount savingsAccount;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.SAVING);
+ if (entity != null) {
+ savingsAccount = (SavingsAccount) entity;
+ buildNotification(
+ "READ_SAVINGSACCOUNT",
+ "savingsAccount",
+ savingsAccount.getId(),
+ "Interest posted to account",
+ "interestPosted",
+ context.authenticatedUser().getId(),
+ savingsAccount.officeId()
+ );
+ }
+ }
+ }
+
+ private class LoanCreatedListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+ Loan loan;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.LOAN);
+ if (entity != null) {
+ loan = (Loan) entity;
+ buildNotification(
+ "APPROVE_LOAN",
+ "loan",
+ loan.getId(),
+ "New loan created",
+ "created",
+ context.authenticatedUser().getId(),
+ loan.getOfficeId()
+ );
+ }
+ }
+ }
+
+ private class LoanApprovedListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+ Loan loan;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.LOAN);
+ if (entity != null) {
+ loan = (Loan) entity;
+ buildNotification(
+ "DISBURSE_LOAN",
+ "loan",
+ loan.getId(),
+ "New loan approved",
+ "approved",
+ context.authenticatedUser().getId(),
+ loan.getOfficeId()
+ );
+ }
+ }
+ }
+
+ private class LoanClosedListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+ Loan loan;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.LOAN);
+ if (entity != null) {
+ loan = (Loan) entity;
+ buildNotification(
+ "READ_LOAN",
+ "loan",
+ loan.getId(),
+ "Loan closed",
+ "loanClosed",
+ context.authenticatedUser().getId(),
+ loan.getOfficeId()
+ );
+ }
+ }
+ }
+
+ private class LoanCloseAsRescheduledListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+ Loan loan;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.LOAN);
+ if (entity != null) {
+ loan = (Loan) entity;
+ buildNotification(
+ "READ_Rescheduled Loans",
+ "loan",
+ loan.getId(),
+ "Loan has been rescheduled",
+ "loanRescheduled",
+ context.authenticatedUser().getId(),
+ loan.getOfficeId()
+ );
+ }
+ }
+ }
+
+ private class LoanMakeRepaymentListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+ Loan loan;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.LOAN);
+ if (entity != null) {
+ loan = (Loan) entity;
+ buildNotification(
+ "READ_LOAN",
+ "loan",
+ loan.getId(),
+ "Repayment made",
+ "repaymentMade",
+ context.authenticatedUser().getId(),
+ loan.getOfficeId()
+ );
+ }
+ }
+ }
+
+ private class LoanProductCreatedListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+
+ LoanProduct loanProduct;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.LOAN_PRODUCT);
+ if (entity != null) {
+ loanProduct = (LoanProduct) entity;
+ buildNotification(
+ "READ_LOANPRODUCT",
+ "loanProduct",
+ loanProduct.getId(),
+ "New loan product created",
+ "created",
+ context.authenticatedUser().getId(),
+ context.authenticatedUser().getOffice().getId()
+ );
+ }
+ }
+ }
+
+ private class SavingsAccountCreatedListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+ SavingsAccount savingsAccount;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.SAVING);
+ if (entity != null) {
+ savingsAccount = (SavingsAccount) entity;
+ buildNotification(
+ "APPROVE_SAVINGSACCOUNT",
+ "savingsAccount",
+ savingsAccount.getId(),
+ "New savings account created",
+ "created",
+ context.authenticatedUser().getId(),
+ savingsAccount.officeId()
+ );
+ }
+ }
+ }
+
+ private class SavingsAccountClosedListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+ SavingsAccount savingsAccount;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.SAVING);
+ if (entity != null) {
+ savingsAccount = (SavingsAccount) entity;
+ buildNotification(
+ "READ_SAVINGSACCOUNT",
+ "savingsAccount",
+ savingsAccount.getId(),
+ "Savings has gone into dormant",
+ "closed",
+ context.authenticatedUser().getId(),
+ savingsAccount.officeId()
+ );
+ }
+ }
+ }
+
+ private class ShareAccountCreatedListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+ ShareAccount shareAccount;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.SHARE_ACCOUNT);
+ if (entity != null) {
+ shareAccount = (ShareAccount) entity;
+ buildNotification(
+ "APPROVE_SHAREACCOUNT",
+ "shareAccount",
+ shareAccount.getId(),
+ "New share account created",
+ "created",
+ context.authenticatedUser().getId(),
+ shareAccount.getOfficeId()
+ );
+ }
+ }
+ }
+
+ private class ShareAccountApprovedListener extends NotificationBusinessEventAdapter {
+
+ @Override
+ public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
+ ShareAccount shareAccount;
+ Object entity = businessEventEntity.get(BUSINESS_ENTITY.SHARE_ACCOUNT);
+ if (entity != null) {
+ shareAccount = (ShareAccount) entity;
+ buildNotification(
+ "ACTIVATE_SHAREACCOUNT",
+ "shareAccount",
+ shareAccount.getId(),
+ "Share account approved",
+ "approved",
+ context.authenticatedUser().getId(),
+ shareAccount.getOfficeId()
+ );
+ }
+ }
+ }
+
+ private void buildNotification(String permission, String objectType,
+ Long objectIdentifier, String notificationContent, String eventType,
+ Long appUserId, Long officeId) {
+
+ String tenantIdentifier = ThreadLocalContextUtil.getTenant().getTenantIdentifier();
+ Queue queue = new ActiveMQQueue("NotificationQueue");
+ List<Long> userIds = retrieveUsersWithSpecificPermission(permission);
+ NotificationData notificationData = new NotificationData(
+ objectType,
+ objectIdentifier,
+ eventType,
+ appUserId,
+ notificationContent,
+ false,
+ tenantIdentifier,
+ officeId,
+ userIds
+ );
+ notificationEventService.broadcastNotification(queue, notificationData);
+
+ }
+
+ private List<Long> retrieveUsersWithSpecificPermission(String permission) {
+ List<AppUser> appUsers = appUserRepository.findAll();
+ List<Long> userIds = new ArrayList<>();
+ for (AppUser appUser : appUsers) {
+ Set<Role> roles = appUser.getRoles();
+ for (Role role : roles) {
+ if (role.hasPermissionTo(permission)) {
+ if (!(userIds.contains(appUser.getId()))) {
+ userIds.add(appUser.getId());
+ }
+ }
+ }
+ }
+ return userIds;
+ }
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorReadRepositoryWrapper.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorReadRepositoryWrapper.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorReadRepositoryWrapper.java
new file mode 100644
index 0000000..8004382
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorReadRepositoryWrapper.java
@@ -0,0 +1,35 @@
+/**
+ * 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.Notification;
+
+import java.util.List;
+
+
+public interface NotificationGeneratorReadRepositoryWrapper {
+
+
+ Notification findById(Long id);
+
+ List<Notification> fetchAllNotifications();
+
+ void delete(Long id);
+
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorReadRepositoryWrapperImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorReadRepositoryWrapperImpl.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorReadRepositoryWrapperImpl.java
new file mode 100644
index 0000000..2bba025
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorReadRepositoryWrapperImpl.java
@@ -0,0 +1,53 @@
+/**
+ * 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.Notification;
+import org.apache.fineract.notification.domain.NotificationRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class NotificationGeneratorReadRepositoryWrapperImpl implements NotificationGeneratorReadRepositoryWrapper {
+
+ private final NotificationRepository notificationRepository;
+
+ @Autowired
+ public NotificationGeneratorReadRepositoryWrapperImpl(NotificationRepository notificationRepository) {
+ this.notificationRepository = notificationRepository;
+ }
+
+ @Override
+ public Notification findById(Long id) {
+ return this.notificationRepository.findOne(id);
+ }
+
+ @Override
+ public List<Notification> fetchAllNotifications() {
+ return this.notificationRepository.findAll();
+ }
+
+ @Override
+ public void delete(Long id) {
+ this.notificationRepository.delete(id);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorWritePlatformService.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorWritePlatformService.java
new file mode 100644
index 0000000..1941955
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorWritePlatformService.java
@@ -0,0 +1,27 @@
+/**
+ * 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.Notification;
+
+public interface NotificationGeneratorWritePlatformService {
+
+ Long create(Notification notification);
+
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorWritePlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorWritePlatformServiceImpl.java
new file mode 100644
index 0000000..c78cbe7
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationGeneratorWritePlatformServiceImpl.java
@@ -0,0 +1,41 @@
+/**
+ * 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.Notification;
+import org.apache.fineract.notification.domain.NotificationRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+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.save(notification);
+ return notification.getId();
+ }
+}
http://git-wip-us.apache.org/repos/asf/fineract/blob/c60c6601/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationMapperReadRepositoryWrapper.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationMapperReadRepositoryWrapper.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationMapperReadRepositoryWrapper.java
new file mode 100644
index 0000000..157f2ff
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationMapperReadRepositoryWrapper.java
@@ -0,0 +1,34 @@
+/**
+ * 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.NotificationMapper;
+
+import java.util.List;
+
+public interface NotificationMapperReadRepositoryWrapper {
+
+
+ NotificationMapper findById(Long id);
+
+ List<NotificationMapper> fetchAllNotifications();
+
+ void delete(Long id);
+
+}