From b78c1e5a1c3b98b2b79a1c4c110eb7efede79d76 Mon Sep 17 00:00:00 2001 From: piyumaldk Date: Tue, 20 Dec 2022 12:26:20 +0530 Subject: [PATCH 01/12] Fix correlation log issue --- .../core/multitenancy/transports/TenantTransportSender.java | 3 ++- .../wso2/carbon/utils/multitenancy/MultitenantConstants.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/transports/TenantTransportSender.java b/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/transports/TenantTransportSender.java index 2d9a65b36d..bafb1b1f09 100644 --- a/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/transports/TenantTransportSender.java +++ b/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/transports/TenantTransportSender.java @@ -197,7 +197,8 @@ public InvocationResponse invoke(MessageContext msgContext) throws AxisFault superTenantOutMessageContext.setProperty(MultitenantConstants.COPY_CONTENT_LENGTH_FROM_INCOMING, contentLengthCopy); - + superTenantOutMessageContext.setProperty(MultitenantConstants.CORRELATION_ID, + msgContext.getProperty(MultitenantConstants.CORRELATION_ID)); superTenantOutMessageContext.setProperty(Constants.Configuration.MESSAGE_TYPE, msgContext.getProperty(Constants.Configuration.MESSAGE_TYPE)); diff --git a/core/org.wso2.carbon.utils/src/main/java/org/wso2/carbon/utils/multitenancy/MultitenantConstants.java b/core/org.wso2.carbon.utils/src/main/java/org/wso2/carbon/utils/multitenancy/MultitenantConstants.java index 6fe1ac61df..20833a4615 100755 --- a/core/org.wso2.carbon.utils/src/main/java/org/wso2/carbon/utils/multitenancy/MultitenantConstants.java +++ b/core/org.wso2.carbon.utils/src/main/java/org/wso2/carbon/utils/multitenancy/MultitenantConstants.java @@ -102,4 +102,5 @@ public class MultitenantConstants { public static final String NO_KEEPALIVE = "NO_KEEPALIVE"; public static final String SYNAPSE_JSON_INPUT_STREAM = "org.apache.synapse.commons.json.JsonInputStream"; + public static final String CORRELATION_ID = "correlation_id"; } From 2fd4b38559ae02bbf62835b56aa3f45aad3ed577 Mon Sep 17 00:00:00 2001 From: RakhithRR Date: Mon, 6 Feb 2023 15:38:14 +0530 Subject: [PATCH 02/12] Upgrade gson to 2.9.1 --- parent/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parent/pom.xml b/parent/pom.xml index ba15865dc4..c761f63c40 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -610,7 +610,7 @@ 1.5.10 1.0M9 2.4.1 - 2.9.0 + 2.9.1 4.4.3 6.10 From e8641b62c0031a059a3b604babc41fe24a99a8e3 Mon Sep 17 00:00:00 2001 From: Sanoj Punchihewa Date: Tue, 21 Feb 2023 11:49:25 +0530 Subject: [PATCH 03/12] Add tenant domain validation for API requests When creating a tenant domain, we have a validation which allows only lowercase letters, numbers, '.', '-' and '_'. Since we are transforming the domain to lowercase when we store and query data from the database, compilations were observed when we send an API request with an uppercase tenant domain. Therefore the same validation is added for requests as well. Git issue: https://github.com/wso2/api-manager/issues/1466 --- .../carbon/core/multitenancy/utils/TenantAxisUtils.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/utils/TenantAxisUtils.java b/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/utils/TenantAxisUtils.java index a5a9d27510..a3983826a1 100644 --- a/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/utils/TenantAxisUtils.java +++ b/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/utils/TenantAxisUtils.java @@ -81,6 +81,7 @@ public final class TenantAxisUtils { private static final Log log = LogFactory.getLog(TenantAxisUtils.class); private static final String TENANT_CONFIGURATION_CONTEXTS = "tenant.config.contexts"; private static final String TENANT_CONFIGURATION_CONTEXTS_CREATED = "tenant.config.contexts.created"; + private static final String ILLEGAL_CHARACTERS_FOR_TENANT_DOMAIN = ".*[^a-z0-9\\._\\-].*"; private static CarbonCoreDataHolder dataHolder = CarbonCoreDataHolder.getInstance(); private static Map tenantReadWriteLocks = new ConcurrentHashMap(); @@ -119,6 +120,12 @@ public static AxisConfiguration getTenantAxisConfiguration(String tenant, ConfigurationContext tenantConfigCtx; Boolean isTenantActive; + if (tenantDomain != null && tenantDomain.matches(ILLEGAL_CHARACTERS_FOR_TENANT_DOMAIN)) { + String errorMsg = "The tenant domain ' " + tenantDomain + + " ' contains one or more illegal characters. The valid characters are " + + "lowercase letters, numbers, '.', '-' and '_'."; + throw new RuntimeException(errorMsg); + } try { isTenantActive = CarbonCoreDataHolder.getInstance().getRealmService().getTenantManager(). isTenantActive(getTenantId(tenantDomain)); From ea16eb26934cad974b9d27636267d8bada39b292 Mon Sep 17 00:00:00 2001 From: GDLMadushanka Date: Fri, 24 Feb 2023 17:07:23 +0530 Subject: [PATCH 04/12] Add debug log to check datasource initialization Add debug logs to view database URL and Driver class information. --- .../carbon/ndatasource/rdbms/RDBMSDataSourceReader.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/org.wso2.carbon.ndatasource.rdbms/src/main/java/org/wso2/carbon/ndatasource/rdbms/RDBMSDataSourceReader.java b/core/org.wso2.carbon.ndatasource.rdbms/src/main/java/org/wso2/carbon/ndatasource/rdbms/RDBMSDataSourceReader.java index 19a8233883..46d5438041 100644 --- a/core/org.wso2.carbon.ndatasource.rdbms/src/main/java/org/wso2/carbon/ndatasource/rdbms/RDBMSDataSourceReader.java +++ b/core/org.wso2.carbon.ndatasource.rdbms/src/main/java/org/wso2/carbon/ndatasource/rdbms/RDBMSDataSourceReader.java @@ -15,6 +15,8 @@ */ package org.wso2.carbon.ndatasource.rdbms; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.wso2.carbon.ndatasource.common.DataSourceException; import org.wso2.carbon.ndatasource.common.spi.DataSourceReader; import org.wso2.carbon.utils.CarbonUtils; @@ -33,6 +35,8 @@ * This class represents the RDBMS based data source reader implementation. */ public class RDBMSDataSourceReader implements DataSourceReader { + + private static Log log = LogFactory.getLog(RDBMSDataSourceReader.class); @Override public String getType() { @@ -64,6 +68,10 @@ public Object createDataSource(String xmlConfiguration, boolean isDataSourceFact (rdbmsConfiguration.getUrl().toLowerCase().contains(";init="))) { throw new DataSourceException( "INIT expressions are not allowed in the connection URL due to security reasons."); + } + if (log.isDebugEnabled()) { + log.debug("Database URL : " + rdbmsConfiguration.getUrl()); + log.debug("Database Driver : " + rdbmsConfiguration.getDriverClassName()); } if (isDataSourceFactoryReference) { return (new RDBMSDataSource(rdbmsConfiguration).getDataSourceFactoryReference()); From 4e46268b3d33077d2eeb2efa9a2db6bdaa785624 Mon Sep 17 00:00:00 2001 From: BLasan Date: Mon, 27 Feb 2023 11:11:16 +0530 Subject: [PATCH 05/12] fixes: https://github.com/wso2/product-apim/issues/9711 --- .../carbon/core/multitenancy/eager/TenantEagerLoader.java | 7 ++++++- .../carbon/core/multitenancy/utils/TenantAxisUtils.java | 7 +++++++ .../src/main/java/org/wso2/carbon/CarbonConstants.java | 2 ++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/eager/TenantEagerLoader.java b/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/eager/TenantEagerLoader.java index 20ab0e0963..659b7bfba9 100644 --- a/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/eager/TenantEagerLoader.java +++ b/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/eager/TenantEagerLoader.java @@ -18,6 +18,7 @@ package org.wso2.carbon.core.multitenancy.eager; +import org.apache.axis2.context.ConfigurationContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; @@ -30,6 +31,8 @@ import java.util.Arrays; import java.util.List; +import static org.wso2.carbon.CarbonConstants.EAGER_LOADING; + /** * This class responsible of processing/validating and load once server startup completed. */ @@ -88,8 +91,10 @@ private void loadTenants(List validTenantDomains) { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); ctx.setTenantDomain(tenantDomain, true); - TenantAxisUtils + ConfigurationContext tenantConfigurationContext = TenantAxisUtils .getTenantConfigurationContext(tenantDomain, carbonCoreDataHolder.getMainServerConfigContext()); + // Set the eager loading property to the tenant configuration context + tenantConfigurationContext.setProperty(EAGER_LOADING, true); } catch (OutOfMemoryError e) { // If OutOfMemoryError during tenant loading we will throw a RuntimeException to notify server admin String msg = "OutOfMemoryError while Eager loading tenant : " + tenantDomain; diff --git a/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/utils/TenantAxisUtils.java b/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/utils/TenantAxisUtils.java index a3983826a1..9d0190bf79 100644 --- a/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/utils/TenantAxisUtils.java +++ b/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/utils/TenantAxisUtils.java @@ -72,6 +72,8 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import static org.wso2.carbon.CarbonConstants.EAGER_LOADING; + /** * Utility methods for Tenant Operations at Axis2-level. */ @@ -447,6 +449,11 @@ public static void cleanupTenants(long tenantIdleTimeMillis) { String tenantDomain = entry.getKey(); synchronized (tenantDomain.intern()) { ConfigurationContext tenantCfgCtx = entry.getValue(); + // Get the Eager Loading tenant property from the tenant configuration context + Object eagerLoadingTenant = tenantCfgCtx.getProperty(EAGER_LOADING); + if (eagerLoadingTenant != null && (boolean) eagerLoadingTenant) { + continue; + } Long lastAccessed = (Long) tenantCfgCtx.getProperty(MultitenantConstants.LAST_ACCESSED); if (System.currentTimeMillis() - lastAccessed >= tenantIdleTimeMillis) { diff --git a/core/org.wso2.carbon.utils/src/main/java/org/wso2/carbon/CarbonConstants.java b/core/org.wso2.carbon.utils/src/main/java/org/wso2/carbon/CarbonConstants.java index 2a5cbb5f0e..69a785cffb 100644 --- a/core/org.wso2.carbon.utils/src/main/java/org/wso2/carbon/CarbonConstants.java +++ b/core/org.wso2.carbon.utils/src/main/java/org/wso2/carbon/CarbonConstants.java @@ -242,6 +242,8 @@ public enum DiagnosticLogMode { public static final String PROTOCOL = "protocol"; public static final String DESCRIPTION = "description"; + public static final String EAGER_LOADING = "EAGER_LOADING_TENANT"; + public static final String ADMIN_SERVICE_PARAM_NAME = "adminService"; public static final String HIDDEN_SERVICE_PARAM_NAME = "hiddenService"; public static final String DYNAMIC_SERVICE_PARAM_NAME = "dynamicService"; From 30ca22c082edbf8e729f7e34299fd9f8ccec0fc2 Mon Sep 17 00:00:00 2001 From: yasasrangika Date: Tue, 28 Feb 2023 14:44:25 +0530 Subject: [PATCH 06/12] improve Error Logs in DBSFileUploadExecutor.java --- .../carbon/ui/transports/fileupload/DBSFileUploadExecutor.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/org.wso2.carbon.ui/src/main/java/org/wso2/carbon/ui/transports/fileupload/DBSFileUploadExecutor.java b/core/org.wso2.carbon.ui/src/main/java/org/wso2/carbon/ui/transports/fileupload/DBSFileUploadExecutor.java index 38e73d6ef4..21c3df7347 100644 --- a/core/org.wso2.carbon.ui/src/main/java/org/wso2/carbon/ui/transports/fileupload/DBSFileUploadExecutor.java +++ b/core/org.wso2.carbon.ui/src/main/java/org/wso2/carbon/ui/transports/fileupload/DBSFileUploadExecutor.java @@ -105,8 +105,7 @@ public boolean execute(HttpServletRequest request, log.error("File upload failed", e); out.write(""); out.write(""); } From ce45665a8da7aa10aadcabc46f9e608dbdccc875 Mon Sep 17 00:00:00 2001 From: Samitha Chathuranga Date: Tue, 28 Feb 2023 19:17:28 +0530 Subject: [PATCH 07/12] Fix the incorrect links in mgt console login page --- .../org/wso2/carbon/i18n/Resources.properties | 8 +++----- .../src/main/resources/web/admin/login.jsp | 18 ------------------ .../src/main/resources/META-INF/product.xml | 3 +-- 3 files changed, 4 insertions(+), 25 deletions(-) diff --git a/core/org.wso2.carbon.i18n/src/main/resources/org/wso2/carbon/i18n/Resources.properties b/core/org.wso2.carbon.i18n/src/main/resources/org/wso2/carbon/i18n/Resources.properties index 55401ce44e..e48eaa59d7 100644 --- a/core/org.wso2.carbon.i18n/src/main/resources/org/wso2/carbon/i18n/Resources.properties +++ b/core/org.wso2.carbon.i18n/src/main/resources/org/wso2/carbon/i18n/Resources.properties @@ -89,12 +89,10 @@ carbon.server.home={0} Home carbon.console.welcome=Welcome to the {0} Management Console user.guide=User Guide user.guide.text=WSO2 Carbon user guide. -forum=Forum -forum.text=The interactive message board for sharing information, questions and comments about WSO2 products. +forum=Community +forum.text=To foster a healthy community through open collaboration and feedback to help each developer and teams. issue.tracker=Issue Tracker -issue.tracker.text=Users are encouraged to report issues & suggest improvements using the JIRA issue tracker. In addition, users can observe the status of the reported issues in progress. -mailing.list=Mailing Lists -mailing.list.text=Report issues, provide feedback & get help from our mailing lists. +issue.tracker.text=Users are encouraged to report issues & suggest improvements using the issue tracker. In addition, users can observe the status of the reported issues in progress. ### login page ### backendURL=Server URL diff --git a/core/org.wso2.carbon.ui/src/main/resources/web/admin/login.jsp b/core/org.wso2.carbon.ui/src/main/resources/web/admin/login.jsp index 0906eaa995..ba4af5a334 100644 --- a/core/org.wso2.carbon.ui/src/main/resources/web/admin/login.jsp +++ b/core/org.wso2.carbon.ui/src/main/resources/web/admin/login.jsp @@ -32,9 +32,6 @@ String userForumURL = String userGuideURL = (String) config.getServletContext().getAttribute(CarbonConstants.PRODUCT_XML_WSO2CARBON + CarbonConstants.PRODUCT_XML_USERGUIDE); -String mailinglistURL = - (String) config.getServletContext().getAttribute(CarbonConstants.PRODUCT_XML_WSO2CARBON + - CarbonConstants.PRODUCT_XML_MAILINGLIST); String issuetrackerURL = (String) config.getServletContext().getAttribute(CarbonConstants.PRODUCT_XML_WSO2CARBON + CarbonConstants.PRODUCT_XML_ISSUETRACKER); @@ -44,9 +41,6 @@ if(userForumURL == null){ if(userGuideURL == null){ userGuideURL = "#"; } -if(mailinglistURL == null){ - mailinglistURL = "#"; -} if(issuetrackerURL == null){ issuetrackerURL = "#"; } @@ -175,18 +169,6 @@ if (CharacterEncoder.getSafeText(request.getParameter("skipLoginPage"))!=null){ - - - - - -

