From adf6664b71f8130ae4c525faf37c8ef6dd503d9c Mon Sep 17 00:00:00 2001 From: arshardh Date: Wed, 19 Apr 2023 17:45:27 +0530 Subject: [PATCH 1/5] Implement recall mechanism for gateway data --- .../apimgt/api/gateway/GatewayAPIDTO.java | 9 +++ .../org.wso2.carbon.apimgt.common.jms/pom.xml | 4 ++ .../jms/JMSConnectionEventListener.java | 8 +++ .../apimgt/common/jms/JMSTaskManager.java | 8 +++ .../apimgt/gateway/InMemoryAPIDeployer.java | 69 +++++++++++++++---- .../apimgt/gateway/internal/DataHolder.java | 1 + .../internal/ServiceReferenceHolder.java | 4 ++ .../listeners/GatewayJMSMessageListener.java | 46 ++++++++++++- .../listeners/GatewayStartupListener.java | 13 ++-- .../apimgt/keymgt/SubscriptionDataHolder.java | 12 ++++ .../apimgt/keymgt/model/entity/API.java | 9 +++ .../v1/common/SynapseArtifactGenerator.java | 1 + 12 files changed, 164 insertions(+), 20 deletions(-) create mode 100644 components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSConnectionEventListener.java diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/gateway/GatewayAPIDTO.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/gateway/GatewayAPIDTO.java index 35c091be20ac..64b563665b88 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/gateway/GatewayAPIDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/gateway/GatewayAPIDTO.java @@ -36,6 +36,7 @@ public class GatewayAPIDTO implements Serializable { private String provider; private String tenantDomain; private String apiId; + private String revision; private String apiContext; private String apiDefinition; private String graphQLSchema; @@ -235,4 +236,12 @@ public String getApiContext() { public void setApiContext(String apiContext) { this.apiContext = apiContext; } + + public String getRevision() { + return revision; + } + + public void setRevision(String revision) { + this.revision = revision; + } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.jms/pom.xml b/components/apimgt/org.wso2.carbon.apimgt.common.jms/pom.xml index 67d626964726..951df89168c5 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.jms/pom.xml +++ b/components/apimgt/org.wso2.carbon.apimgt.common.jms/pom.xml @@ -38,6 +38,10 @@ org.wso2.carbon.apimgt org.wso2.carbon.apimgt.impl + + org.wso2.carbon.apimgt + org.wso2.carbon.apimgt.keymgt + diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSConnectionEventListener.java b/components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSConnectionEventListener.java new file mode 100644 index 000000000000..bd3f53a7fa29 --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSConnectionEventListener.java @@ -0,0 +1,8 @@ +package org.wso2.carbon.apimgt.common.jms; + +public interface JMSConnectionEventListener { + + void onReconnect(); + + void onDisconnect(); +} diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSTaskManager.java b/components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSTaskManager.java index b4960b69d811..b0165199822b 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSTaskManager.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSTaskManager.java @@ -743,6 +743,10 @@ public void onException(JMSException j) { setJmsTaskManagerState(STATE_FAILURE); log.error("JMS Connection failed : " + j.getMessage() + " - shutting down worker tasks"); + if (messageListener instanceof JMSConnectionEventListener) { + ((JMSConnectionEventListener) messageListener).onDisconnect(); + } + int r = 1; long retryDuration = initialReconnectDuration; @@ -782,6 +786,10 @@ public void onException(JMSException j) { isOnExceptionError = false; log.info("Reconnection attempt: " + r + " for " + jmsConsumerName + " was successful!"); + + if (messageListener instanceof JMSConnectionEventListener) { + ((JMSConnectionEventListener) messageListener).onReconnect(); + } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java index e6e09cf5fa8a..2f8a280f7f3b 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java @@ -33,6 +33,7 @@ import org.apache.synapse.transport.dynamicconfigurations.DynamicProfileReloaderHolder; import org.wso2.carbon.apimgt.api.APIManagementException; import org.wso2.carbon.apimgt.api.ExceptionCodes; +import org.wso2.carbon.apimgt.api.APIManagementException; import org.wso2.carbon.apimgt.api.gateway.GatewayAPIDTO; import org.wso2.carbon.apimgt.api.gateway.GatewayContentDTO; import org.wso2.carbon.apimgt.api.gateway.GraphQLSchemaDTO; @@ -60,6 +61,7 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.UUID; @@ -185,6 +187,11 @@ private GatewayAPIDTO retrieveArtifact(String apiId, Set gatewayLabels) return result; } + public boolean deployAllAPIsAtGatewayStartup(Set assignedGatewayLabels, String tenantDomain) + throws ArtifactSynchronizerException { + return deployAllAPIs(assignedGatewayLabels, tenantDomain, false); + } + /** * Deploy an API in the gateway using the deployAPI method in gateway admin. * @@ -193,43 +200,67 @@ private GatewayAPIDTO retrieveArtifact(String apiId, Set gatewayLabels) * @return True if all API artifacts retrieved from the storage and successfully deployed without any error. else * false */ - public boolean deployAllAPIsAtGatewayStartup(Set assignedGatewayLabels, String tenantDomain) - throws ArtifactSynchronizerException { + public boolean deployAllAPIs(Set assignedGatewayLabels, String tenantDomain, + boolean redeployChangedAPIs) throws ArtifactSynchronizerException { boolean result = false; + Map apiMap = null; try { deployJWKSSynapseAPI(tenantDomain); // Deploy JWKS API } catch (APIManagementException e) { log.error("Error while deploying JWKS API for tenant domain :" + tenantDomain, e); } - if (gatewayArtifactSynchronizerProperties.isRetrieveFromStorageEnabled()) { if (artifactRetriever != null) { try { int errorCount = 0; String labelString = String.join("|", assignedGatewayLabels); String encodedString = Base64.encodeBase64URLSafeString(labelString.getBytes()); + APIGatewayAdmin apiGatewayAdmin = new APIGatewayAdmin(); - MessageContext.setCurrentMessageContext(org.wso2.carbon.apimgt.gateway.utils.GatewayUtils.createAxis2MessageContext()); + MessageContext.setCurrentMessageContext( + org.wso2.carbon.apimgt.gateway.utils.GatewayUtils.createAxis2MessageContext()); PrivilegedCarbonContext.startTenantFlow(); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); + PrivilegedCarbonContext.getThreadLocalCarbonContext() + .setTenantDomain(tenantDomain, true); List gatewayRuntimeArtifacts = ServiceReferenceHolder.getInstance().getArtifactRetriever() .retrieveAllArtifacts(encodedString, tenantDomain); - if (gatewayRuntimeArtifacts.size() == 0) { + if (gatewayRuntimeArtifacts.isEmpty()) { return true; } + if (redeployChangedAPIs) { + DataHolder dataHolder = DataHolder.getInstance(); + apiMap = dataHolder.getTenantAPIMap().get(tenantDomain); + } for (String runtimeArtifact : gatewayRuntimeArtifacts) { GatewayAPIDTO gatewayAPIDTO = null; try { if (StringUtils.isNotEmpty(runtimeArtifact)) { gatewayAPIDTO = new Gson().fromJson(runtimeArtifact, GatewayAPIDTO.class); - log.info("Deploying synapse artifacts of " + gatewayAPIDTO.getName()); - apiGatewayAdmin.deployAPI(gatewayAPIDTO); - addDeployedCertificatesToAPIAssociation(gatewayAPIDTO); - addDeployedGraphqlQLToAPI(gatewayAPIDTO); - DataHolder.getInstance().addKeyManagerToAPIMapping(gatewayAPIDTO.getApiId(), - gatewayAPIDTO.getKeyManagers()); - DataHolder.getInstance().markAPIAsDeployed(gatewayAPIDTO); + if (redeployChangedAPIs && apiMap != null) { + org.wso2.carbon.apimgt.keymgt.model.entity.API api = + apiMap.get(gatewayAPIDTO.getApiContext()); + // Here, we redeploy APIs only if there is a new revision deployed in the + // Control Plane and not synced with the gateway due to connection issues. + if (api != null && api.getRevisionId() != null && + (!api.getRevisionId().equalsIgnoreCase(gatewayAPIDTO.getRevision()))) { + DeployAPIInGatewayEvent deployAPIInGatewayEvent = + new DeployAPIInGatewayEvent(UUID.randomUUID().toString(), + System.currentTimeMillis(), + APIConstants.EventType.REMOVE_API_FROM_GATEWAY.name(), + tenantDomain, api.getApiId(), api.getUuid(), + assignedGatewayLabels, api.getName(), api.getVersion(), + api.getApiProvider(), api.getApiType(), api.getContext()); + unDeployAPI(deployAPIInGatewayEvent); + deployAPIFromDTO(gatewayAPIDTO, apiGatewayAdmin); + } else { + if (log.isDebugEnabled()) { + log.debug("API " + gatewayAPIDTO.getName() + " is already deployed"); + } + } + } else { + deployAPIFromDTO(gatewayAPIDTO, apiGatewayAdmin); + } } } catch (AxisFault axisFault) { log.error("Error in deploying " + gatewayAPIDTO.getName() + " to the Gateway ", axisFault); @@ -264,6 +295,18 @@ public boolean deployAllAPIsAtGatewayStartup(Set assignedGatewayLabels, return result; } + private void deployAPIFromDTO(GatewayAPIDTO gatewayAPIDTO, APIGatewayAdmin apiGatewayAdmin) throws AxisFault { + log.info("Deploying synapse artifacts of API ID: " + gatewayAPIDTO.getApiId() + + " and Context: " + gatewayAPIDTO.getApiContext()); + apiGatewayAdmin.deployAPI(gatewayAPIDTO); + addDeployedCertificatesToAPIAssociation(gatewayAPIDTO); + addDeployedGraphqlQLToAPI(gatewayAPIDTO); + DataHolder.getInstance().addKeyManagerToAPIMapping(gatewayAPIDTO.getApiId(), + gatewayAPIDTO.getKeyManagers()); + DataHolder.getInstance().markAPIAsDeployed(gatewayAPIDTO); + } + + private void unDeployAPI(APIGatewayAdmin apiGatewayAdmin, DeployAPIInGatewayEvent gatewayEvent) throws AxisFault { if (gatewayArtifactSynchronizerProperties.isRetrieveFromStorageEnabled()) { diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/DataHolder.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/DataHolder.java index ba162da55982..98e260af9ab4 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/DataHolder.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/DataHolder.java @@ -164,6 +164,7 @@ public void markAPIAsDeployed(GatewayAPIDTO gatewayAPIDTO) { if (log.isDebugEnabled()) { log.debug("API : " + api.getApiName() + "is deployed successfully"); } + api.setRevisionId(gatewayAPIDTO.getRevision()); } } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/ServiceReferenceHolder.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/ServiceReferenceHolder.java index ade19418b387..327261a2ef40 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/ServiceReferenceHolder.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/ServiceReferenceHolder.java @@ -395,6 +395,10 @@ public boolean isTenantLoaded(String tenantDomain) { return activeTenants.contains(tenantDomain); } + public Set getActiveTenants() { + return activeTenants; + } + public void setRedisCacheUtil(RedisCacheUtils redisCacheUtils) { } diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayJMSMessageListener.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayJMSMessageListener.java index 3cdd7eb1ffa2..82807d9f5614 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayJMSMessageListener.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayJMSMessageListener.java @@ -27,6 +27,7 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.apimgt.api.APIManagementException; import org.wso2.carbon.apimgt.api.model.APIStatus; +import org.wso2.carbon.apimgt.common.jms.JMSConnectionEventListener; import org.wso2.carbon.apimgt.gateway.APILoggerManager; import org.wso2.carbon.apimgt.gateway.EndpointCertificateDeployer; import org.wso2.carbon.apimgt.gateway.GoogleAnalyticsConfigDeployer; @@ -55,6 +56,7 @@ import org.wso2.carbon.apimgt.impl.notifier.events.SubscriptionPolicyEvent; import org.wso2.carbon.apimgt.impl.notifier.events.KeyTemplateEvent; import org.wso2.carbon.apimgt.impl.utils.APIUtil; +import org.wso2.carbon.apimgt.keymgt.SubscriptionDataHolder; import org.wso2.carbon.context.PrivilegedCarbonContext; import java.util.HashSet; @@ -67,10 +69,11 @@ import javax.jms.TextMessage; import javax.jms.Topic; -public class GatewayJMSMessageListener implements MessageListener { +public class GatewayJMSMessageListener implements MessageListener, JMSConnectionEventListener { private static final Log log = LogFactory.getLog(GatewayJMSMessageListener.class); private boolean debugEnabled = log.isDebugEnabled(); + private boolean refreshOnReconnect = false; private InMemoryAPIDeployer inMemoryApiDeployer = new InMemoryAPIDeployer(); private EventHubConfigurationDto eventHubConfigurationDto = ServiceReferenceHolder.getInstance() .getAPIManagerConfiguration().getEventHubConfigurationDto(); @@ -78,6 +81,13 @@ public class GatewayJMSMessageListener implements MessageListener { .getInstance().getAPIManagerConfiguration().getGatewayArtifactSynchronizerProperties(); ExecutorService executor = Executors.newSingleThreadExecutor(r -> new Thread(r, "DeploymentThread")); + public GatewayJMSMessageListener() { + } + + public GatewayJMSMessageListener(boolean refreshOnReconnect) { + this.refreshOnReconnect = refreshOnReconnect; + } + public void onMessage(Message message) { try { @@ -410,4 +420,38 @@ private synchronized void handleAsyncWebhooksUnSubscriptionMessage(JsonNode payl ServiceReferenceHolder.getInstance().getSubscriptionsDataService() .removeSubscription(apiKey, topicName, tenantDomain, subscriber); } + + @Override + public void onReconnect() { + if (refreshOnReconnect) { + log.info("Refreshing gateway data stores and deployments."); + new Thread(() -> { + SubscriptionDataHolder.getInstance().refreshSubscriptionStore(); + redeployGatewayArtifacts(); + }).start(); + } + } + + private void redeployGatewayArtifacts() { + Set activeTenants = ServiceReferenceHolder.getInstance().getActiveTenants(); + activeTenants.forEach(tenantDomain -> { + try { + if (log.isDebugEnabled()) { + log.debug("Redeploying artifacts for tenant: " + tenantDomain); + } + inMemoryApiDeployer. + deployAllAPIs(gatewayArtifactSynchronizerProperties.getGatewayLabels(), + tenantDomain, true); + } catch (ArtifactSynchronizerException e) { + log.error("Error while redeploying gateway artifacts for tenant: " + tenantDomain, e); + } + }); + + } + + @Override + public void onDisconnect() { + // We currently do not have any logic to execute for this scenario. + // Added in case we need to implement an operation in the future. + } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayStartupListener.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayStartupListener.java index 3eb3d3d8e0b6..6fb01aea1c13 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayStartupListener.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayStartupListener.java @@ -167,12 +167,12 @@ public void completedServerStartup() { } }).start(); SubscriptionDataHolder.getInstance().registerTenantSubscriptionStore(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); + try { + retrieveAllAPIMetadata(); + } catch (DataLoadingException e) { + log.error("Error while loading All API Metadata", e); + } if (GatewayUtils.isOnDemandLoading()) { - try { - retrieveAllAPIMetadata(); - } catch (DataLoadingException e) { - log.error("Error while loading All API Metadata", e); - } try { new EndpointCertificateDeployer().deployAllCertificatesAtStartup(); } catch (APIManagementException e) { @@ -190,7 +190,8 @@ public void completedServerStartup() { jmsTransportHandlerForEventHub.subscribeForJmsEvents(APIConstants.TopicNames.TOPIC_CACHE_INVALIDATION, new APIMgtGatewayCacheMessageListener()); jmsTransportHandlerForEventHub - .subscribeForJmsEvents(APIConstants.TopicNames.TOPIC_NOTIFICATION, new GatewayJMSMessageListener()); + .subscribeForJmsEvents(APIConstants.TopicNames.TOPIC_NOTIFICATION, + new GatewayJMSMessageListener(true)); jmsTransportHandlerForEventHub .subscribeForJmsEvents(APIConstants.TopicNames.TOPIC_THROTTLE_DATA, new JMSMessageListener()); jmsTransportHandlerForEventHub.subscribeForJmsEvents(APIConstants.TopicNames.TOPIC_ASYNC_WEBHOOKS_DATA, diff --git a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/SubscriptionDataHolder.java b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/SubscriptionDataHolder.java index a90ea3400056..f7610eacfa5d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/SubscriptionDataHolder.java +++ b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/SubscriptionDataHolder.java @@ -17,6 +17,8 @@ */ package org.wso2.carbon.apimgt.keymgt; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.wso2.carbon.apimgt.keymgt.model.SubscriptionDataStore; import org.wso2.carbon.apimgt.keymgt.model.impl.SubscriptionDataStoreImpl; @@ -30,6 +32,7 @@ public class SubscriptionDataHolder { protected Map subscriptionStore = new ConcurrentHashMap<>(); + private static final Log log = LogFactory.getLog(SubscriptionDataHolder.class); private static SubscriptionDataHolder instance = new SubscriptionDataHolder(); public static SubscriptionDataHolder getInstance() { @@ -80,4 +83,13 @@ public SubscriptionDataStore getTenantSubscriptionStore(String tenantDomain) { return null; } + public void refreshSubscriptionStore() { + subscriptionStore.keySet().forEach(tenant -> { + if (log.isDebugEnabled()) { + log.debug("Refreshing subscription data store for tenant: " + tenant); + } + initializeSubscriptionStore(tenant); + }); + } + } diff --git a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/model/entity/API.java b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/model/entity/API.java index 11f0678a7339..5b54131d60da 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/model/entity/API.java +++ b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/model/entity/API.java @@ -41,6 +41,7 @@ public class API implements CacheableEntity { private String organization; private boolean deployed = false; private boolean isDefaultVersion = false; + private String revisionId; public API() { } @@ -295,4 +296,12 @@ public boolean isDeployed() { public void setDeployed(boolean deployed) { this.deployed = deployed; } + + public String getRevisionId() { + return revisionId; + } + + public void setRevisionId(String revisionId) { + this.revisionId = revisionId; + } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/SynapseArtifactGenerator.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/SynapseArtifactGenerator.java index fe25a44e5a04..cc322d1794fa 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/SynapseArtifactGenerator.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/SynapseArtifactGenerator.java @@ -134,6 +134,7 @@ public RuntimeArtifactDto generateGatewayArtifact(List ap } } if (gatewayAPIDTO != null) { + gatewayAPIDTO.setRevision(runTimeArtifact.getRevision()); String content = new Gson().toJson(gatewayAPIDTO); synapseArtifacts.add(content); } From 2df6a990a1370688f328ba38bf0991d2fb06c9e2 Mon Sep 17 00:00:00 2001 From: arshardh Date: Fri, 28 Jul 2023 17:31:50 +0530 Subject: [PATCH 2/5] Fix review comments --- .../apimgt/gateway/listeners/GatewayJMSMessageListener.java | 3 +++ .../org/wso2/carbon/apimgt/keymgt/SubscriptionDataHolder.java | 2 ++ 2 files changed, 5 insertions(+) diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayJMSMessageListener.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayJMSMessageListener.java index 82807d9f5614..a289a4026ad4 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayJMSMessageListener.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayJMSMessageListener.java @@ -436,6 +436,7 @@ private void redeployGatewayArtifacts() { Set activeTenants = ServiceReferenceHolder.getInstance().getActiveTenants(); activeTenants.forEach(tenantDomain -> { try { + new EndpointCertificateDeployer(tenantDomain).deployCertificatesAtStartup(); if (log.isDebugEnabled()) { log.debug("Redeploying artifacts for tenant: " + tenantDomain); } @@ -444,6 +445,8 @@ private void redeployGatewayArtifacts() { tenantDomain, true); } catch (ArtifactSynchronizerException e) { log.error("Error while redeploying gateway artifacts for tenant: " + tenantDomain, e); + } catch (APIManagementException e) { + log.error("Error while redeploying endpoint certificates for tenant: " + tenantDomain, e); } }); diff --git a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/SubscriptionDataHolder.java b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/SubscriptionDataHolder.java index f7610eacfa5d..238a299b8aaf 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/SubscriptionDataHolder.java +++ b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/SubscriptionDataHolder.java @@ -85,6 +85,8 @@ public SubscriptionDataStore getTenantSubscriptionStore(String tenantDomain) { public void refreshSubscriptionStore() { subscriptionStore.keySet().forEach(tenant -> { + // Cleaning the existing SubscriptionDataStore instance before re-population + subscriptionStore.put(tenant, new SubscriptionDataStoreImpl(tenant)); if (log.isDebugEnabled()) { log.debug("Refreshing subscription data store for tenant: " + tenant); } From 4b9597d4153e006912c4b2c6b9a646449f7fe3fb Mon Sep 17 00:00:00 2001 From: arshardh Date: Fri, 28 Jul 2023 19:00:15 +0530 Subject: [PATCH 3/5] Add synchronized block for redeploy logic --- .../carbon/apimgt/gateway/InMemoryAPIDeployer.java | 11 +++++++---- .../gateway/listeners/GatewayJMSMessageListener.java | 6 ++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java index 2f8a280f7f3b..8d4026ae2e93 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java @@ -205,10 +205,13 @@ public boolean deployAllAPIs(Set assignedGatewayLabels, String tenantDom boolean result = false; Map apiMap = null; - try { - deployJWKSSynapseAPI(tenantDomain); // Deploy JWKS API - } catch (APIManagementException e) { - log.error("Error while deploying JWKS API for tenant domain :" + tenantDomain, e); + + if (!redeployChangedAPIs) { + try { + deployJWKSSynapseAPI(tenantDomain); // Deploy JWKS API + } catch (APIManagementException e) { + log.error("Error while deploying JWKS API for tenant domain :" + tenantDomain, e); + } } if (gatewayArtifactSynchronizerProperties.isRetrieveFromStorageEnabled()) { if (artifactRetriever != null) { diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayJMSMessageListener.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayJMSMessageListener.java index a289a4026ad4..f60022d11a3d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayJMSMessageListener.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayJMSMessageListener.java @@ -426,8 +426,10 @@ public void onReconnect() { if (refreshOnReconnect) { log.info("Refreshing gateway data stores and deployments."); new Thread(() -> { - SubscriptionDataHolder.getInstance().refreshSubscriptionStore(); - redeployGatewayArtifacts(); + synchronized (this) { + SubscriptionDataHolder.getInstance().refreshSubscriptionStore(); + redeployGatewayArtifacts(); + } }).start(); } } From 377810cdd2414598881f83e57839f8a0388d691f Mon Sep 17 00:00:00 2001 From: arshardh Date: Tue, 31 Oct 2023 13:54:58 +0530 Subject: [PATCH 4/5] Refactor code --- .../jms/JMSConnectionEventListener.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSConnectionEventListener.java b/components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSConnectionEventListener.java index bd3f53a7fa29..e14643948b41 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSConnectionEventListener.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSConnectionEventListener.java @@ -1,8 +1,32 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. + * + * Licensed 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.apimgt.common.jms; +/** + * This interface is used to listen to JMS connection events. + */ public interface JMSConnectionEventListener { + /** + * This method will be called when the JMS connection is re-established after a disconnection. + */ void onReconnect(); + /** + * This method will be called when the JMS connection is disconnected. + */ void onDisconnect(); } From 18f854a1d8d5dfbed59288080c5f67d536c38db9 Mon Sep 17 00:00:00 2001 From: Anusha Jayasundara Date: Fri, 19 Jan 2024 14:55:28 +0530 Subject: [PATCH 5/5] Update components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSConnectionEventListener.java --- .../carbon/apimgt/common/jms/JMSConnectionEventListener.java | 1 + 1 file changed, 1 insertion(+) diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSConnectionEventListener.java b/components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSConnectionEventListener.java index e14643948b41..cab1f8a84fe6 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSConnectionEventListener.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.jms/src/main/java/org/wso2/carbon/apimgt/common/jms/JMSConnectionEventListener.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.wso2.carbon.apimgt.common.jms; /**