diff --git a/open-banking-accelerator/accelerators/ob-apim/carbon-home/repository/resources/conf/templates/repository/conf/open-banking.xml.j2 b/open-banking-accelerator/accelerators/ob-apim/carbon-home/repository/resources/conf/templates/repository/conf/open-banking.xml.j2 index 6e261320..ccbf09ab 100644 --- a/open-banking-accelerator/accelerators/ob-apim/carbon-home/repository/resources/conf/templates/repository/conf/open-banking.xml.j2 +++ b/open-banking-accelerator/accelerators/ob-apim/carbon-home/repository/resources/conf/templates/repository/conf/open-banking.xml.j2 @@ -66,13 +66,6 @@ {{open_banking.gateway.cache.cache_modified_expiry_minutes}} {% endif %} - - {% if open_banking.gateway.cache.idempotency_validation_cache.cache_time_to_live is defined %} - {{open_banking.gateway.cache.idempotency_validation_cache.cache_time_to_live}} - {% else %} - 1440 - {% endif %} - @@ -210,26 +203,6 @@ - - - {% if open_banking.gateway.idempotency.enabled is defined %} - {{open_banking.gateway.idempotency.enabled}} - {% else %} - false - {% endif %} - - {% if open_banking.gateway.idempotency.allowed_time_duration is defined %} - {{open_banking.gateway.idempotency.allowed_time_duration}} - {% else %} - 1440 - {% endif %} - - {% if open_banking.gateway.idempotency.idempotency_key_header is defined %} - {{open_banking.gateway.idempotency.idempotency_key_header}} - {% else %} - x-idempotency-key - {% endif %} - diff --git a/open-banking-accelerator/accelerators/ob-is/carbon-home/repository/resources/conf/templates/repository/conf/open-banking.xml.j2 b/open-banking-accelerator/accelerators/ob-is/carbon-home/repository/resources/conf/templates/repository/conf/open-banking.xml.j2 index 9b0a5cfa..ff27c6e3 100644 --- a/open-banking-accelerator/accelerators/ob-is/carbon-home/repository/resources/conf/templates/repository/conf/open-banking.xml.j2 +++ b/open-banking-accelerator/accelerators/ob-is/carbon-home/repository/resources/conf/templates/repository/conf/open-banking.xml.j2 @@ -390,6 +390,19 @@ {% endif %} + + {% if open_banking.gateway.idempotency.enabled is defined %} + {{open_banking.gateway.idempotency.enabled}} + {% else %} + false + {% endif %} + + {% if open_banking.gateway.idempotency.allowed_time_duration is defined %} + {{open_banking.gateway.idempotency.allowed_time_duration}} + {% else %} + 1440 + {% endif %} + {% if open_banking.dcr.validator is defined %} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/pom.xml b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/pom.xml index 1b417e52..1e7e1927 100644 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/pom.xml +++ b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/pom.xml @@ -33,10 +33,6 @@ bundle WSO2 Open Banking - Common component - - com.hazelcast - hazelcast - org.apache.ws.commons.axiom.wso2 axiom @@ -275,10 +271,7 @@ org.osgi.framework;version="${osgi.framework.imp.pkg.version.range}", - org.osgi.service.component;version="${osgi.service.component.imp.pkg.version.range}", - com.hazelcast.config; version="${com.hazelcast.hazelcast.version}", - com.hazelcast.core; version="${com.hazelcast.hazelcast.version}", - com.hazelcast.map; version="${com.hazelcast.hazelcast.version}" + org.osgi.service.component;version="${osgi.service.component.imp.pkg.version.range}" !com.wso2.openbanking.accelerator.common.internal, diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/distributed/caching/OpenBankingDistributedCache.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/distributed/caching/OpenBankingDistributedCache.java deleted file mode 100644 index 145d9cd4..00000000 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/distributed/caching/OpenBankingDistributedCache.java +++ /dev/null @@ -1,153 +0,0 @@ -/** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). - * - * 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 - * - * 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 com.wso2.openbanking.accelerator.common.distributed.caching; - -import com.hazelcast.map.IMap; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.concurrent.TimeUnit; - -/** - * Abstract cache manager for Open Banking Distributed cache. - * - * @param Key of the cache. - * @param Value of the cache. - */ -public abstract class OpenBankingDistributedCache { - private final String cacheName; - - private static final Log log = LogFactory.getLog(OpenBankingDistributedCache.class); - - /** - * Initialize With unique cache name. - * - * @param cacheName Name of the cache. - */ - public OpenBankingDistributedCache(String cacheName) { - - this.cacheName = cacheName; - if (log.isDebugEnabled()) { - log.debug(String.format("Distributed Cache initialized for %s.", cacheName.replaceAll("[\r\n]", ""))); - } - } - - /** - * Get from cache. - * - * @param key cache key. - * @return cache. - */ - public V getFromCache(K key) { - - if (isEnabled()) { - - IMap cache = getBaseCache(); - - if (cache.containsKey(key)) { - if (log.isDebugEnabled()) { - log.debug(String.format("Found cache entry `%s` in cache %s.", - key.toString().replaceAll("[\r\n]", ""), cacheName.replaceAll("[\r\n]", ""))); - } - return cache.get(key); - } else { - if (log.isDebugEnabled()) { - log.debug(String.format("Cache entry `%s` is not Found in cache %s.", - key.toString().replaceAll("[\r\n]", ""), cacheName.replaceAll("[\r\n]", ""))); - } - return null; - } - } else { - log.debug("Distributed cache is Disabled."); - return null; - } - } - - /** - * Add Object to cache. - * - * @param key cache key. - * @param value object to be cached. - */ - public void addToCache(K key, V value) { - if (isEnabled()) { - IMap cache = getBaseCache(); - if (log.isDebugEnabled()) { - log.debug(String.format("`%s` added into cache %s.", key.toString().replaceAll("[\r\n]", ""), - cacheName.replaceAll("[\r\n]", ""))); - } - cache.put(key, value, getCacheTimeToLiveMinutes(), TimeUnit.MINUTES); - } else { - log.debug("Distributed cache is Disabled."); - } - } - - /** - * Remove from cache. - * - * @param key cache key. - */ - public void removeFromCache(K key) { - if (isEnabled()) { - if (log.isDebugEnabled()) { - log.debug(String.format("`%s` removed from cache %s.", key.toString().replaceAll("[\r\n]", ""), - cacheName.replaceAll("[\r\n]", ""))); - } - IMap cache = getBaseCache(); - cache.remove(key); - } else { - log.debug("Distributed cache is Disabled."); - } - } - - /** - * Method to check if the cache is empty. - * - * @return true if empty, false if populated. - */ - public boolean isEmpty() { - return getBaseCache().isEmpty(); - } - - /** - * Get the clustered cache. - * - * @return cache map. - */ - private IMap getBaseCache() { - return OpenBankingDistributedMember.of().getHazelcastInstance().getMap(this.cacheName); - } - - /** - * Method to get if the Distributed caching is enabled. - * - * @return True if enabled, false if disabled. - */ - private boolean isEnabled() { - return OpenBankingDistributedMember.of().isEnabled(); - } - - /** - * Get Cache expiry time upon modification in minutes. - * - * @return integer denoting number of minutes. - */ - public abstract int getCacheTimeToLiveMinutes(); - -} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/distributed/caching/OpenBankingDistributedCacheConstants.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/distributed/caching/OpenBankingDistributedCacheConstants.java deleted file mode 100644 index 58d5bf75..00000000 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/distributed/caching/OpenBankingDistributedCacheConstants.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). - * - * 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 - * - * 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 com.wso2.openbanking.accelerator.common.distributed.caching; - -/** - * Open banking distributed cache constants. - */ -public class OpenBankingDistributedCacheConstants { - - // Distributed cache cluster name. - public static final String CLUSTER_NAME = "OB_DISTRIBUTED_CACHE"; - - // Common constants for both TCP and Multicast. - public static final String ENABLED = "DistributedCache.Enabled"; - public static final String HOST_NAME = "DistributedCache.HostName"; - public static final String PORT = "DistributedCache.Port"; - public static final String DISCOVERY_MECHANISM = "DistributedCache.DiscoveryMechanism"; - - // Constants used for Multicast. - public static final String MULTICAST = "Multicast"; - public static final String MULTICAST_GROUP = "DistributedCache.MulticastGroup"; - public static final String MULTICAST_PORT = "DistributedCache.MulticastPort"; - public static final String TRUSTED_INTERFACES = "DistributedCache.TrustedInterfaces.TrustedInterface"; - - // Constants used for TCP. - public static final String TCP = "TCP"; - public static final String MEMBERS = "DistributedCache.Members.Member"; - - // Constants for hazelcast properties. - public static final String PROPERTY_MAX_HEARTBEAT = "DistributedCache.Properties.MaxHeartbeat"; - public static final String PROPERTY_MAX_MASTER_CONFIRMATION = "DistributedCache.Properties.MasterConfirmation"; - public static final String PROPERTY_MERGE_FIRST_RUN_DELAY = "DistributedCache.Properties.MergeFirstRunDelay"; - public static final String PROPERTY_MERGE_NEXT_RUN_DELAY = "DistributedCache.Properties.MergeNextRunDelay"; - public static final String PROPERTY_LOGGING_TYPE = "DistributedCache.Properties.LoggingType"; - - // Hazelcast Constants for hazelcast properties. - public static final String HAZELCAST_PROPERTY_MAX_HEARTBEAT = "hazelcast.max.no.heartbeat.seconds"; - public static final String HAZELCAST_PROPERTY_MAX_MASTER_CONFIRMATION = "hazelcast.max.no.master." + - "confirmation.seconds"; - public static final String HAZELCAST_PROPERTY_MERGE_FIRST_RUN_DELAY = "hazelcast.merge.first.run.delay.seconds"; - public static final String HAZELCAST_PROPERTY_MERGE_NEXT_RUN_DELAY = "hazelcast.merge.next.run.delay.seconds"; - public static final String HAZELCAST_PROPERTY_LOGGING_TYPE = "hazelcast.logging.type"; -} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/distributed/caching/OpenBankingDistributedCacheKey.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/distributed/caching/OpenBankingDistributedCacheKey.java deleted file mode 100644 index b1818a73..00000000 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/distributed/caching/OpenBankingDistributedCacheKey.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). - * - * 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 - * - * 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 com.wso2.openbanking.accelerator.common.distributed.caching; - -import java.io.Serializable; -import java.util.Objects; - -/** - * Abstract class for Open Banking Distributed Cache Key. - */ -public class OpenBankingDistributedCacheKey implements Serializable { - - private static final long serialVersionUID = -2106706990466051087L; - private String cacheKey; - - - /** - * public constructor for OpenBankingDistributedCacheKey. - * - * @param cacheKey String cache key. - */ - public OpenBankingDistributedCacheKey(String cacheKey) { - setCacheKey(cacheKey); - } - - /** - * Get Instance OpenBankingDistributedCacheKey. - * - * @param cacheKey String cache key. - * @return new OpenBankingDistributedCacheKey instance. - */ - public static OpenBankingDistributedCacheKey of(String cacheKey) { - return new OpenBankingDistributedCacheKey(cacheKey); - } - - /** - * Getter for cacheKey. - * - * @return String cacheKey. - */ - public String getCacheKey() { - return this.cacheKey; - } - - /** - * Setter for cacheKey. - * - * @param cacheKey String cacheKey. - */ - public void setCacheKey(String cacheKey) { - this.cacheKey = cacheKey; - } - - /** - * Equals Method for OpenBankingDistributedCacheKey objects. - * - * @param o Object. - * @return True if equal, false if not-equal. - */ - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - OpenBankingDistributedCacheKey that = (OpenBankingDistributedCacheKey) o; - return Objects.equals(getCacheKey(), that.getCacheKey()); - } - - /** - * hashcode for OpenBankingDistributedCacheKey. - * - * @return hashcode. - */ - @Override - public int hashCode() { - return Objects.hash(getCacheKey()); - } -} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/distributed/caching/OpenBankingDistributedMember.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/distributed/caching/OpenBankingDistributedMember.java deleted file mode 100644 index 4c4147cf..00000000 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/distributed/caching/OpenBankingDistributedMember.java +++ /dev/null @@ -1,330 +0,0 @@ -/** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). - * - * 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 - * - * 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 com.wso2.openbanking.accelerator.common.distributed.caching; - -import com.hazelcast.config.Config; -import com.hazelcast.config.JoinConfig; -import com.hazelcast.config.MulticastConfig; -import com.hazelcast.config.NetworkConfig; -import com.hazelcast.config.TcpIpConfig; -import com.hazelcast.core.Hazelcast; -import com.hazelcast.core.HazelcastInstance; -import com.wso2.openbanking.accelerator.common.config.OpenBankingConfigParser; -import com.wso2.openbanking.accelerator.common.util.SecurityUtils; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.ArrayList; -import java.util.Map; -import java.util.Properties; - -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.CLUSTER_NAME; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.DISCOVERY_MECHANISM; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.ENABLED; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.HAZELCAST_PROPERTY_LOGGING_TYPE; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.HAZELCAST_PROPERTY_MAX_HEARTBEAT; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.HAZELCAST_PROPERTY_MAX_MASTER_CONFIRMATION; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.HAZELCAST_PROPERTY_MERGE_FIRST_RUN_DELAY; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.HAZELCAST_PROPERTY_MERGE_NEXT_RUN_DELAY; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.HOST_NAME; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.MEMBERS; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.MULTICAST; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.MULTICAST_GROUP; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.MULTICAST_PORT; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.PORT; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.PROPERTY_LOGGING_TYPE; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.PROPERTY_MAX_HEARTBEAT; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.PROPERTY_MAX_MASTER_CONFIRMATION; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.PROPERTY_MERGE_FIRST_RUN_DELAY; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.PROPERTY_MERGE_NEXT_RUN_DELAY; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.TCP; -import static com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants.TRUSTED_INTERFACES; - -/** - * Singleton class to create a hazelcast cluster member. - */ -public class OpenBankingDistributedMember { - private boolean enabled; - private static volatile OpenBankingDistributedMember openBankingDistributedMember; - private final HazelcastInstance hazelcastInstance; - private static final Map configurations = OpenBankingConfigParser.getInstance().getConfiguration(); - - private static final Log log = LogFactory.getLog(OpenBankingDistributedMember.class); - - /** - * Private constructor. - */ - private OpenBankingDistributedMember() { - setEnabled(); - - Config hazelcastConfig = new Config(); - hazelcastConfig.setClusterName(CLUSTER_NAME); - - setProperties(hazelcastConfig); - - NetworkConfig network = hazelcastConfig.getNetworkConfig(); - - setNetworkConfigurations(network); - - this.hazelcastInstance = Hazelcast.newHazelcastInstance(hazelcastConfig); - } - - /** - * Method to get the singleton object. - * - * @return distributedMember. - */ - public static OpenBankingDistributedMember of() { - if (openBankingDistributedMember == null) { - synchronized (OpenBankingDistributedMember.class) { - if (openBankingDistributedMember == null) { - openBankingDistributedMember = new OpenBankingDistributedMember(); - } - } - } - return openBankingDistributedMember; - } - - /** - * Method to destroy the singleton instance. - */ - public static synchronized void shutdown() { - openBankingDistributedMember.getHazelcastInstance().shutdown(); - openBankingDistributedMember = null; - log.debug("Shutdown distributed cache member."); - } - - /** - * Getter for enabled. - * - * @return Boolean enabled. - */ - public boolean isEnabled() { - return this.enabled; - } - - /** - * Setter for enabled, using the config file. - */ - public void setEnabled() { - Object isEnableConfiguration = configurations.get(ENABLED); - if (isEnableConfiguration != null) { - String isEnableConfigurationString = isEnableConfiguration.toString(); - setEnabled(isEnableConfigurationString.equals("true")); - } - } - - /** - * Setter of enabled. - * - * @param enabled Boolean enabled. - */ - public void setEnabled(boolean enabled) { - if (enabled) { - log.debug("Distributed Caching enabled"); - } else { - log.debug("Distributed Caching disabled"); - } - this.enabled = enabled; - } - - /** - * Getter for hazelcast instance. - * - * @return this.hazelcastInstance. - */ - public HazelcastInstance getHazelcastInstance() { - return this.hazelcastInstance; - } - - /** - * Method to set hazelcast properties. - * - * @param hazelcastConfig hazelcastConfig. - */ - @SuppressFBWarnings("CRLF_INJECTION_LOGS") - // Suppressed content - hazelcastConfig.getProperties() - // Suppression reason - Warning are appearing on Properties, not strings. Also the properties will be set in config - // by the admin - // Suppressed warning count - 1 - private synchronized void setProperties(Config hazelcastConfig) { - - Properties hazelcastProperties = new Properties(); - - setProperty(hazelcastProperties, PROPERTY_MAX_HEARTBEAT, HAZELCAST_PROPERTY_MAX_HEARTBEAT); - setProperty(hazelcastProperties, PROPERTY_MAX_MASTER_CONFIRMATION, HAZELCAST_PROPERTY_MAX_MASTER_CONFIRMATION); - setProperty(hazelcastProperties, PROPERTY_MERGE_FIRST_RUN_DELAY, HAZELCAST_PROPERTY_MERGE_FIRST_RUN_DELAY); - setProperty(hazelcastProperties, PROPERTY_MERGE_NEXT_RUN_DELAY, HAZELCAST_PROPERTY_MERGE_NEXT_RUN_DELAY); - setProperty(hazelcastProperties, PROPERTY_LOGGING_TYPE, HAZELCAST_PROPERTY_LOGGING_TYPE); - - hazelcastConfig.setProperties(hazelcastProperties); - - if (log.isDebugEnabled()) { - log.debug("Hazelcast Properties : " + hazelcastConfig.getProperties()); - } - } - - /** - * Method to set hazelcast property. - * - * @param property Property. - * @param configurationName Name of the configuration in config file. - * @param hazelcastProperty hazelcast configuration. - */ - private void setProperty(Properties property, String configurationName, String hazelcastProperty) { - Object configuration = configurations.get(configurationName); - if (configuration != null) { - String configurationString = configuration.toString(); - property.setProperty(hazelcastProperty, configurationString); - } - } - - /** - * Method to set hazelcast network configurations. - * - * @param network network. - */ - private synchronized void setNetworkConfigurations(NetworkConfig network) { - - // Configuring host name of the hazelcast instance. - Object hostName = configurations.get(HOST_NAME); - if (hostName != null) { - String hostNameString = hostName.toString(); - network.setPublicAddress(hostNameString); - } - - // Configuring port of the hazelcast instance. - Object port = configurations.get(PORT); - if (port != null) { - String portString = port.toString(); - int portInt = Integer.parseInt(portString); - network.setPort(portInt); - } - - if (log.isDebugEnabled()) { - log.debug("Network is set to " + network.getPublicAddress().replaceAll("[\r\n]", "") + ":" + - network.getPort()); - } - - // Configuring the discovery mechanism of the hazelcast instance. - JoinConfig join = network.getJoin(); - Object discoveryMechanism = configurations.get(DISCOVERY_MECHANISM); - if (discoveryMechanism != null) { // When discovery method is configured. - - String discoveryMechanismString = discoveryMechanism.toString(); - - if (discoveryMechanismString.equals(TCP)) { - // Discovery method TCP. - setConfigurationsTCP(join); - } else if (discoveryMechanismString.equals(MULTICAST)) { - // Discovery method Multicast. - setConfigurationsMulticast(join); - } - } else { // Defaulting Multicast when discovery method is not configured. - setConfigurationsMulticast(join); - } - } - - /** - * Method to set discovery mechanism TCP. - * - * @param join JoinConfig join. - */ - @SuppressFBWarnings("CRLF_INJECTION_LOGS") - // Suppressed content - tcpipConfig.getMembers() - // Suppression reason - False positive: New lines are already removed - // Suppressed warning count - 1 - private void setConfigurationsTCP(JoinConfig join) { - log.debug("Discovery mechanism : TCP"); - join.getMulticastConfig().setEnabled(false); - TcpIpConfig tcpipConfig = join.getTcpIpConfig(); - tcpipConfig.setEnabled(true); - - // Configuring TCP members. - Object members = configurations.get(MEMBERS); - if (members != null) { - ArrayList membersList = new ArrayList<>(); - if (members instanceof ArrayList) { - membersList.addAll((ArrayList) members); - } else if (members instanceof String) { - membersList.add((String) members); - } - for (String member : membersList) { - tcpipConfig.addMember(member.trim()); - } - } - if (log.isDebugEnabled()) { - log.debug("Members: " + SecurityUtils.sanitize(tcpipConfig.getMembers())); - } - } - - /** - * Method to set discovery mechanism Multicast. - * - * @param join JoinConfig join. - */ - @SuppressFBWarnings("CRLF_INJECTION_LOGS") - // Suppressed content - multicastConfig.getTrustedInterfaces() - // Suppression reason - False positive: New lines are already removed - // Suppressed warning count - 1 - private void setConfigurationsMulticast(JoinConfig join) { - log.debug("Discovery mechanism : Multicast"); - join.getTcpIpConfig().setEnabled(false); - MulticastConfig multicastConfig = join.getMulticastConfig(); - multicastConfig.setEnabled(true); - - // Configuring multicast group. - Object multicastGroup = configurations.get(MULTICAST_GROUP); - if (multicastGroup != null) { - String multicastGroupString = multicastGroup.toString(); - multicastConfig.setMulticastGroup(multicastGroupString); - } - - // Configuring multicast port. - Object multicastPort = configurations.get(MULTICAST_PORT); - if (multicastPort != null) { - String multicastPortString = multicastPort.toString(); - int multicastPortInt = Integer.parseInt(multicastPortString); - multicastConfig.setMulticastPort(multicastPortInt); - } - - if (log.isDebugEnabled()) { - log.debug("Discovery mechanism is set to Multicast.\n\tMulticast Group: " + - multicastConfig.getMulticastGroup().replaceAll("[\r\n]", "") + - "\n\tMulticast Port: " + multicastConfig.getMulticastPort()); - } - // Configuring trusted interfaces. - Object trustedInterfaces = configurations.get(TRUSTED_INTERFACES); - if (trustedInterfaces != null) { - ArrayList trustedInterfacesList = new ArrayList<>(); - if (trustedInterfaces instanceof ArrayList) { - trustedInterfacesList.addAll((ArrayList) trustedInterfaces); - } else if (trustedInterfaces instanceof String) { - trustedInterfacesList.add((String) trustedInterfaces); - } - for (String trustedInterface : trustedInterfacesList) { - multicastConfig.addTrustedInterface(trustedInterface.trim()); - } - } - if (log.isDebugEnabled()) { - log.debug("\n\tTrusted Interfaces: " + SecurityUtils.sanitize(multicastConfig.getTrustedInterfaces())); - } - } -} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/util/HTTPClientUtils.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/util/HTTPClientUtils.java index 37996812..5e84500f 100644 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/util/HTTPClientUtils.java +++ b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/main/java/com/wso2/openbanking/accelerator/common/util/HTTPClientUtils.java @@ -66,6 +66,7 @@ public class HTTPClientUtils { * @return Closeable https client * @throws OpenBankingException OpenBankingException exception */ + @Generated(message = "Ignoring because ServerConfiguration cannot be mocked") public static CloseableHttpClient getHttpsClient() throws OpenBankingException { SSLConnectionSocketFactory sslsf = createSSLConnectionSocketFactory(); diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/java/com/wso2/openbanking/accelerator/common/test/distributed/caching/OpenBankingDistributedCacheMulticastTest.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/java/com/wso2/openbanking/accelerator/common/test/distributed/caching/OpenBankingDistributedCacheMulticastTest.java deleted file mode 100644 index 76cfa338..00000000 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/java/com/wso2/openbanking/accelerator/common/test/distributed/caching/OpenBankingDistributedCacheMulticastTest.java +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). - * - * 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 - * - * 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 com.wso2.openbanking.accelerator.common.test.distributed.caching; - -import com.wso2.openbanking.accelerator.common.config.OpenBankingConfigParser; -import com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants; -import com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedMember; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.testng.PowerMockTestCase; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -/** - * Unit test for open banking distributed cache with Multicast discovery method. - */ -@PowerMockIgnore({"jdk.internal.reflect.*", "javax.management.*"}) -@PrepareForTest({OpenBankingConfigParser.class}) -public class OpenBankingDistributedCacheMulticastTest extends PowerMockTestCase { - - - private static TestOpenBankingDistributedCache cacheMulticast; - - @Mock - OpenBankingConfigParser openBankingConfigParser; - - - @BeforeClass - public void beforeTests() { - MockitoAnnotations.initMocks(this); - - Map configsMulticast = new HashMap<>(); - configsMulticast.put(OpenBankingDistributedCacheConstants.ENABLED, "true"); - configsMulticast.put(OpenBankingDistributedCacheConstants.HOST_NAME, "localhost"); - configsMulticast.put(OpenBankingDistributedCacheConstants.PORT, "5721"); - configsMulticast.put(OpenBankingDistributedCacheConstants.DISCOVERY_MECHANISM, "Multicast"); - configsMulticast.put(OpenBankingDistributedCacheConstants.MULTICAST_GROUP, "224.2.2.3"); - configsMulticast.put(OpenBankingDistributedCacheConstants.MULTICAST_PORT, "54321"); - ArrayList interfaces = new ArrayList<>(); - interfaces.add("192.168.1.100-110"); - configsMulticast.put(OpenBankingDistributedCacheConstants.TRUSTED_INTERFACES, interfaces); - configsMulticast.put(OpenBankingDistributedCacheConstants.PROPERTY_LOGGING_TYPE, "none"); - - Mockito.when(openBankingConfigParser.getConfiguration()).thenReturn(configsMulticast); - - PowerMockito.mockStatic(OpenBankingConfigParser.class); - PowerMockito.when(OpenBankingConfigParser.getInstance()) - .thenReturn(openBankingConfigParser); - - cacheMulticast = new TestOpenBankingDistributedCache("test-cache-multicast"); - - } - - @Test(priority = 1) - public void addGetTestMulticast() { - TestOpenBankingDistributedCacheKey key = new TestOpenBankingDistributedCacheKey("test-cache-key"); - cacheMulticast.addToCache(key, "cache-body"); - String fromCache = null; - if (!cacheMulticast.isEmpty()) { - fromCache = cacheMulticast.getFromCache(key); - } - - Assert.assertEquals(fromCache, "cache-body"); - } - - @Test(priority = 2) - public void removeTestMulticast() { - TestOpenBankingDistributedCacheKey key = new TestOpenBankingDistributedCacheKey("test-cache-key"); - cacheMulticast.removeFromCache(key); - - String fromCache = cacheMulticast.getFromCache(key); - - Assert.assertNull(fromCache); - } - - @Test(priority = 3) - public void cacheEvictionTestMulticast() throws InterruptedException { - TestOpenBankingDistributedCacheKey key = new TestOpenBankingDistributedCacheKey("test-cache-key"); - cacheMulticast.addToCache(key, "cache-body"); - TimeUnit.MINUTES.sleep(2); - - String fromCache = cacheMulticast.getFromCache(key); - Assert.assertNull(fromCache); - } - - @AfterClass - public void after() { - OpenBankingDistributedMember.of().shutdown(); - } -} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/java/com/wso2/openbanking/accelerator/common/test/distributed/caching/OpenBankingDistributedCacheTCPTest.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/java/com/wso2/openbanking/accelerator/common/test/distributed/caching/OpenBankingDistributedCacheTCPTest.java deleted file mode 100644 index 0b65dae1..00000000 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/java/com/wso2/openbanking/accelerator/common/test/distributed/caching/OpenBankingDistributedCacheTCPTest.java +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). - * - * 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 - * - * 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 com.wso2.openbanking.accelerator.common.test.distributed.caching; - -import com.wso2.openbanking.accelerator.common.config.OpenBankingConfigParser; -import com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants; -import com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedMember; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.testng.PowerMockTestCase; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; - - -/** - * Unit test for open banking distributed cache with TCP discovery method. - */ -@PowerMockIgnore({"jdk.internal.reflect.*", "javax.management.*"}) -@PrepareForTest({OpenBankingConfigParser.class}) -public class OpenBankingDistributedCacheTCPTest extends PowerMockTestCase { - - - private static TestOpenBankingDistributedCache cacheTCP; - - @Mock - OpenBankingConfigParser openBankingConfigParser; - - - @BeforeClass - public void beforeTests() { - MockitoAnnotations.initMocks(this); - - Map configsTCP = new HashMap<>(); - configsTCP.put(OpenBankingDistributedCacheConstants.ENABLED, "true"); - configsTCP.put(OpenBankingDistributedCacheConstants.HOST_NAME, "localhost"); - configsTCP.put(OpenBankingDistributedCacheConstants.PORT, "5721"); - configsTCP.put(OpenBankingDistributedCacheConstants.DISCOVERY_MECHANISM, "TCP"); - ArrayList members = new ArrayList<>(); - members.add("localhost:5722"); - configsTCP.put(OpenBankingDistributedCacheConstants.MEMBERS, members); - configsTCP.put(OpenBankingDistributedCacheConstants.PROPERTY_LOGGING_TYPE, "none"); - - Mockito.when(openBankingConfigParser.getConfiguration()).thenReturn(configsTCP); - - PowerMockito.mockStatic(OpenBankingConfigParser.class); - PowerMockito.when(OpenBankingConfigParser.getInstance()) - .thenReturn(openBankingConfigParser); - - cacheTCP = new TestOpenBankingDistributedCache("test-cache-tcp"); - - } - - @Test(priority = 1) - public void addGetTestTCP() { - TestOpenBankingDistributedCacheKey key = new TestOpenBankingDistributedCacheKey("test-cache-key"); - cacheTCP.addToCache(key, "cache-body"); - String fromCache = null; - if (!cacheTCP.isEmpty()) { - fromCache = cacheTCP.getFromCache(key); - } - - Assert.assertEquals(fromCache, "cache-body"); - } - - @Test(priority = 2) - public void removeTestTCP() { - TestOpenBankingDistributedCacheKey key = new TestOpenBankingDistributedCacheKey("test-cache-key"); - cacheTCP.removeFromCache(key); - - String fromCache = cacheTCP.getFromCache(key); - - Assert.assertNull(fromCache); - } - - @Test(priority = 3) - public void cacheEvictionTestTCP() throws InterruptedException { - TestOpenBankingDistributedCacheKey key = new TestOpenBankingDistributedCacheKey("test-cache-key"); - cacheTCP.addToCache(key, "cache-body"); - TimeUnit.MINUTES.sleep(2); - - String fromCache = cacheTCP.getFromCache(key); - Assert.assertNull(fromCache); - } - - - @AfterClass - public void after() { - OpenBankingDistributedMember.of().shutdown(); - } -} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/java/com/wso2/openbanking/accelerator/common/test/distributed/caching/TestOpenBankingDistributedCache.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/java/com/wso2/openbanking/accelerator/common/test/distributed/caching/TestOpenBankingDistributedCache.java deleted file mode 100644 index 01c5a027..00000000 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/java/com/wso2/openbanking/accelerator/common/test/distributed/caching/TestOpenBankingDistributedCache.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). - * - * 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 - * - * 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 com.wso2.openbanking.accelerator.common.test.distributed.caching; - -import com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCache; - -/** - * TestOpenBankingDistributedCache. - */ -public class TestOpenBankingDistributedCache - extends OpenBankingDistributedCache { - - int cacheTimeToLiveMinutes; - - /** - * Initialize With unique cache name. - * - * @param cacheName Name of the cache. - */ - public TestOpenBankingDistributedCache(String cacheName) { - super(cacheName); - setCacheTimeToLiveMinutes(); - } - - @Override - public int getCacheTimeToLiveMinutes() { - return this.cacheTimeToLiveMinutes; - } - - public void setCacheTimeToLiveMinutes() { - this.cacheTimeToLiveMinutes = 2; - } -} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/java/com/wso2/openbanking/accelerator/common/test/distributed/caching/TestOpenBankingDistributedCacheKey.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/java/com/wso2/openbanking/accelerator/common/test/distributed/caching/TestOpenBankingDistributedCacheKey.java deleted file mode 100644 index 639eaf35..00000000 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/java/com/wso2/openbanking/accelerator/common/test/distributed/caching/TestOpenBankingDistributedCacheKey.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). - * - * 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 - * - * 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 com.wso2.openbanking.accelerator.common.test.distributed.caching; - -import com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheKey; - -/** - * TestOpenBankingDistributedCacheKey. - */ -public class TestOpenBankingDistributedCacheKey extends OpenBankingDistributedCacheKey { - - public TestOpenBankingDistributedCacheKey(String cacheKey) { - super(cacheKey); - } - - public static OpenBankingDistributedCacheKey of(String cacheKey) { - return new TestOpenBankingDistributedCacheKey(cacheKey); - } -} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/java/com/wso2/openbanking/accelerator/common/test/util/SecurityUtilsTest.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/java/com/wso2/openbanking/accelerator/common/test/util/SecurityUtilsTest.java new file mode 100644 index 00000000..d15625b0 --- /dev/null +++ b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/java/com/wso2/openbanking/accelerator/common/test/util/SecurityUtilsTest.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 com.wso2.openbanking.accelerator.common.test.util; + +import com.wso2.openbanking.accelerator.common.util.SecurityUtils; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.List; +import java.util.Set; + +/** + * Tests Common Security Utils. + */ +public class SecurityUtilsTest { + + @Test + public void testSanitizeString() { + String sanitizedString = SecurityUtils.sanitizeString("tests\nsanitizing"); + Assert.assertFalse(sanitizedString.contains("\n")); + } + + @Test + public void testSanitizeStringList() { + List sanitizedList = SecurityUtils.sanitize(List.of( + "tests\nsanitizing", + "tests\nsanitizing", + "tests\nsanitizing" + ) + ); + Assert.assertFalse(sanitizedList.stream().anyMatch(s -> s.contains("\n"))); + } + + @Test + public void testSanitizeStringSet() { + Set sanitizedList = SecurityUtils.sanitize(Set.of( + "tests\nsanitizing", + "tests\nsanitizingtext", + "tests\nsanitizingwords" + ) + ); + Assert.assertFalse(sanitizedList.stream().anyMatch(s -> s.contains("\n"))); + } + + @Test + public void testContainSpecialChars() { + Assert.assertTrue(SecurityUtils.containSpecialChars("tests&sanitizing")); + } +} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/resources/testng.xml b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/resources/testng.xml index b791b6f8..2eaab446 100644 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/resources/testng.xml +++ b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.common/src/test/resources/testng.xml @@ -50,19 +50,14 @@ - - - - - - + - + - + - + diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/pom.xml b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/pom.xml index c4a8b9bb..b4eaa95b 100644 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/pom.xml +++ b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/pom.xml @@ -147,11 +147,6 @@ - - com.hazelcast - hazelcast - test - org.wso2.orbit.com.nimbusds nimbus-jose-jwt diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/main/java/com/wso2/openbanking/accelerator/gateway/cache/OpenBankingIdempotencyCacheKey.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/main/java/com/wso2/openbanking/accelerator/gateway/cache/OpenBankingIdempotencyCacheKey.java deleted file mode 100644 index 6d9dd690..00000000 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/main/java/com/wso2/openbanking/accelerator/gateway/cache/OpenBankingIdempotencyCacheKey.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). - * - * 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 - * - * 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 com.wso2.openbanking.accelerator.gateway.cache; - -import com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheKey; - -/** - * Cache Key for Open Banking Idempotency cache. - */ -public class OpenBankingIdempotencyCacheKey extends OpenBankingDistributedCacheKey { - - private static final long serialVersionUID = -6635236272993690731L; - - /** - * public constructor for OpenBankingDistributedCacheKey. - * - * @param cacheKey String cache key. - */ - public OpenBankingIdempotencyCacheKey(String cacheKey) { - super(cacheKey); - } - - /** - * Static method to create a cache key. - * - * @param cacheKey cache key in string. - * @return OpenBankingIdempotencyCacheKey. - */ - public static OpenBankingIdempotencyCacheKey of(String cacheKey) { - return new OpenBankingIdempotencyCacheKey(cacheKey); - } -} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/main/java/com/wso2/openbanking/accelerator/gateway/cache/OpenBankingIdempotencyValidationCache.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/main/java/com/wso2/openbanking/accelerator/gateway/cache/OpenBankingIdempotencyValidationCache.java deleted file mode 100644 index 1a683c22..00000000 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/main/java/com/wso2/openbanking/accelerator/gateway/cache/OpenBankingIdempotencyValidationCache.java +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). - * - * 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 - * - * 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 com.wso2.openbanking.accelerator.gateway.cache; - -import com.wso2.openbanking.accelerator.common.config.OpenBankingConfigParser; -import com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCache; -import com.wso2.openbanking.accelerator.gateway.util.IdempotencyConstants; - -import java.util.HashMap; - -/** - * Cache definition to store Request against the idempotency key. - */ -public class OpenBankingIdempotencyValidationCache - extends OpenBankingDistributedCache> { - - private final int cacheTimeToLiveMinutes; - private static final String cacheName = "Idempotency-Validation-Cache"; - private static volatile OpenBankingIdempotencyValidationCache idempotencyValidationCache; - - /** - * Initialize With unique cache name. - * - * @param cacheName Name of the cache. - */ - private OpenBankingIdempotencyValidationCache(String cacheName) { - super(cacheName); - this.cacheTimeToLiveMinutes = setCacheTimeToLiveMinutes(); - } - - /** - * Creating a singleton OpenBankingIdempotencyValidationCache object. - * - * @return OpenBankingIdempotencyValidationCache object. - */ - public static OpenBankingIdempotencyValidationCache getInstance() { - if (idempotencyValidationCache == null) { - synchronized (OpenBankingIdempotencyValidationCache.class) { - if (idempotencyValidationCache == null) { - idempotencyValidationCache = new OpenBankingIdempotencyValidationCache( - OpenBankingIdempotencyValidationCache.cacheName); - } - } - } - return idempotencyValidationCache; - } - - /** - * Getter for cache time to live in minutes. - * - * @return cache time to live for Open Banking Idempotency Validation Cache. - */ - @Override - public int getCacheTimeToLiveMinutes() { - return this.cacheTimeToLiveMinutes; - } - - /** - * Method to read cache time to live from configurations. - * - * @return Open Banking Idempotency Validation Cache time to live in minutes as set configurations, - * if configuration is not set return 3600 as default. - */ - public int setCacheTimeToLiveMinutes() { - String cacheTimeToLive = (String) OpenBankingConfigParser.getInstance().getConfiguration() - .get(IdempotencyConstants.IDEMPOTENCY_CACHE_TIME_TO_LIVE); - - return cacheTimeToLive == null ? 3600 : Integer.parseInt(cacheTimeToLive); - } -} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/main/java/com/wso2/openbanking/accelerator/gateway/executor/idempotency/OpenBankingIdempotencyHandlingExecutor.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/main/java/com/wso2/openbanking/accelerator/gateway/executor/idempotency/OpenBankingIdempotencyHandlingExecutor.java deleted file mode 100644 index 3bd11c33..00000000 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/main/java/com/wso2/openbanking/accelerator/gateway/executor/idempotency/OpenBankingIdempotencyHandlingExecutor.java +++ /dev/null @@ -1,376 +0,0 @@ -/** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). - * - * 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 - * - * 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 com.wso2.openbanking.accelerator.gateway.executor.idempotency; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.wso2.openbanking.accelerator.common.config.OpenBankingConfigParser; -import com.wso2.openbanking.accelerator.common.error.OpenBankingErrorCodes; -import com.wso2.openbanking.accelerator.gateway.cache.OpenBankingIdempotencyCacheKey; -import com.wso2.openbanking.accelerator.gateway.cache.OpenBankingIdempotencyValidationCache; -import com.wso2.openbanking.accelerator.gateway.executor.core.OpenBankingGatewayExecutor; -import com.wso2.openbanking.accelerator.gateway.executor.model.OBAPIRequestContext; -import com.wso2.openbanking.accelerator.gateway.executor.model.OBAPIResponseContext; -import com.wso2.openbanking.accelerator.gateway.executor.model.OpenBankingExecutorError; -import com.wso2.openbanking.accelerator.gateway.util.GatewayConstants; -import com.wso2.openbanking.accelerator.gateway.util.IdempotencyConstants; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.apimgt.common.gateway.dto.MsgInfoDTO; - -import java.io.IOException; -import java.time.Duration; -import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -/** - * Executor to handle Payment Idempotency. - */ -public abstract class OpenBankingIdempotencyHandlingExecutor implements OpenBankingGatewayExecutor { - - private static final Log log = LogFactory.getLog(OpenBankingIdempotencyHandlingExecutor.class); - private OpenBankingIdempotencyValidationCache openBankingIdempotencyValidationCache = - OpenBankingIdempotencyValidationCache.getInstance(); - private OpenBankingConfigParser openBankingConfigParser = OpenBankingConfigParser.getInstance(); - - /** - * Method to handle pre request. - * - * @param obapiRequestContext OB request context object. - */ - @Override - public void preProcessRequest(OBAPIRequestContext obapiRequestContext) { - - } - - /** - * Method to handle post request. - * - * @param obapiRequestContext OB request context object. - */ - @Override - public void postProcessRequest(OBAPIRequestContext obapiRequestContext) { - - // Checking if idempotency is enabled. - if (!isIdempotencyEnabledFromConfig()) { - return; - } - - // Validating if the request is a valid idempotency available request. - if (!isValidIdempotencyRequest(obapiRequestContext)) { - return; - } - - //Retrieve headers and payload - Map requestHeaders = obapiRequestContext.getMsgInfo().getHeaders(); - - //Retrieve consumer key from headers - String consumerKey = obapiRequestContext.getApiRequestInfo().getConsumerKey(); - //Retrieve idempotency key from headers - String idempotencyKey = requestHeaders.get(getIdempotencyKeyConstantFromConfig()); - //Retrieve context properties - Map contextProps = obapiRequestContext.getContextProps(); - - // Retrieve elected resources - String resource = obapiRequestContext.getMsgInfo().getResource(); - - //Construct cache keys for request and response using client Id and idempotency key - String idempotencyCacheKey = consumerKey + "_" + resource + "_" + idempotencyKey; - - try { - Map payloadMap = getPayloadFromRequest(obapiRequestContext); - - String payload; - if (payloadMap.containsKey(IdempotencyConstants.PAYLOAD)) { - payload = (String) payloadMap.get(IdempotencyConstants.PAYLOAD); - } else { - log.error("Error reading payload, " + IdempotencyConstants.PAYLOAD + " is not set."); - return; - } - - int httpStatus; - if (payloadMap.containsKey(IdempotencyConstants.HTTP_STATUS)) { - httpStatus = (int) payloadMap.get(IdempotencyConstants.HTTP_STATUS); - } else { - log.error("Error reading HTTP status, " + IdempotencyConstants.HTTP_STATUS + " is not set."); - return; - } - - Map cachedObjectMap = getPropertiesFromCache(idempotencyCacheKey); - //Check whether the request exists in the cache - if (!cachedObjectMap.isEmpty()) { - log.debug("Handling idempotency through gateway"); - - // previous result is present in cache, retrieving request from cache - String cachedRequest = cachedObjectMap.get(GatewayConstants.REQUEST_CACHE_KEY); - String createdTime = cachedObjectMap.get(GatewayConstants.CREATED_TIME_CACHE_KEY); - //Check whether payload received is similar to the payload stored - if (isJSONPayloadSimilar(cachedRequest, payload)) { - log.debug("Payloads are similar for idempotent request"); - //Payloads are similar, hence checking whether request came within allowed time - if (isRequestReceivedWithinAllowedTime(createdTime)) { - log.debug("Idempotent request received within allowed time"); - //Retrieving the response from cache - String cachedResponse = cachedObjectMap.get(GatewayConstants.RESPONSE_CACHE_KEY); - - //Setting payload as modified payload - log.debug("Setting cached payload as the response"); - obapiRequestContext.setModifiedPayload(cachedResponse); - - //Setting Context Properties to return response without executing further - contextProps.put(GatewayConstants.IS_RETURN_RESPONSE, GatewayConstants.TRUE); - contextProps.put(GatewayConstants.MODIFIED_STATUS, String.valueOf(httpStatus)); - } - } else { - //Payloads are not similar, hence returning an error - log.error(IdempotencyConstants.Error.EXECUTOR_IDEMPOTENCY_KEY_FRAUDULENT); - obapiRequestContext.setError(true); - obapiRequestContext.setErrors(handleIdempotencyErrors(obapiRequestContext, - IdempotencyConstants.Error.EXECUTOR_IDEMPOTENCY_KEY_FRAUDULENT, - IdempotencyConstants.Error.HEADER_INVALID)); - } - } else { - log.debug("Request is not found in cache, adding the request to cache."); - //Since request is not in cache, adding the request to the cache against the idempotency key - contextProps.put(GatewayConstants.REQUEST_CACHE_KEY, payload); - } - } catch (IOException e) { - log.error(IdempotencyConstants.Error.EXECUTOR_IDEMPOTENCY_KEY_ERROR, e); - obapiRequestContext.setError(true); - obapiRequestContext.setErrors(handleIdempotencyErrors(obapiRequestContext, - IdempotencyConstants.Error.EXECUTOR_IDEMPOTENCY_KEY_ERROR, - IdempotencyConstants.Error.HEADER_INVALID)); - return; - } - //Adding idempotency key to the context properties - contextProps.put(GatewayConstants.IDEMPOTENCY_KEY_CACHE_KEY, idempotencyKey); - obapiRequestContext.setContextProps(contextProps); - } - - /** - * Method to handle pre response. - * - * @param obapiResponseContext OB response context object. - */ - @Override - public void preProcessResponse(OBAPIResponseContext obapiResponseContext) { - - } - - /** - * Method to handle post response. - * - * @param obapiResponseContext OB response context object. - */ - @Override - public void postProcessResponse(OBAPIResponseContext obapiResponseContext) { - - // Checking if idempotency is enabled. - if (!isIdempotencyEnabledFromConfig()) { - return; - } - - // Validating if the response is a valid idempotency available response. - if (!isValidIdempotencyResponse(obapiResponseContext)) { - return; - } - - //Retrieving payload - String responsePayload = obapiResponseContext.getResponsePayload(); - //Retrieve idempotency key from headers - String consumerKey = obapiResponseContext.getApiRequestInfo().getConsumerKey(); - //Retrieve context properties - Map contextProps = obapiResponseContext.getContextProps(); - - MsgInfoDTO msgInfoDTO = obapiResponseContext.getMsgInfo(); - - String idempotencyKey; - if (msgInfoDTO.getHeaders().get(getIdempotencyKeyConstantFromConfig()) != null) { - //Retrieve idempotency key from headers - idempotencyKey = msgInfoDTO.getHeaders().get(getIdempotencyKeyConstantFromConfig()); - } else { - //Retrieve idempotency key from context props if it does not exist as a header - idempotencyKey = contextProps.get(GatewayConstants.IDEMPOTENCY_KEY_CACHE_KEY); - } - - String createdTime = getCreatedTimeFromResponse(obapiResponseContext); - if (createdTime == null) { - log.error(IdempotencyConstants.Error.DATE_MISSING); - return; - } - - // Retrieve elected resources - String resource = msgInfoDTO.getResource(); - - //Construct cache keys for request and response using client Id and idempotency key - String idempotencyCacheKey = consumerKey + "_" + resource + "_" + idempotencyKey; - - //Add response and created time to the cache - HashMap cachedObject = getPropertiesFromCache(idempotencyCacheKey); - if (contextProps.get(GatewayConstants.REQUEST_CACHE_KEY) != null) { - cachedObject.put(GatewayConstants.REQUEST_CACHE_KEY, contextProps.get(GatewayConstants.REQUEST_CACHE_KEY)); - } - cachedObject.put(GatewayConstants.RESPONSE_CACHE_KEY, responsePayload); - cachedObject.put(GatewayConstants.CREATED_TIME_CACHE_KEY, createdTime); - - log.debug("Setting properties to cache"); - setPropertiesToCache(idempotencyCacheKey, cachedObject); - } - - /** - * Method to handle errors in Idempotency validation. - * - * @param obapiRequestContext obapiRequestContext. - * @param message message. - * @return Arraylist of OpenBankingExecutorError. - */ - protected ArrayList handleIdempotencyErrors(OBAPIRequestContext obapiRequestContext, - String message, String errorCode) { - - OpenBankingExecutorError error = new OpenBankingExecutorError(errorCode, - IdempotencyConstants.Error.IDEMPOTENCY_HANDLE_ERROR, message, - OpenBankingErrorCodes.BAD_REQUEST_CODE); - ArrayList executorErrors = obapiRequestContext.getErrors(); - executorErrors.add(error); - return executorErrors; - } - - /** - * Method to store properties to cache. - * - * @param key unique cache key. - * @param idempotentDetails properties to store. - */ - private void setPropertiesToCache(String key, HashMap idempotentDetails) { - - openBankingIdempotencyValidationCache.addToCache( - OpenBankingIdempotencyCacheKey.of(key), idempotentDetails); - } - - /** - * Method to retrieve context properties from cache. - * - * @param key unique cache key. - * @return context properties. - */ - private HashMap getPropertiesFromCache(String key) { - - HashMap cachedObject = openBankingIdempotencyValidationCache.getFromCache( - OpenBankingIdempotencyCacheKey.of(key)); - return cachedObject == null ? new HashMap<>() : cachedObject; - } - - /** - * Method to compare whether JSON payloads are equal. - * - * @param jsonString1 JSON payload retrieved from database - * @param jsonString2 JSON payload received from current request - * @return - * @throws IOException - */ - private boolean isJSONPayloadSimilar(String jsonString1, String jsonString2) throws IOException { - - JsonNode expectedNode = new ObjectMapper().readTree(jsonString1); - JsonNode actualNode = new ObjectMapper().readTree(jsonString2); - return expectedNode.equals(actualNode); - } - - /** - * Method to check whether difference between two dates is less than the configured time. - * - * @param createdTime Created Time of the request - * @return - */ - protected boolean isRequestReceivedWithinAllowedTime(String createdTime) { - - if (createdTime == null) { - return true; - } - String allowedTimeDuration = (String) openBankingConfigParser.getConfiguration() - .get(IdempotencyConstants.IDEMPOTENCY_ALLOWED_TIME); - if (allowedTimeDuration != null) { - OffsetDateTime createdDate = OffsetDateTime.parse(createdTime); - OffsetDateTime currDate = OffsetDateTime.now(createdDate.getOffset()); - - long diffInHours = Duration.between(createdDate, currDate).toMinutes(); - return diffInHours <= Long.parseLong(allowedTimeDuration); - } else { - log.error("Idempotency Allowed duration is null"); - return false; - } - } - - /** - * Method to check whether Idempotency handling is required. - * - * @return True if idempotency is required, else False. - */ - private boolean isIdempotencyEnabledFromConfig() { - - String isIdempotencyEnabled = (String) openBankingConfigParser.getConfiguration() - .get(IdempotencyConstants.IDEMPOTENCY_IS_ENABLED); - - return Boolean.parseBoolean(isIdempotencyEnabled); - } - - /** - * Method to get the Idempotency Key from the config. - * - * @return idempotency key. - */ - protected String getIdempotencyKeyConstantFromConfig() { - - return (String) openBankingConfigParser.getConfiguration() - .get(IdempotencyConstants.IDEMPOTENCY_KEY_HEADER); - } - - /** - * Method to get Created time from response. - * - * @param obapiResponseContext obapiResponseContext. - * @return created time. - */ - public abstract String getCreatedTimeFromResponse(OBAPIResponseContext obapiResponseContext); - - /** - * Method to get payload from request. - * - * @param obapiRequestContext obapiRequestContext. - * @return Map containing the payload and the http status. - */ - public abstract Map getPayloadFromRequest(OBAPIRequestContext obapiRequestContext); - - /** - * Method to check if the request is a valid idempotency request. - * - * @param obapiRequestContext obapiRequestContext. - * @return True if the request is valid, False if not. - */ - public abstract boolean isValidIdempotencyRequest(OBAPIRequestContext obapiRequestContext); - - /** - * Method to check if the method is a valid idempotency response. - * - * @param obapiResponseContext obapiResponseContext. - * @return True if the response is valid, False if not. - */ - public abstract boolean isValidIdempotencyResponse(OBAPIResponseContext obapiResponseContext); -} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/test/java/com/wso2/openbanking/accelerator/gateway/executor/idempotency/OpenBankingIdempotencyHandlingExecutorImpl.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/test/java/com/wso2/openbanking/accelerator/gateway/executor/idempotency/OpenBankingIdempotencyHandlingExecutorImpl.java deleted file mode 100644 index d6feeb91..00000000 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/test/java/com/wso2/openbanking/accelerator/gateway/executor/idempotency/OpenBankingIdempotencyHandlingExecutorImpl.java +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). - * - * 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 - * - * 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 com.wso2.openbanking.accelerator.gateway.executor.idempotency; - -import com.wso2.openbanking.accelerator.gateway.executor.model.OBAPIRequestContext; -import com.wso2.openbanking.accelerator.gateway.executor.model.OBAPIResponseContext; -import com.wso2.openbanking.accelerator.gateway.util.IdempotencyConstants; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.HttpStatus; -import org.wso2.carbon.apimgt.common.gateway.dto.MsgInfoDTO; - -import java.util.HashMap; -import java.util.Map; - - -/** - * OpenBankingIdempotencyHandlingExecutorImpl. - */ -public class OpenBankingIdempotencyHandlingExecutorImpl extends OpenBankingIdempotencyHandlingExecutor { - - private static final Log log = LogFactory.getLog(OpenBankingIdempotencyHandlingExecutorImpl.class); - - - @Override - public String getCreatedTimeFromResponse(OBAPIResponseContext obapiResponseContext) { - MsgInfoDTO msgInfoDTO = obapiResponseContext.getMsgInfo(); - String createdTime = null; - if (msgInfoDTO.getHeaders().get("CreatedTime") != null) { - //Retrieve response created time from headers - createdTime = msgInfoDTO.getHeaders().get("CreatedTime"); - } - return createdTime; - } - - @Override - public Map getPayloadFromRequest(OBAPIRequestContext obapiRequestContext) { - Map map = new HashMap<>(); - map.put(IdempotencyConstants.PAYLOAD, obapiRequestContext.getRequestPayload()); - map.put(IdempotencyConstants.HTTP_STATUS, HttpStatus.SC_CREATED); - return map; - } - - @Override - public boolean isValidIdempotencyRequest(OBAPIRequestContext obapiRequestContext) { - return true; - } - - @Override - public boolean isValidIdempotencyResponse(OBAPIResponseContext obapiResponseContext) { - return true; - } -} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/test/java/com/wso2/openbanking/accelerator/gateway/executor/idempotency/OpenBankingIdempotencyHandlingExecutorTests.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/test/java/com/wso2/openbanking/accelerator/gateway/executor/idempotency/OpenBankingIdempotencyHandlingExecutorTests.java deleted file mode 100644 index 6af805f0..00000000 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/test/java/com/wso2/openbanking/accelerator/gateway/executor/idempotency/OpenBankingIdempotencyHandlingExecutorTests.java +++ /dev/null @@ -1,229 +0,0 @@ -/** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). - * - * 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 - * - * 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 com.wso2.openbanking.accelerator.gateway.executor.idempotency; - -import com.wso2.openbanking.accelerator.common.config.OpenBankingConfigParser; -import com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedCacheConstants; -import com.wso2.openbanking.accelerator.common.distributed.caching.OpenBankingDistributedMember; -import com.wso2.openbanking.accelerator.gateway.cache.OpenBankingIdempotencyCacheKey; -import com.wso2.openbanking.accelerator.gateway.cache.OpenBankingIdempotencyValidationCache; -import com.wso2.openbanking.accelerator.gateway.executor.model.OBAPIRequestContext; -import com.wso2.openbanking.accelerator.gateway.executor.model.OBAPIResponseContext; -import com.wso2.openbanking.accelerator.gateway.util.GatewayConstants; -import com.wso2.openbanking.accelerator.gateway.util.IdempotencyConstants; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.testng.PowerMockTestCase; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; -import org.wso2.carbon.apimgt.common.gateway.dto.APIRequestInfoDTO; -import org.wso2.carbon.apimgt.common.gateway.dto.MsgInfoDTO; - -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import static org.mockito.Mockito.when; -import static org.powermock.api.mockito.PowerMockito.mockStatic; - -/** - ** Tests class for OpenBankingIdempotencyHandlingExecutor. - */ -@PowerMockIgnore({"jdk.internal.reflect.*", "javax.management.*"}) -@PrepareForTest({OpenBankingConfigParser.class}) -public class OpenBankingIdempotencyHandlingExecutorTests extends PowerMockTestCase { - - @Mock - OBAPIRequestContext obapiRequestContextMock; - - @Mock - OBAPIResponseContext obapiResponseContextMock; - - @Mock - MsgInfoDTO msgInfoDTO; - - @Mock - APIRequestInfoDTO apiRequestInfoDTO; - - @Mock - OpenBankingConfigParser openBankingConfigParser; - - String sampleIdempotencyKey = "a5ff9494-2a15-48f9-8ab4-05a10b91215b"; - String sampleConsumerKey = "dummykey"; - String sampleElectedResource = "/sampleElectedResource/1234"; - String sampleResponsePayload = "{\"transactionStatus\":\"RCVD\",\"chosenScaMethod\":" + - "[{\"name\":\"SMS OTP on Mobile\"," + - "\"authenticationType\":\"SMS_OTP\",\"explanation\":\"SMS based one time password\"," + - "\"authenticationMethodId\":\"sms-otp\"}],\"_links\":{\"scaStatus\":" + - "{\"href\":\"/v1/payments/sepa-credit-transfers/beecd66c-82ae-4ac8-9c04-9bd7c886d4a4/" + - "authorisations/1d5b6e3b-2180-4b4f-bb8c-054c597cb4e3\"},\"scaOAuth\":" + - "{\"href\":\"https://localhost:8243/.well-known/openid-configuration\"}," + - "\"self\":{\"href\":\"/v/payments/sepa-credit-transfers/beecd66c-82ae-4ac8-9c04-9bd7c886d4a4\"}," + - "\"status\":{\"href\":\"/v1/payments/sepa-credit-transfers/beecd66c-82ae-4ac8-9c04-9bd7c886d4a4" + - "/status\"}},\"paymentId\":\"beecd66c-82ae-4ac8-9c04-9bd7c886d4a4\"}"; - - DateTimeFormatter dtf = DateTimeFormatter.ISO_OFFSET_DATE_TIME; - ZonedDateTime zdt = ZonedDateTime.now(); - String sampleCreatedTime = dtf.format(zdt); - - String idempotencyCacheKeyHeader = "x-Idempotency-Key"; - - @BeforeClass - public void initClass() { - - MockitoAnnotations.initMocks(this); - } - - @Test(priority = 1) - public void testPostProcessResponse() { - - mockStatic(OpenBankingConfigParser.class); - when(OpenBankingConfigParser.getInstance()).thenReturn(openBankingConfigParser); - - Map configuration = new HashMap<>(); - configuration.putAll(getDistributedCachingMockConfigurations()); - configuration.putAll(getIdempotencyMockConfigurations()); - Mockito.when(openBankingConfigParser.getConfiguration()).thenReturn(configuration); - - PowerMockito.mockStatic(OpenBankingConfigParser.class); - PowerMockito.when(OpenBankingConfigParser.getInstance()) - .thenReturn(openBankingConfigParser); - - // Mocking response payload - when(obapiResponseContextMock.getResponsePayload()).thenReturn(sampleResponsePayload); - - // Mocking consumer key - when(obapiResponseContextMock.getApiRequestInfo()).thenReturn(apiRequestInfoDTO); - when(apiRequestInfoDTO.getConsumerKey()).thenReturn(sampleConsumerKey); - - // Mocking context props - Map contextProps = new HashMap<>(); - contextProps.put(GatewayConstants.REQUEST_CACHE_KEY, sampleResponsePayload); - contextProps.put(GatewayConstants.IDEMPOTENCY_KEY_CACHE_KEY, sampleIdempotencyKey); - when(obapiResponseContextMock.getContextProps()).thenReturn(contextProps); - - // Mocking response headers - when(obapiResponseContextMock.getMsgInfo()).thenReturn(msgInfoDTO); - Map responseHeaders = new HashMap<>(); - responseHeaders.put(idempotencyCacheKeyHeader, sampleIdempotencyKey); - responseHeaders.put("CreatedTime", sampleCreatedTime); - when(msgInfoDTO.getHeaders()).thenReturn(responseHeaders); - - // Mocking elected resource - when(msgInfoDTO.getResource()).thenReturn(sampleElectedResource); - - OpenBankingIdempotencyHandlingExecutorImpl openBankingIdempotencyHandlingExecutorImpl = - new OpenBankingIdempotencyHandlingExecutorImpl(); - openBankingIdempotencyHandlingExecutorImpl.postProcessResponse(obapiResponseContextMock); - - String cacheKey = sampleConsumerKey + "_" + sampleElectedResource + "_" + sampleIdempotencyKey; - HashMap expectedFromCache = new HashMap<>(); - expectedFromCache.put(GatewayConstants.REQUEST_CACHE_KEY, sampleResponsePayload); - expectedFromCache.put(GatewayConstants.RESPONSE_CACHE_KEY, sampleResponsePayload); - expectedFromCache.put(GatewayConstants.CREATED_TIME_CACHE_KEY, sampleCreatedTime); - - HashMap fromCache = OpenBankingIdempotencyValidationCache.getInstance() - .getFromCache(OpenBankingIdempotencyCacheKey.of(cacheKey)); - - Assert.assertEquals(fromCache, expectedFromCache); - } - - @Test(priority = 2) - public void testPostProcessRequest() { - - mockStatic(OpenBankingConfigParser.class); - when(OpenBankingConfigParser.getInstance()).thenReturn(openBankingConfigParser); - - Map configuration = new HashMap<>(); - configuration.putAll(getDistributedCachingMockConfigurations()); - configuration.putAll(getIdempotencyMockConfigurations()); - Mockito.when(openBankingConfigParser.getConfiguration()).thenReturn(configuration); - - PowerMockito.mockStatic(OpenBankingConfigParser.class); - PowerMockito.when(OpenBankingConfigParser.getInstance()) - .thenReturn(openBankingConfigParser); - - when(obapiRequestContextMock.getRequestPayload()).thenReturn(sampleResponsePayload); - // Mocking request headers - when(obapiRequestContextMock.getMsgInfo()).thenReturn(msgInfoDTO); - Map requestHeaders = new HashMap<>(); - requestHeaders.put(idempotencyCacheKeyHeader, sampleIdempotencyKey); - when(msgInfoDTO.getHeaders()).thenReturn(requestHeaders); - - // Mocking elected resource - when(msgInfoDTO.getResource()).thenReturn(sampleElectedResource); - - // Mocking consumer key - when(obapiRequestContextMock.getApiRequestInfo()).thenReturn(apiRequestInfoDTO); - when(apiRequestInfoDTO.getConsumerKey()).thenReturn(sampleConsumerKey); - - OpenBankingIdempotencyHandlingExecutorImpl openBankingIdempotencyHandlingExecutorImpl = - new OpenBankingIdempotencyHandlingExecutorImpl(); - openBankingIdempotencyHandlingExecutorImpl.postProcessRequest(obapiRequestContextMock); - - } - - private Map getDistributedCachingMockConfigurations() { - - Map configuration = new HashMap<>(); - - configuration.put(OpenBankingDistributedCacheConstants.ENABLED, "true"); - configuration.put(OpenBankingDistributedCacheConstants.HOST_NAME, "localhost"); - configuration.put(OpenBankingDistributedCacheConstants.PORT, "5721"); - configuration.put(OpenBankingDistributedCacheConstants.DISCOVERY_MECHANISM, "Multicast"); - configuration.put(OpenBankingDistributedCacheConstants.MULTICAST_GROUP, "224.2.2.3"); - configuration.put(OpenBankingDistributedCacheConstants.MULTICAST_PORT, "54321"); - ArrayList interfaces = new ArrayList<>(); - interfaces.add("192.168.1.100-110"); - configuration.put(OpenBankingDistributedCacheConstants.TRUSTED_INTERFACES, interfaces); - configuration.put(OpenBankingDistributedCacheConstants.HAZELCAST_PROPERTY_MAX_HEARTBEAT, "600"); - configuration.put(OpenBankingDistributedCacheConstants.HAZELCAST_PROPERTY_MAX_MASTER_CONFIRMATION, "900"); - configuration.put(OpenBankingDistributedCacheConstants.HAZELCAST_PROPERTY_MERGE_FIRST_RUN_DELAY, "60"); - configuration.put(OpenBankingDistributedCacheConstants.HAZELCAST_PROPERTY_MERGE_NEXT_RUN_DELAY, "30"); - configuration.put(OpenBankingDistributedCacheConstants.PROPERTY_LOGGING_TYPE, "none"); - - return configuration; - } - - private Map getIdempotencyMockConfigurations() { - - Map configuration = new HashMap<>(); - configuration.put(IdempotencyConstants.IDEMPOTENCY_IS_ENABLED, "true"); - configuration.put(IdempotencyConstants.IDEMPOTENCY_CACHE_TIME_TO_LIVE, "1440"); - configuration.put(IdempotencyConstants.IDEMPOTENCY_KEY_HEADER, idempotencyCacheKeyHeader); - configuration.put(IdempotencyConstants.IDEMPOTENCY_ALLOWED_TIME, "24"); - - return configuration; - } - - @AfterClass - public void after() { - - OpenBankingDistributedMember.of().shutdown(); - } - -} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/test/java/com/wso2/openbanking/accelerator/gateway/executor/impl/error/handler/OBDefaultErrorHandlerTest.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/test/java/com/wso2/openbanking/accelerator/gateway/executor/impl/error/handler/OBDefaultErrorHandlerTest.java new file mode 100644 index 00000000..d7921b2e --- /dev/null +++ b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/test/java/com/wso2/openbanking/accelerator/gateway/executor/impl/error/handler/OBDefaultErrorHandlerTest.java @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 com.wso2.openbanking.accelerator.gateway.executor.impl.error.handler; + +import com.wso2.openbanking.accelerator.gateway.executor.model.OBAPIRequestContext; +import com.wso2.openbanking.accelerator.gateway.executor.model.OBAPIResponseContext; +import com.wso2.openbanking.accelerator.gateway.executor.model.OpenBankingExecutorError; +import org.mockito.Mockito; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +/** + * Test class for OBDefaultErrorHandler. + */ +public class OBDefaultErrorHandlerTest { + + Map contextProps = new HashMap<>(); + + @Test + public void testPreRequestFlow() { + + OBAPIRequestContext obapiRequestContext = Mockito.mock(OBAPIRequestContext.class); + Mockito.when(obapiRequestContext.isError()).thenReturn(true); + Mockito.when(obapiRequestContext.getErrors()).thenReturn(getErrorList()); + Mockito.when(obapiRequestContext.getContextProps()).thenReturn(contextProps); + Mockito.when(obapiRequestContext.getAnalyticsData()).thenReturn(new HashMap<>()); + + OBDefaultErrorHandler commonReportingDataExecutor = Mockito.spy(OBDefaultErrorHandler.class); + commonReportingDataExecutor.preProcessRequest(obapiRequestContext); + verify(obapiRequestContext, times(0)).setError(false); + } + + @Test + public void testPostRequestFlow() { + + OBAPIRequestContext obapiRequestContext = Mockito.mock(OBAPIRequestContext.class); + Mockito.when(obapiRequestContext.isError()).thenReturn(true); + Mockito.when(obapiRequestContext.getErrors()).thenReturn(getErrorList()); + Mockito.when(obapiRequestContext.getContextProps()).thenReturn(contextProps); + Mockito.when(obapiRequestContext.getAnalyticsData()).thenReturn(new HashMap<>()); + + OBDefaultErrorHandler commonReportingDataExecutor = Mockito.spy(OBDefaultErrorHandler.class); + commonReportingDataExecutor.postProcessRequest(obapiRequestContext); + verify(obapiRequestContext, times(0)).setError(false); + } + + @Test + public void testPreResponseFlow() { + + OBAPIResponseContext obapiResponseContext = Mockito.mock(OBAPIResponseContext.class); + Mockito.when(obapiResponseContext.isError()).thenReturn(true); + Mockito.when(obapiResponseContext.getErrors()).thenReturn(getErrorList()); + Mockito.when(obapiResponseContext.getContextProps()).thenReturn(contextProps); + Mockito.when(obapiResponseContext.getAnalyticsData()).thenReturn(new HashMap<>()); + + OBDefaultErrorHandler commonReportingDataExecutor = Mockito.spy(OBDefaultErrorHandler.class); + commonReportingDataExecutor.preProcessResponse(obapiResponseContext); + verify(obapiResponseContext, times(0)).setError(false); + } + + @Test + public void testPostResponseFlow() { + + OBAPIResponseContext obapiResponseContext = Mockito.mock(OBAPIResponseContext.class); + Mockito.when(obapiResponseContext.isError()).thenReturn(true); + Mockito.when(obapiResponseContext.getErrors()).thenReturn(getErrorList()); + Mockito.when(obapiResponseContext.getContextProps()).thenReturn(contextProps); + Mockito.when(obapiResponseContext.getAnalyticsData()).thenReturn(new HashMap<>()); + + OBDefaultErrorHandler commonReportingDataExecutor = Mockito.spy(OBDefaultErrorHandler.class); + commonReportingDataExecutor.postProcessResponse(obapiResponseContext); + verify(obapiResponseContext, times(0)).setError(false); + } + + private ArrayList getErrorList() { + + OpenBankingExecutorError error = new OpenBankingExecutorError("400", "Invalid Request", + "Mandatory parameter is missing", "400"); + + ArrayList errors = new ArrayList<>(); + errors.add(error); + return errors; + } +} diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/test/resources/testng.xml b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/test/resources/testng.xml index 723ddc92..49169106 100644 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/test/resources/testng.xml +++ b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.gateway/src/test/resources/testng.xml @@ -36,6 +36,7 @@ + @@ -57,11 +58,6 @@ - - - - - diff --git a/open-banking-accelerator/components/consent-management/com.wso2.openbanking.accelerator.consent.extensions/src/main/java/com/wso2/openbanking/accelerator/consent/extensions/common/idempotency/IdempotencyValidationResult.java b/open-banking-accelerator/components/consent-management/com.wso2.openbanking.accelerator.consent.extensions/src/main/java/com/wso2/openbanking/accelerator/consent/extensions/common/idempotency/IdempotencyValidationResult.java new file mode 100644 index 00000000..5a09f8ed --- /dev/null +++ b/open-banking-accelerator/components/consent-management/com.wso2.openbanking.accelerator.consent.extensions/src/main/java/com/wso2/openbanking/accelerator/consent/extensions/common/idempotency/IdempotencyValidationResult.java @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 com.wso2.openbanking.accelerator.consent.extensions.common.idempotency; + +import com.wso2.openbanking.accelerator.consent.mgt.dao.models.DetailedConsentResource; + +/** + * Class to hold idempotency validation result. + */ +public class IdempotencyValidationResult { + + private boolean isIdempotent; + private boolean isValid; + private DetailedConsentResource consent; + private String consentId; + + public IdempotencyValidationResult(boolean isIdempotent, boolean isValid, DetailedConsentResource consent, + String consentId) { + this.isIdempotent = isIdempotent; + this.isValid = isValid; + this.consent = consent; + this.consentId = consentId; + } + + public boolean isIdempotent() { + return isIdempotent; + } + + public void setIsIdempotent(boolean isIdempotent) { + this.isIdempotent = isIdempotent; + } + + public boolean isValid() { + return isValid; + } + + public void setValid(boolean isValid) { + this.isValid = isValid; + } + + public DetailedConsentResource getConsent() { + return consent; + } + + public void setConsent(DetailedConsentResource consent) { + this.consent = consent; + } + + public String getConsentId() { + return consentId; + } + + public void setConsentID(String consentId) { + this.consentId = consentId; + } +} diff --git a/open-banking-accelerator/components/consent-management/com.wso2.openbanking.accelerator.consent.extensions/src/main/java/com/wso2/openbanking/accelerator/consent/extensions/common/idempotency/IdempotencyValidator.java b/open-banking-accelerator/components/consent-management/com.wso2.openbanking.accelerator.consent.extensions/src/main/java/com/wso2/openbanking/accelerator/consent/extensions/common/idempotency/IdempotencyValidator.java new file mode 100644 index 00000000..eabf32ad --- /dev/null +++ b/open-banking-accelerator/components/consent-management/com.wso2.openbanking.accelerator.consent.extensions/src/main/java/com/wso2/openbanking/accelerator/consent/extensions/common/idempotency/IdempotencyValidator.java @@ -0,0 +1,205 @@ +/** + * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 com.wso2.openbanking.accelerator.consent.extensions.common.idempotency; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.wso2.openbanking.accelerator.common.config.OpenBankingConfigParser; +import com.wso2.openbanking.accelerator.common.exception.ConsentManagementException; +import com.wso2.openbanking.accelerator.consent.extensions.internal.ConsentExtensionsDataHolder; +import com.wso2.openbanking.accelerator.consent.mgt.dao.models.DetailedConsentResource; +import com.wso2.openbanking.accelerator.consent.mgt.service.ConsentCoreService; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.IOException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.time.Duration; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.Date; +import java.util.Map; + +/** + * Class to handle idempotency related operations. + */ +public class IdempotencyValidator { + + private static final Log log = LogFactory.getLog(IdempotencyValidator.class); + private static final OpenBankingConfigParser parser = OpenBankingConfigParser.getInstance(); + private static final ConsentCoreService consentCoreService = ConsentExtensionsDataHolder.getInstance() + .getConsentCoreService(); + public static final String IDEMPOTENCY_IS_ENABLED = "Consent.Idempotency.IsEnabled"; + private static final String IDEMPOTENCY_ALLOWED_TIME = "Consent.Idempotency.AllowedTimeDuration"; + + public IdempotencyValidator() { + } + + /** + * Method to check whether the request is idempotent. + * This method will first check whether idempotency validation is enabled. Then it will check whether the + * idempotency key exists in the database and whether the request is received within the allowed time. + * + * @param idempotencyKeyName Idempotency Key Name + * @param idempotencyKeyValue Idempotency Key Value + * @param request Request Payload + * @return IdempotencyValidationResult + */ + public static IdempotencyValidationResult validateIdempotency(String idempotencyKeyName, String idempotencyKeyValue, + String request) { + if (Boolean.parseBoolean((String) parser.getConfiguration().get(IDEMPOTENCY_IS_ENABLED))) { + if (idempotencyKeyValue == null || request.isEmpty()) { + log.debug("Idempotency Key Value or Request is empty. Hence cannot proceed with " + + "idempotency validation"); + return new IdempotencyValidationResult(false, false, null, null); + } + try { + ArrayList consentIds = getConsentIdsFromIdempotencyKey(idempotencyKeyName, + idempotencyKeyValue); + if (isIdempotencyKeyExists(consentIds)) { + log.debug("Idempotency Key exists in the database. Hence this is an idempotent request"); + for (String consentId : consentIds) { + DetailedConsentResource consentRequest = consentCoreService.getDetailedConsent(consentId); + if (consentRequest != null) { + if (isJSONPayloadSimilar(consentRequest.getReceipt(), request)) { + if (isRequestReceivedWithinAllowedTime(consentRequest.getCreatedTime())) { + log.debug("Payloads are similar and request received within allowed time." + + " Hence this is a valid idempotent request"); + return new IdempotencyValidationResult(true, true, + consentRequest, consentId); + } else { + log.debug("Payloads are similar and request is not within allowed time." + + " Hence this is not a valid idempotent request"); + return new IdempotencyValidationResult(true, false, null, null); + } + } else { + log.debug("Payloads are not similar, Hence this is not a valid idempotent " + + "request"); + return new IdempotencyValidationResult(true, false, null, null); + } + } else { + log.debug("No consent details found for the consent ID, Hence this is not a " + + "valid idempotent request"); + return new IdempotencyValidationResult(true, false, null, null); + } + } + } + } catch (IOException | ConsentManagementException e) { + log.error("Error occurred while comparing JSON payloads", e); + } + } + return new IdempotencyValidationResult(false, false, null, null); + } + + /** + * Method to store the idempotency key in the database. + * + * @param consentId Consent ID + * @param idempotencyKeyName Idempotency Key Name + * @param idempotencyKeyValue Idempotency Key Value + * @return Whether the idempotency key is stored in the database + * @throws ConsentManagementException If an error occurs while storing the idempotency key + */ + public static boolean storeIdempotencyKeyInAttributes(String consentId, String idempotencyKeyName, + String idempotencyKeyValue) throws ConsentManagementException { + + return consentCoreService.storeConsentAttributes(consentId, Map.of(idempotencyKeyName, idempotencyKeyValue)); + } + + /** + * Method to retrieve the consent ids that have the idempotency key name and value as attribute. + * + * @param idempotencyKeyName Idempotency Key Name + * @param idempotencyKeyValue Idempotency Key Value + * @return List of consent ids + */ + private static ArrayList getConsentIdsFromIdempotencyKey(String idempotencyKeyName, + String idempotencyKeyValue) { + try { + return consentCoreService.getConsentIdByConsentAttributeNameAndValue( + idempotencyKeyName, idempotencyKeyValue); + } catch (ConsentManagementException e) { + log.debug("No consent ids found for the idempotency key value"); + return new ArrayList<>(); + } + } + + /** + * Method to check whether the idempotency key exists in the database. + * + * @param consentIds List of consentIds + * @return Whether the idempotency key exists + */ + private static boolean isIdempotencyKeyExists(ArrayList consentIds) { + return consentIds.size() > 0; + } + + /** + * Method to compare whether JSON payloads are equal. + * + * @param jsonString1 JSON payload retrieved from database + * @param jsonString2 JSON payload received from current request + * @return Whether JSON payloads are equal + * @throws IOException If an error occurs while comparing JSON payloads + */ + private static boolean isJSONPayloadSimilar(String jsonString1, String jsonString2) throws IOException { + + JsonNode expectedNode = new ObjectMapper().readTree(jsonString1); + JsonNode actualNode = new ObjectMapper().readTree(jsonString2); + return expectedNode.equals(actualNode); + } + + /** + * Method to check whether difference between two dates is less than the configured time. + * + * @param createdTime Created Time of the request + * @return Whether the request is received within allowed time + */ + protected static boolean isRequestReceivedWithinAllowedTime(long createdTime) { + + if (createdTime == 0L) { + return false; + } + String allowedTimeDuration = (String) parser.getConfiguration() + .get(IDEMPOTENCY_ALLOWED_TIME); + if (allowedTimeDuration != null) { + OffsetDateTime createdDate = OffsetDateTime.parse(convertToISO8601(createdTime)); + OffsetDateTime currDate = OffsetDateTime.now(createdDate.getOffset()); + + long diffInHours = Duration.between(createdDate, currDate).toMinutes(); + return diffInHours <= Long.parseLong(allowedTimeDuration); + } else { + log.error("Idempotency Allowed duration is null"); + return false; + } + } + + /** + * Convert long date values to ISO 8601 format. + * @param dateValue Date value + * @return ISO 8601 formatted date + */ + public static String convertToISO8601(long dateValue) { + + DateFormat simple = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); + Date simpleDateVal = new Date(dateValue * 1000); + return simple.format(simpleDateVal); + } +} diff --git a/open-banking-accelerator/components/consent-management/com.wso2.openbanking.accelerator.consent.mgt.dao/pom.xml b/open-banking-accelerator/components/consent-management/com.wso2.openbanking.accelerator.consent.mgt.dao/pom.xml index 33e724c8..0e175dee 100644 --- a/open-banking-accelerator/components/consent-management/com.wso2.openbanking.accelerator.consent.mgt.dao/pom.xml +++ b/open-banking-accelerator/components/consent-management/com.wso2.openbanking.accelerator.consent.mgt.dao/pom.xml @@ -80,6 +80,11 @@ powermock-module-testng test + + com.wso2.openbanking.accelerator + com.wso2.openbanking.accelerator.consent.extensions + test + diff --git a/pom.xml b/pom.xml index 9479e7a6..e4aaab44 100644 --- a/pom.xml +++ b/pom.xml @@ -487,11 +487,6 @@ javax.servlet ${equinox.javax.servlet.version} - - com.hazelcast - hazelcast - ${com.hazelcast.hazelcast.version} - org.jacoco @@ -792,7 +787,6 @@ 1.10.1 4.7.3 3.1.0 - 5.0.2 1.0.0.wso2v3 1.12.0 1.2.0.wso2v1