-

- -

- - diff --git a/distribution/product/modules/styles/src/main/resources/META-INF/product.xml b/distribution/product/modules/styles/src/main/resources/META-INF/product.xml index 381d460174..9f2cc7f230 100644 --- a/distribution/product/modules/styles/src/main/resources/META-INF/product.xml +++ b/distribution/product/modules/styles/src/main/resources/META-INF/product.xml @@ -17,9 +17,8 @@ --> - http://stackoverflow.com/questions/tagged/wso2/ + https://wso2.com/community/ https://docs.wso2.org/display/Carbon450/WSO2+Carbon+Documentation - http://wso2.org/mail https://wso2.org/jira/browse/CARBON/ From 103a2bda70b425a20f8adf0ced954096d96d622a Mon Sep 17 00:00:00 2001 From: Avishka-Shamendra Date: Thu, 3 Aug 2023 09:47:21 +0530 Subject: [PATCH 08/12] Add ResponseHeaderSetFilter J2 mapping. --- .../templates/repository/conf/tomcat/web.xml.j2 | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/distribution/kernel/carbon-home/repository/resources/conf/templates/repository/conf/tomcat/web.xml.j2 b/distribution/kernel/carbon-home/repository/resources/conf/templates/repository/conf/tomcat/web.xml.j2 index 14d5d7d131..9045682ce0 100644 --- a/distribution/kernel/carbon-home/repository/resources/conf/templates/repository/conf/tomcat/web.xml.j2 +++ b/distribution/kernel/carbon-home/repository/resources/conf/templates/repository/conf/tomcat/web.xml.j2 @@ -488,6 +488,23 @@ --> + {% for entry in tomcat.custom_response_header_filters %} + + ResponseHeaderSetFilter#{{loop.index}} + org.wso2.carbon.tomcat.ext.filter.ResponseHeaderSetFilter + + headers + {{entry.headers}} + + + + + ResponseHeaderSetFilter#{{loop.index}} + {{entry.filter_url_pattern}} + REQUEST + FORWARD + + {% endfor %} {% if custom_header_filter.enable is sameas true %} From 7b7dff4bcc8b2db31c80bef62bdd5d1ec16a1b7c Mon Sep 17 00:00:00 2001 From: Savindu Dimal Date: Fri, 8 Sep 2023 12:34:54 +0530 Subject: [PATCH 09/12] Stop transport listeners asynchronously during server shutdown --- .../wso2/carbon/core/ServerManagement.java | 61 ++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/ServerManagement.java b/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/ServerManagement.java index 1bbbb028be..9ebfb9de82 100644 --- a/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/ServerManagement.java +++ b/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/ServerManagement.java @@ -33,9 +33,15 @@ import javax.management.QueryExp; import java.io.File; import java.lang.management.ManagementPermission; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; /** * Class for handling Server management functionalilty. @@ -75,13 +81,44 @@ public void startMaintenance() throws Exception { secMan.checkPermission(new ManagementPermission("control")); } log.info("Starting to switch to maintenance mode..."); + stopTransportListeners(); + destroyTransportListeners(); + waitForRequestCompletion(); + } + + /** + * Stop Transport Listeners asynchronously and wait for the completion of the tasks + */ + private void stopTransportListeners() { + ExecutorService transportListenerShutdownPool = Executors.newFixedThreadPool(inTransports.size()); + List> listenerShutdownFutures = new ArrayList<>(); for (TransportInDescription tinDesc : inTransports.values()) { TransportListener transport = tinDesc.getReceiver(); - transport.stop(); + Future future = transportListenerShutdownPool.submit(new TransportListenerShutdownTask(transport)); + listenerShutdownFutures.add(future); + } + + // Wait until shutting down the transport listeners before proceeding + for (Future future : listenerShutdownFutures) { + try { + future.get(); + } catch (Exception e) { + log.error("Error while completing transport listener shutdown", e); + } } + transportListenerShutdownPool.shutdown(); log.info("Stopped all transport listeners"); + } - waitForRequestCompletion(); + /** + * Destroy Transport Listeners + */ + private void destroyTransportListeners() { + // Destroy the TransportListener at the end to clear up resources + for (TransportInDescription tinDesc : inTransports.values()) { + TransportListener transport = tinDesc.getReceiver(); + transport.destroy(); + } } /** @@ -264,4 +301,24 @@ public void endMaintenance() throws Exception { } log.info("Switched to normal mode"); } + + /** + * Callable task to pause and shutdown a transport listener + */ + private class TransportListenerShutdownTask implements Callable { + private TransportListener transport; + + public TransportListenerShutdownTask(TransportListener transport) { + this.transport = transport; + } + + public Void call() throws Exception { + try { + transport.stop(); + } catch (Exception e) { + log.error("Error while stopping Transport Listener", e); + } + return null; + } + } } From c7452271a1d666fac1d7858eeb8ecdcc47a333f5 Mon Sep 17 00:00:00 2001 From: Dinith Herath <41161459+DinithHerath@users.noreply.github.com> Date: Thu, 23 Feb 2023 19:55:31 +0530 Subject: [PATCH 10/12] Fix for running APIM as windows on JAVA17 via yajsw --- .../kernel/carbon-home/bin/yajsw/wrapper.conf | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/distribution/kernel/carbon-home/bin/yajsw/wrapper.conf b/distribution/kernel/carbon-home/bin/yajsw/wrapper.conf index 45d1513d23..8f515b27a2 100644 --- a/distribution/kernel/carbon-home/bin/yajsw/wrapper.conf +++ b/distribution/kernel/carbon-home/bin/yajsw/wrapper.conf @@ -81,29 +81,29 @@ wrapper.app.parameter.2 = RUN wrapper.java.additional.1 = -Xbootclasspath/a:${carbon_home}/lib/xboot/*.jar wrapper.java.additional.2 = -Xms256m wrapper.java.additional.3 = -Xmx1024m -wrapper.java.additional.4 = -XX:MaxPermSize=256m -wrapper.java.additional.5 = -XX:+HeapDumpOnOutOfMemoryError -wrapper.java.additional.6 = -XX:HeapDumpPath=${carbon_home}/repository/logs/heap-dump.hprof -wrapper.java.additional.7 = -Dcom.sun.management.jmxremote -wrapper.java.additional.8 = -Dcarbon.registry.root=\/ -wrapper.java.additional.9 = -Dcarbon.home=${carbon_home} -wrapper.java.additional.10 = -Dwso2.server.standalone=true -wrapper.java.additional.11 = -Djava.command=${java_home}/bin/java -wrapper.java.additional.12 = -Djava.io.tmpdir=${carbon_home}/tmp -wrapper.java.additional.13 = -Dcatalina.base=${carbon_home}/lib/tomcat -wrapper.java.additional.14 = -Djava.util.logging.config.file=${carbon_home}/repository/conf/etc/logging-bridge.properties -wrapper.java.additional.15 = -Dcarbon.config.dir.path=${carbon_home}/repository/conf -wrapper.java.additional.16 = -Dcarbon.logs.path=${carbon_home}/repository/logs -wrapper.java.additional.17 = -Dcomponents.repo=${carbon_home}/repository/components/plugins -wrapper.java.additional.18 = -Dconf.location=${carbon_home}/repository/conf -wrapper.java.additional.19 = -Dcom.atomikos.icatch.file=${carbon_home}/lib/transactions.properties -wrapper.java.additional.20 = -Dcom.atomikos.icatch.hide_init_file_path=true -wrapper.java.additional.21 = -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true -wrapper.java.additional.22 = -Dcom.sun.jndi.ldap.connect.pool.authentication=simple -wrapper.java.additional.23 = -Dcom.sun.jndi.ldap.connect.pool.timeout=3000 -wrapper.java.additional.24 = -Dorg.terracotta.quartz.skipUpdateCheck=true -wrapper.java.additional.25 = -Dorg.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING=false -wrapper.java.additional.26 = -Dfile.encoding=UTF8 -wrapper.java.additional.27 = -DworkerNode=false -wrapper.java.additional.28 = -Dhttpclient.hostnameVerifier=DefaultAndLocalhost -wrapper.java.additional.29 = -Dcarbon.new.config.dir.path=${carbon_home}/repository/resources/conf +wrapper.java.additional.4 = -XX:+HeapDumpOnOutOfMemoryError +wrapper.java.additional.5 = -XX:HeapDumpPath=${carbon_home}/repository/logs/heap-dump.hprof +wrapper.java.additional.6 = -Dcom.sun.management.jmxremote +wrapper.java.additional.7 = -Dcarbon.registry.root=\/ +wrapper.java.additional.8 = -Dcarbon.home=${carbon_home} +wrapper.java.additional.9 = -Dwso2.server.standalone=true +wrapper.java.additional.10 = -Djava.command=${java_home}/bin/java +wrapper.java.additional.11 = -Djava.io.tmpdir=${carbon_home}/tmp +wrapper.java.additional.12 = -Dcatalina.base=${carbon_home}/lib/tomcat +wrapper.java.additional.13 = -Djava.util.logging.config.file=${carbon_home}/repository/conf/etc/logging-bridge.properties +wrapper.java.additional.14 = -Dcarbon.config.dir.path=${carbon_home}/repository/conf +wrapper.java.additional.15 = -Dcarbon.logs.path=${carbon_home}/repository/logs +wrapper.java.additional.16 = -Dcomponents.repo=${carbon_home}/repository/components/plugins +wrapper.java.additional.17 = -Dconf.location=${carbon_home}/repository/conf +wrapper.java.additional.18 = -Dcom.atomikos.icatch.file=${carbon_home}/lib/transactions.properties +wrapper.java.additional.19 = -Dcom.atomikos.icatch.hide_init_file_path=true +wrapper.java.additional.20 = -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true +wrapper.java.additional.21 = -Dcom.sun.jndi.ldap.connect.pool.authentication=simple +wrapper.java.additional.22 = -Dcom.sun.jndi.ldap.connect.pool.timeout=3000 +wrapper.java.additional.23 = -Dorg.terracotta.quartz.skipUpdateCheck=true +wrapper.java.additional.24 = -Dorg.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING=false +wrapper.java.additional.25 = -Dfile.encoding=UTF8 +wrapper.java.additional.26 = -DworkerNode=false +wrapper.java.additional.27 = -Dhttpclient.hostnameVerifier=DefaultAndLocalhost +wrapper.java.additional.28 = -Dcarbon.new.config.dir.path=${carbon_home}/repository/resources/conf +wrapper.java.additional.29 = -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager From ee3726e98a5a23bbdb2cefd72ccb357b4054958f Mon Sep 17 00:00:00 2001 From: hiranyakavishani Date: Fri, 2 Feb 2024 16:30:03 +0530 Subject: [PATCH 11/12] Adding missing registry indices --- distribution/kernel/carbon-home/dbscripts/db2.sql | 2 ++ distribution/kernel/carbon-home/dbscripts/h2.sql | 1 + distribution/kernel/carbon-home/dbscripts/mssql.sql | 4 ++++ distribution/kernel/carbon-home/dbscripts/mysql.sql | 1 + distribution/kernel/carbon-home/dbscripts/oracle.sql | 2 ++ distribution/kernel/carbon-home/dbscripts/oracle_rac.sql | 2 ++ distribution/kernel/carbon-home/dbscripts/postgresql.sql | 3 ++- 7 files changed, 14 insertions(+), 1 deletion(-) diff --git a/distribution/kernel/carbon-home/dbscripts/db2.sql b/distribution/kernel/carbon-home/dbscripts/db2.sql index 83f6d1e313..576966e630 100644 --- a/distribution/kernel/carbon-home/dbscripts/db2.sql +++ b/distribution/kernel/carbon-home/dbscripts/db2.sql @@ -282,6 +282,8 @@ CREATE TABLE REG_RESOURCE_TAG( CREATE INDEX REG_TAG_IND_BY_PA1 ON REG_RESOURCE_TAG(REG_PATH_ID,REG_RESOURCE_NAME,REG_TENANT_ID)/ +CREATE INDEX REG_TAG_IND_BY_TG1 + ON REG_RESOURCE_TAG(REG_TAG_ID, REG_TENANT_ID)/ CREATE INDEX REG_TAG_IND_BY_VE1 ON REG_RESOURCE_TAG(REG_VERSION,REG_TENANT_ID)/ diff --git a/distribution/kernel/carbon-home/dbscripts/h2.sql b/distribution/kernel/carbon-home/dbscripts/h2.sql index ec1f31a461..4a7b1dbd6a 100644 --- a/distribution/kernel/carbon-home/dbscripts/h2.sql +++ b/distribution/kernel/carbon-home/dbscripts/h2.sql @@ -163,6 +163,7 @@ ALTER TABLE REG_RESOURCE_TAG ADD CONSTRAINT IF NOT EXISTS REG_RESOURCE_TAG_FK_BY ALTER TABLE REG_RESOURCE_TAG ADD CONSTRAINT IF NOT EXISTS REG_RESOURCE_TAG_FK_BY_TAG_ID FOREIGN KEY (REG_TAG_ID, REG_TENANT_ID) REFERENCES REG_TAG (REG_ID, REG_TENANT_ID); CREATE INDEX IF NOT EXISTS REG_RESOURCE_TAG_IND_BY_PATH_ID_AND_RESOURCE_NAME ON REG_RESOURCE_TAG(REG_PATH_ID, REG_RESOURCE_NAME, REG_TENANT_ID); CREATE INDEX IF NOT EXISTS REG_RESOURCE_TAG_IND_BY_VERSION ON REG_RESOURCE_TAG(REG_VERSION, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_TAG_IND_BY_REG_TAG_ID ON REG_RESOURCE_TAG(REG_TAG_ID, REG_TENANT_ID); CREATE TABLE IF NOT EXISTS REG_PROPERTY ( REG_ID INTEGER NOT NULL AUTO_INCREMENT, diff --git a/distribution/kernel/carbon-home/dbscripts/mssql.sql b/distribution/kernel/carbon-home/dbscripts/mssql.sql index 026da68ca3..b906057d0f 100755 --- a/distribution/kernel/carbon-home/dbscripts/mssql.sql +++ b/distribution/kernel/carbon-home/dbscripts/mssql.sql @@ -258,6 +258,10 @@ IF EXISTS (SELECT NAME FROM SYSINDEXES WHERE NAME = 'REG_RESOURCE_TAG_IND_BY_VER DROP INDEX REG_RESOURCE_TAG.REG_RESOURCE_TAG_IND_BY_VERSION CREATE INDEX REG_RESOURCE_TAG_IND_BY_VERSION ON REG_RESOURCE_TAG(REG_VERSION, REG_TENANT_ID); +IF EXISTS (SELECT NAME FROM SYSINDEXES WHERE NAME = 'REG_RESOURCE_TAG_IND_BY_REG_TAG_ID') + DROP INDEX REG_RESOURCE_TAG.REG_RESOURCE_TAG_IND_BY_REG_TAG_ID + CREATE INDEX REG_RESOURCE_TAG_IND_BY_REG_TAG_ID ON REG_RESOURCE_TAG(REG_TAG_ID, REG_TENANT_ID); + --CREATE TABLE REG_PROPERTY IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[REG_PROPERTY]') AND TYPE IN (N'U')) diff --git a/distribution/kernel/carbon-home/dbscripts/mysql.sql b/distribution/kernel/carbon-home/dbscripts/mysql.sql index 4fb59b615c..b46f40fd38 100644 --- a/distribution/kernel/carbon-home/dbscripts/mysql.sql +++ b/distribution/kernel/carbon-home/dbscripts/mysql.sql @@ -189,6 +189,7 @@ ALTER TABLE REG_RESOURCE_PROPERTY ADD CONSTRAINT REG_RESOURCE_PROPERTY_FK_BY_PAT ALTER TABLE REG_RESOURCE_PROPERTY ADD CONSTRAINT REG_RESOURCE_PROPERTY_FK_BY_TAG_ID FOREIGN KEY (REG_PROPERTY_ID, REG_TENANT_ID) REFERENCES REG_PROPERTY (REG_ID, REG_TENANT_ID); CREATE INDEX REG_RESOURCE_PROPERTY_IND_BY_PATH_ID_AND_RESOURCE_NAME USING HASH ON REG_RESOURCE_PROPERTY(REG_PATH_ID, REG_RESOURCE_NAME, REG_TENANT_ID); CREATE INDEX REG_RESOURCE_PROPERTY_IND_BY_VERSION USING HASH ON REG_RESOURCE_PROPERTY(REG_VERSION, REG_TENANT_ID); +CREATE INDEX REG_RESOURCE_TAG_IND_BY_REG_TAG_ID USING HASH ON REG_RESOURCE_TAG(REG_TAG_ID, REG_TENANT_ID); -- CREATE TABLE IF NOT EXISTS REG_ASSOCIATIONS ( -- SRC_PATH_ID INTEGER, diff --git a/distribution/kernel/carbon-home/dbscripts/oracle.sql b/distribution/kernel/carbon-home/dbscripts/oracle.sql index 5913649bf2..51440d980e 100644 --- a/distribution/kernel/carbon-home/dbscripts/oracle.sql +++ b/distribution/kernel/carbon-home/dbscripts/oracle.sql @@ -275,6 +275,8 @@ CREATE INDEX REG_TAG_IND_BY_PATH_ID ON REG_RESOURCE_TAG(REG_PATH_ID, REG_RESOURC / CREATE INDEX REG_TAG_IND_BY_VERSION ON REG_RESOURCE_TAG(REG_VERSION, REG_TENANT_ID) / +CREATE INDEX REG_TAG_IND_BY_TAG_ID ON REG_RESOURCE_TAG(REG_TAG_ID, REG_TENANT_ID) +/ CREATE TABLE REG_PROPERTY ( REG_ID INTEGER, REG_NAME VARCHAR2(100) NOT NULL, diff --git a/distribution/kernel/carbon-home/dbscripts/oracle_rac.sql b/distribution/kernel/carbon-home/dbscripts/oracle_rac.sql index c831cff87d..cb9f48028a 100644 --- a/distribution/kernel/carbon-home/dbscripts/oracle_rac.sql +++ b/distribution/kernel/carbon-home/dbscripts/oracle_rac.sql @@ -275,6 +275,8 @@ CREATE INDEX REG_TAG_IND_BY_PATH_ID ON REG_RESOURCE_TAG(REG_PATH_ID, REG_RESOURC / CREATE INDEX REG_TAG_IND_BY_VERSION ON REG_RESOURCE_TAG(REG_VERSION, REG_TENANT_ID) / +CREATE INDEX REG_TAG_IND_BY_TAG_ID ON REG_RESOURCE_TAG(REG_TAG_ID, REG_TENANT_ID) +/ CREATE TABLE REG_PROPERTY ( REG_ID INTEGER, REG_NAME VARCHAR2(100) NOT NULL, diff --git a/distribution/kernel/carbon-home/dbscripts/postgresql.sql b/distribution/kernel/carbon-home/dbscripts/postgresql.sql index 50ffa4921a..df8bd3fc76 100644 --- a/distribution/kernel/carbon-home/dbscripts/postgresql.sql +++ b/distribution/kernel/carbon-home/dbscripts/postgresql.sql @@ -195,6 +195,7 @@ ALTER TABLE REG_RESOURCE_TAG ADD CONSTRAINT REG_RESOURCE_TAG_FK_BY_PATH_ID FOREI ALTER TABLE REG_RESOURCE_TAG ADD CONSTRAINT REG_RESOURCE_TAG_FK_BY_TAG_ID FOREIGN KEY (REG_TAG_ID, REG_TENANT_ID) REFERENCES REG_TAG (REG_ID, REG_TENANT_ID); CREATE INDEX REG_RESOURCE_TAG_IND_BY_PATH_ID_AND_RESOURCE_NAME ON REG_RESOURCE_TAG(REG_PATH_ID, REG_RESOURCE_NAME, REG_TENANT_ID); CREATE INDEX REG_RESOURCE_TAG_IND_BY_VERSION ON REG_RESOURCE_TAG(REG_VERSION, REG_TENANT_ID); +CREATE INDEX REG_RESOURCE_TAG_IND_BY_REG_TAG_ID ON REG_RESOURCE_TAG(REG_TAG_ID, REG_TENANT_ID); DROP TABLE IF EXISTS REG_PROPERTY; DROP SEQUENCE IF EXISTS REG_PROPERTY_PK_SEQ; @@ -224,7 +225,7 @@ ALTER TABLE REG_RESOURCE_PROPERTY ADD CONSTRAINT REG_RESOURCE_PROPERTY_FK_BY_PAT ALTER TABLE REG_RESOURCE_PROPERTY ADD CONSTRAINT REG_RESOURCE_PROPERTY_FK_BY_TAG_ID FOREIGN KEY (REG_PROPERTY_ID, REG_TENANT_ID) REFERENCES REG_PROPERTY (REG_ID, REG_TENANT_ID); CREATE INDEX REG_RESOURCE_PROPERTY_IND_BY_PATH_ID_AND_RESOURCE_NAME ON REG_RESOURCE_PROPERTY(REG_PATH_ID, REG_RESOURCE_NAME, REG_TENANT_ID); CREATE INDEX REG_RESOURCE_PROPERTY_IND_BY_VERSION ON REG_RESOURCE_PROPERTY(REG_VERSION, REG_TENANT_ID); - +CREATE INDEX REG_RESOURCE_PROPERTY_IND_BY_REG_PROP_ID ON REG_RESOURCE_PROPERTY(REG_TENANT_ID, REG_PROPERTY_ID); DROP TABLE IF EXISTS REG_ASSOCIATION; DROP SEQUENCE IF EXISTS REG_ASSOCIATION_PK_SEQ; From 1232ce602bbab034b4b43d5bff80f7a9927a9d81 Mon Sep 17 00:00:00 2001 From: GDLMadushanka Date: Wed, 12 Oct 2022 13:50:51 +0530 Subject: [PATCH 12/12] Add datasource caching Add datasource caching to avoid creating excessive connections to the databse. Fixes wso2/api-manager/issues/781 --- .../multitenancy/utils/TenantAxisUtils.java | 5 ++ .../common/UserStoreDeploymentManager.java | 6 ++ .../user/core/jdbc/JDBCUserStoreManager.java | 19 +++++- .../user/core/util/DatasourceDataHolder.java | 67 +++++++++++++++++++ 4 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/util/DatasourceDataHolder.java diff --git a/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/utils/TenantAxisUtils.java b/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/utils/TenantAxisUtils.java index 9d0190bf79..045a4599ee 100644 --- a/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/utils/TenantAxisUtils.java +++ b/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/multitenancy/utils/TenantAxisUtils.java @@ -58,6 +58,7 @@ import org.wso2.carbon.registry.core.session.UserRegistry; import org.wso2.carbon.user.core.tenant.Tenant; import org.wso2.carbon.user.core.tenant.TenantManager; +import org.wso2.carbon.user.core.util.DatasourceDataHolder; import org.wso2.carbon.utils.Axis2ConfigurationContextObserver; import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.ServerConstants; @@ -480,6 +481,10 @@ public static void cleanupTenants(long tenantIdleTimeMillis) { } } tenantConfigContexts.remove(tenantDomain); + // removing cached datasources of the domain + DatasourceDataHolder.removeDatasourcesOfTenant(getTenantId(tenantDomain)); + } catch (Exception e) { + log.error("Error occurred while fetching the tenant details"); } finally { PrivilegedCarbonContext.endTenantFlow(); } diff --git a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/common/UserStoreDeploymentManager.java b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/common/UserStoreDeploymentManager.java index 2c40e3e236..554d0e72e9 100644 --- a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/common/UserStoreDeploymentManager.java +++ b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/common/UserStoreDeploymentManager.java @@ -29,9 +29,11 @@ import org.wso2.carbon.user.core.config.UserStoreConfigXMLProcessor; import org.wso2.carbon.user.core.tenant.TenantCache; import org.wso2.carbon.user.core.tenant.TenantIdKey; +import org.wso2.carbon.user.core.util.DatasourceDataHolder; import org.wso2.carbon.user.core.util.UserCoreUtil; import java.io.File; +import java.util.AbstractMap; import java.util.regex.Pattern; public class UserStoreDeploymentManager { @@ -165,6 +167,10 @@ public void undeploy(String fileName) throws DeploymentException { if (!isDisabled) { userStoreManager.removeSecondaryUserStoreManager(domainName); + DatasourceDataHolder dataHolder = DatasourceDataHolder.getInstance(); + AbstractMap.SimpleEntry key + = new AbstractMap.SimpleEntry<>(String.valueOf(tenantId), domainName.toUpperCase()); + dataHolder.removeDomainDataSources(key); } } catch (Exception ex) { String errorMessage = "Error occurred at undeploying " + domainName + " from tenant:" + diff --git a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/jdbc/JDBCUserStoreManager.java b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/jdbc/JDBCUserStoreManager.java index 25a6bcb643..e9bead5758 100644 --- a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/jdbc/JDBCUserStoreManager.java +++ b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/jdbc/JDBCUserStoreManager.java @@ -54,6 +54,7 @@ import org.wso2.carbon.user.core.profile.ProfileConfigurationManager; import org.wso2.carbon.user.core.tenant.Tenant; import org.wso2.carbon.user.core.util.DatabaseUtil; +import org.wso2.carbon.user.core.util.DatasourceDataHolder; import org.wso2.carbon.user.core.util.JDBCRealmUtil; import org.wso2.carbon.user.core.util.UserCoreUtil; import org.wso2.carbon.utils.Secret; @@ -71,6 +72,7 @@ import java.sql.SQLIntegrityConstraintViolationException; import java.sql.SQLTimeoutException; import java.sql.Timestamp; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -116,7 +118,7 @@ public class JDBCUserStoreManager extends AbstractUserStoreManager { private static final String MYSQL = "mysql"; private static final String MARIADB = "mariadb"; private static final String POSTGRESQL = "postgresql"; - + public static final String PRIMARY_USER_STORE_DOMAIN = "PRIMARY"; private static final int MAX_ITEM_LIMIT_UNLIMITED = -1; public JDBCUserStoreManager() { @@ -293,9 +295,16 @@ public JDBCUserStoreManager(RealmConfiguration realmConfig, Map } this.claimManager = claimManager; this.userRealm = realm; - + boolean addDataStore = false; + // cache secondary user-store datasources. + String domain = getMyDomainName(); + AbstractMap.SimpleEntry key = new AbstractMap.SimpleEntry<>(String.valueOf(tenantId), domain); + jdbcds = DatasourceDataHolder.getInstance().getDataStoreForDomain(key); try { - jdbcds = loadUserStoreSpacificDataSoruce(); + if (jdbcds == null) { + addDataStore = !(PRIMARY_USER_STORE_DOMAIN.equals(domain) || tenantId == MultitenantConstants.SUPER_TENANT_ID); + jdbcds = loadUserStoreSpacificDataSoruce(); + } if (jdbcds == null) { jdbcds = (DataSource) properties.get(UserCoreConstants.DATA_SOURCE); @@ -305,6 +314,10 @@ public JDBCUserStoreManager(RealmConfiguration realmConfig, Map properties.put(UserCoreConstants.DATA_SOURCE, jdbcds); } + if (addDataStore) { + DatasourceDataHolder.getInstance().addDataSourceForDomain(key, jdbcds); + } + if (log.isDebugEnabled()) { log.debug("The jdbcDataSource being used by JDBCUserStoreManager :: " + jdbcds.hashCode()); diff --git a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/util/DatasourceDataHolder.java b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/util/DatasourceDataHolder.java new file mode 100644 index 0000000000..d2798540a1 --- /dev/null +++ b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/util/DatasourceDataHolder.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2022, WSO2 LLC (http://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 org.wso2.carbon.user.core.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.sql.DataSource; +import java.util.AbstractMap; +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Data holder to maintain datasource (JDBC) references of each domain. + */ +public class DatasourceDataHolder { + + private static final DatasourceDataHolder Instance = new DatasourceDataHolder(); + private static Log log = LogFactory.getLog(DatasourceDataHolder.class); + //key = + private static ConcurrentHashMap, DataSource> dataSourceHolder + = new ConcurrentHashMap<>(); + + public static DatasourceDataHolder getInstance() { + return Instance; + } + + public void addDataSourceForDomain(AbstractMap.SimpleEntry key, DataSource dataSource) { + dataSourceHolder.put(key, dataSource); + } + + public void removeDomainDataSources(AbstractMap.SimpleEntry domain) { + dataSourceHolder.remove(domain); + } + + public DataSource getDataStoreForDomain(AbstractMap.SimpleEntry domain) { + return dataSourceHolder.get(domain); + } + + public static void removeDatasourcesOfTenant(int tenantId) { + Iterator> iterator = dataSourceHolder.keySet().iterator(); + while (iterator.hasNext()) { + AbstractMap.SimpleEntry entry = iterator.next(); + if (entry.getKey().equals(String.valueOf(tenantId))) { + // Closing the connections + if (dataSourceHolder.get(entry) instanceof org.apache.tomcat.jdbc.pool.DataSourceProxy) { + ((org.apache.tomcat.jdbc.pool.DataSourceProxy) dataSourceHolder.get(entry)).close(true); + } + dataSourceHolder.remove(entry); + } + } + } +}