Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Accelerator 4] Adding real time event notification #193

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions financial-services-accelerator/accelerators/fs-is/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
<exclude>**/commons-beanutils-1.9.4.jar</exclude>
<exclude>**/hibernate-validator-6.0.20.Final.jar</exclude>
<exclude>**/validation-api-2.0.1.Final.jar</exclude>
<exclude>**/quartz-2.3.2.jar</exclude>
</excludes>
</fileset>
<fileset>
Expand Down Expand Up @@ -117,6 +118,13 @@
regex="org.wso2.financial.services.accelerator.consent.mgt.dao-(\d.*?)\.jar$"/>
</fileset>
</copy>
<copy todir="${project.basedir}/carbon-home/repository/components/dropins" overwrite="true">
<fileset
dir="../../components/org.wso2.financial.services.accelerator.event.notifications.service/target">
<filename
regex="org.wso2.financial.services.accelerator.event.notifications.service-(\d.*?)\.jar$"/>
</fileset>
</copy>

<unzip src="../../internal-webapps/org.wso2.financial.services.accelerator.consent.mgt.endpoint/target/api#fs#consent.war"
dest="${project.basedir}/carbon-home/repository/deployment/server/webapps/api#fs#consent/"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public class HTTPClientUtils {
* @return Closeable https client
* @throws FinancialServicesException FinancialServicesException exception
*/
@Generated(message = "Ignoring because ServerConfiguration cannot be mocked")
@Generated(message = "Ignoring since method contains no logics")
public static CloseableHttpClient getHttpsClient() throws FinancialServicesException {

SSLConnectionSocketFactory sslsf = createSSLConnectionSocketFactory();
Expand All @@ -89,13 +89,13 @@ public static CloseableHttpClient getHttpsClient() throws FinancialServicesExcep
}

/**
* Get closeable https client to send realtime event notifications.
* Get closeable https client with given max Total and max per route values.
*
* @return Closeable https client
* @throws FinancialServicesException FinancialServicesException exception
*/
@Generated(message = "Ignoring since method contains no logics")
public static CloseableHttpClient getRealtimeEventNotificationHttpsClient() throws FinancialServicesException {
public static CloseableHttpClient getHttpsClient(int maxTotal, int maxPerRoute) throws FinancialServicesException {

SSLConnectionSocketFactory sslsf = createSSLConnectionSocketFactory();

Expand All @@ -109,10 +109,8 @@ public static CloseableHttpClient getRealtimeEventNotificationHttpsClient() thro
new PoolingHttpClientConnectionManager();

// configuring default maximum connections
connectionManager.setMaxTotal(FinancialServicesConfigParser.getInstance()
.getRealtimeEventNotificationMaxRetries() + 1);
connectionManager.setDefaultMaxPerRoute(FinancialServicesConfigParser.getInstance()
.getRealtimeEventNotificationMaxRetries() + 1);
connectionManager.setMaxTotal(maxTotal);
connectionManager.setDefaultMaxPerRoute(maxPerRoute);

return HttpClients.custom().setConnectionManager(connectionManager).build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,14 @@ public static KeyStore getTrustStore() throws ConsentManagementException {
*/
public static String signJWTWithDefaultKey(String body) throws Exception {
KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(-1234);
Key privateKey = keyStoreManager.getDefaultPrivateKey();
return generateJWT(body, privateKey);
KeyStore primaryKeyStore = keyStoreManager.getPrimaryKeyStore();
if (primaryKeyStore != null) {
Key privateKey = keyStoreManager.getDefaultPrivateKey();
return generateJWT(body, privateKey);
} else {
throw new FinancialServicesRuntimeException("Error while retrieving the Primary Keystore");
}

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,9 @@
org.wso2.carbon.identity.oauth2.*;version="${identity.inbound.auth.oauth.version.range}",
org.wso2.financial.services.accelerator.common.*;version="${project.version}",
org.wso2.financial.services.accelerator.consent.mgt.dao.*;version="${project.version}",
org.wso2.financial.services.accelerator.consent.mgt.service.*;version="${project.version}",
org.wso2.financial.services.accelerator.consent.mgt.service.*;version="${project.version}"
</Import-Package>
<DynamicImport-Package>*</DynamicImport-Package>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed offline, let's create an issue to remove this dynamic imports line in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created issue #218

<Export-Package>
!org.wso2.financial.services.accelerator.event.notifications.service.internal,
org.wso2.financial.services.accelerator.event.notifications.service.*;version="${project.version}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;
import org.wso2.financial.services.accelerator.common.config.FinancialServicesConfigParser;
import org.wso2.financial.services.accelerator.common.util.DatabaseUtils;
import org.wso2.financial.services.accelerator.event.notifications.service.constants.EventNotificationConstants;
import org.wso2.financial.services.accelerator.event.notifications.service.dao.EventNotificationDAO;
Expand All @@ -29,14 +30,15 @@
import org.wso2.financial.services.accelerator.event.notifications.service.model.Notification;
import org.wso2.financial.services.accelerator.event.notifications.service.model.NotificationEvent;
import org.wso2.financial.services.accelerator.event.notifications.service.persistence.EventNotificationStoreInitializer;
import org.wso2.financial.services.accelerator.event.notifications.service.realtime.service.EventNotificationProducerService;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.Map;
import java.util.UUID;

/**
* This is the event creation service class.
* Event creation service class.
*/
public class EventCreationService {

Expand Down Expand Up @@ -64,11 +66,9 @@ public String publishEventNotification(NotificationCreationDTO notificationCreat
eventResponse = eventCreationDAO.persistEventNotification(connection, notification, eventsList);
DatabaseUtils.commitTransaction(connection);

//TODO:
// Check whether the real time event notification is enabled.
// if (FinancialServicesConfigParser.getInstance().isRealtimeEventNotificationEnabled()) {
// new Thread(new EventNotificationProducerService(notification, eventsList)).start();
// }
if (FinancialServicesConfigParser.getInstance().isRealtimeEventNotificationEnabled()) {
new Thread(new EventNotificationProducerService(notification, eventsList)).start();
}
return eventResponse;
} catch (FSEventNotificationException e) {
DatabaseUtils.rollbackTransaction(connection);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
import java.util.Map;

/**
* This is the event polling service.
* Event polling service.
*/
public class EventPollingService {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import java.util.List;

/**
* This is the event subscription service class.
* Event subscription service class.
*/
public class EventSubscriptionService {
private static final Log log = LogFactory.getLog(EventSubscriptionService.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/**
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
* <p>
* WSO2 LLC. 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.wso2.financial.services.accelerator.event.notifications.service;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.wso2.financial.services.accelerator.common.util.DatabaseUtils;
import org.wso2.financial.services.accelerator.event.notifications.service.constants.EventNotificationConstants;
import org.wso2.financial.services.accelerator.event.notifications.service.dao.EventNotificationDAO;
import org.wso2.financial.services.accelerator.event.notifications.service.exception.FSEventNotificationException;
import org.wso2.financial.services.accelerator.event.notifications.service.model.Notification;
import org.wso2.financial.services.accelerator.event.notifications.service.model.NotificationEvent;
import org.wso2.financial.services.accelerator.event.notifications.service.persistence.EventNotificationStoreInitializer;

import java.sql.Connection;
import java.util.List;

/**
* Realtime Notification service class.
*/
public class RealtimeNotificationService {

private static final Log log = LogFactory.getLog(RealtimeNotificationService.class);

/**
* Method to retrieve notification by status.
*
* @param status Notification status to retrieve
* @return List of notifications by status
* @throws FSEventNotificationException Exception when retrieving notifications by status
*/
public List<Notification> getNotificationsByStatus(String status)
throws FSEventNotificationException {

EventNotificationDAO eventNotificationDAO = EventNotificationStoreInitializer.getEventNotificationDAO();

Connection connection = DatabaseUtils.getDBConnection();

try {
List<Notification> events = eventNotificationDAO.
getNotificationsByStatus(connection, status);
if (log.isDebugEnabled()) {
log.debug(String.format("Event Notifications with %s status retrieved successfully.",
status.replaceAll("[\r\n]", "")));
}
DatabaseUtils.commitTransaction(connection);
return events;
} catch (FSEventNotificationException e) {
log.error("Error while retrieving event notification.", e);
DatabaseUtils.rollbackTransaction(connection);
throw new FSEventNotificationException(EventNotificationConstants.ERROR_STORING_EVENT_SUBSCRIPTION, e);
} finally {
log.debug(EventNotificationConstants.DATABASE_CONNECTION_CLOSE_LOG_MSG);
DatabaseUtils.closeConnection(connection);
}
}

/**
* Method to retrieve notifications by NotificationID.
*
* @param notificationId Notification ID to retrieve
* @return List of notifications by notification ID
* @throws FSEventNotificationException Exception when retrieving notifications by notification ID
*/
public List<NotificationEvent> getEventsByNotificationID(String notificationId)
throws FSEventNotificationException {

EventNotificationDAO eventNotificationDAO = EventNotificationStoreInitializer.getEventNotificationDAO();

Connection connection = DatabaseUtils.getDBConnection();

try {
//store event subscription data in the database
List<NotificationEvent> notificationEvents = eventNotificationDAO.
getEventsByNotificationID(connection, notificationId);
if (log.isDebugEnabled()) {
log.debug(String.format("Event Notifications with notification id %s retrieved successfully.",
notificationId.replaceAll("[\r\n]", "")));
}
DatabaseUtils.commitTransaction(connection);
return notificationEvents;
} catch (FSEventNotificationException e) {
log.error("Error while retrieving event notification.", e);
DatabaseUtils.rollbackTransaction(connection);
throw new FSEventNotificationException(EventNotificationConstants.ERROR_STORING_EVENT_SUBSCRIPTION, e);
} finally {
log.debug(EventNotificationConstants.DATABASE_CONNECTION_CLOSE_LOG_MSG);
DatabaseUtils.closeConnection(connection);
}
}

/**
* Method to update the notification status by ID, allowed values are.
* OPEN,ACK and ERR
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if only these values are allowed shouldn't we accept an enum?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIxed in 00babc1

*
* @param notificationId Notification ID to update
* @param notificationStatus Notification status to update
* @throws FSEventNotificationException Exception when updating notification status by ID
*/
public void updateNotificationStatusById(String notificationId,
EventNotificationConstants.EventNotificationStatusEnum notificationStatus)
throws FSEventNotificationException {

Connection connection = DatabaseUtils.getDBConnection();

EventNotificationDAO eventNotificationDAO = EventNotificationStoreInitializer.getEventNotificationDAO();

try {
//update the stored event notification
eventNotificationDAO.updateNotificationStatusById(connection, notificationId,
notificationStatus.toString());

log.debug("Event Notification updated successfully.");
DatabaseUtils.commitTransaction(connection);
} catch (JSONException e) {
log.error("Error while Parsing the stored request Object", e);
throw new FSEventNotificationException("Error while Parsing the stored request Object", e);
} catch (FSEventNotificationException e) {
log.error("Error while updating event notification.", e);
DatabaseUtils.rollbackTransaction(connection);
throw new FSEventNotificationException(e.getMessage(), e);
} finally {
log.debug(EventNotificationConstants.DATABASE_CONNECTION_CLOSE_LOG_MSG);
DatabaseUtils.closeConnection(connection);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@

package org.wso2.financial.services.accelerator.event.notifications.service.constants;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
* Event Notification Constants.
*/
Expand All @@ -31,6 +35,40 @@ public class EventNotificationConstants {
public static final String ERROR = "ERR";
public static final String OPEN = "OPEN";

/**
* Specifies the Schema Names of Debtor Account.
*/
public enum EventNotificationStatusEnum {

ACK("ACK"),

ERROR("ERR"),

OPEN("OPEN");

private final String value;

EventNotificationStatusEnum(String value) {
this.value = value;
}

@Override
public String toString() {
return String.valueOf(value);
}

public static EventNotificationStatusEnum fromValue(String text) {

List<EventNotificationStatusEnum> valueList = Arrays.asList(EventNotificationStatusEnum.values());
Optional<EventNotificationStatusEnum> accountOpt = valueList
.stream()
.filter(i -> String.valueOf(i.value).equals(text))
.findAny();

return accountOpt.orElse(null);
}
}

//Response Status
public static final String NOT_FOUND = "NOTFOUND";
public static final String OK = "OK";
Expand Down
Loading
Loading