From 6a4859182e1637545efb6ae49f35377284edaa4a Mon Sep 17 00:00:00 2001 From: Chamika Sudusinghe <44718392+chamikasudusinghe@users.noreply.github.com> Date: Tue, 20 Jun 2023 20:40:35 +0530 Subject: [PATCH 1/6] refactored the methods to get resources of apis Issue: wso2/api-manager#1564 --- .../main/java/org/apache/synapse/api/API.java | 28 +++----------- .../java/org/apache/synapse/api/ApiUtils.java | 37 ++++++++++++++++--- .../api/dispatch/DefaultDispatcher.java | 2 + .../dispatch/URITemplateBasedDispatcher.java | 5 ++- .../dispatch/URLMappingBasedDispatcher.java | 4 ++ .../apache/synapse/rest/RESTConstants.java | 1 + 6 files changed, 47 insertions(+), 30 deletions(-) diff --git a/modules/core/src/main/java/org/apache/synapse/api/API.java b/modules/core/src/main/java/org/apache/synapse/api/API.java index 78cfb298c6..2c59db3b47 100644 --- a/modules/core/src/main/java/org/apache/synapse/api/API.java +++ b/modules/core/src/main/java/org/apache/synapse/api/API.java @@ -246,6 +246,10 @@ public Resource[] getResources() { return resources.values().toArray(new Resource[resources.size()]); } + public Map getResourcesMap() { + return resources; + } + public void addHandler(Handler handler) { handlers.add(handler); } @@ -443,12 +447,7 @@ public void process(MessageContext synCtx) { msgCtx.getIncomingTransportName() + "://" + hostHeader); } - Set acceptableResources = new LinkedHashSet(); - for (Resource r : resources.values()) { - if (isBound(r, synCtx) && r.canProcess(synCtx)) { - acceptableResources.add(r); - } - } + Set acceptableResources = ApiUtils.getAcceptableResources(resources, synCtx); boolean processed = false; if (!acceptableResources.isEmpty()) { @@ -530,23 +529,6 @@ private void handleMethodNotAllowed(MessageContext synCtx) { } - /** - * Checks whether the provided resource is capable of processing the message from the provided message context. - * The resource becomes capable to do this when the it contains either the name of the api caller, - * or {@value ApiConstants#DEFAULT_BINDING_ENDPOINT_NAME}, in its binds-to. - * - * @param resource Resource object - * @param synCtx MessageContext object - * @return Whether the provided resource is bound to the provided message context - */ - private boolean isBound(Resource resource, MessageContext synCtx) { - Collection bindings = resource.getBindsTo(); - Object apiCaller = synCtx.getProperty(ApiConstants.API_CALLER); - if (apiCaller != null) { - return bindings.contains(apiCaller.toString()); - } - return bindings.contains(ApiConstants.DEFAULT_BINDING_ENDPOINT_NAME); - } /** * Helper method to use when no matching resource found diff --git a/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java b/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java index 03f87607c0..a7a6ecde00 100644 --- a/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java +++ b/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java @@ -39,8 +39,7 @@ import java.net.URISyntaxException; import java.net.URL; import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.List; +import java.util.*; public class ApiUtils { @@ -158,6 +157,34 @@ public static String getSubRequestPath(MessageContext synCtx) { return (String) synCtx.getProperty(RESTConstants.REST_SUB_REQUEST_PATH); } + /** + * Checks whether the provided resource is capable of processing the message from the provided message context. + * The resource becomes capable to do this when the it contains either the name of the api caller, + * or {@value ApiConstants#DEFAULT_BINDING_ENDPOINT_NAME}, in its binds-to. + * + * @param resource Resource object + * @param synCtx MessageContext object + * @return Whether the provided resource is bound to the provided message context + */ + public static boolean isBound(Resource resource, MessageContext synCtx) { + Collection bindings = resource.getBindsTo(); + Object apiCaller = synCtx.getProperty(ApiConstants.API_CALLER); + if (apiCaller != null) { + return bindings.contains(apiCaller.toString()); + } + return bindings.contains(ApiConstants.DEFAULT_BINDING_ENDPOINT_NAME); + } + + public static Set getAcceptableResources(Map resources, MessageContext synCtx) { + Set acceptableResources = new LinkedHashSet(); + for (Resource r : resources.values()) { + if (isBound(r, synCtx) && r.canProcess(synCtx)) { + acceptableResources.add(r); + } + } + return acceptableResources; + } + public static List getDispatchers() { return dispatchers; } @@ -177,10 +204,10 @@ private static void handleException(String msg, Throwable t) { * and false if the two values don't match */ public static boolean matchApiPath(String path, String context) { - if (!path.startsWith(context + "/") && !path.startsWith(context + "?") && - !context.equals(path) && !"/".equals(context)) { + if (!path.startsWith(context + "/") && !path.startsWith(context + "?") + && !context.equals(path) && !"/".equals(context)) { return false; } return true; } -} +} \ No newline at end of file diff --git a/modules/core/src/main/java/org/apache/synapse/api/dispatch/DefaultDispatcher.java b/modules/core/src/main/java/org/apache/synapse/api/dispatch/DefaultDispatcher.java index b2ed6f41d1..58ccaa1598 100644 --- a/modules/core/src/main/java/org/apache/synapse/api/dispatch/DefaultDispatcher.java +++ b/modules/core/src/main/java/org/apache/synapse/api/dispatch/DefaultDispatcher.java @@ -20,6 +20,7 @@ import org.apache.synapse.MessageContext; import org.apache.synapse.api.Resource; +import org.apache.synapse.rest.RESTConstants; import java.util.Collection; @@ -28,6 +29,7 @@ public class DefaultDispatcher implements RESTDispatcher { public Resource findResource(MessageContext synCtx, Collection resources) { for (Resource resource : resources) { if (resource.getDispatcherHelper() == null) { + synCtx.setProperty(RESTConstants.SELECTED_RESOURCE, resource); return resource; } } diff --git a/modules/core/src/main/java/org/apache/synapse/api/dispatch/URITemplateBasedDispatcher.java b/modules/core/src/main/java/org/apache/synapse/api/dispatch/URITemplateBasedDispatcher.java index 27f77ff24f..007e684747 100644 --- a/modules/core/src/main/java/org/apache/synapse/api/dispatch/URITemplateBasedDispatcher.java +++ b/modules/core/src/main/java/org/apache/synapse/api/dispatch/URITemplateBasedDispatcher.java @@ -35,12 +35,13 @@ public Resource findResource(MessageContext synCtx, Collection resourc DispatcherHelper helper = r.getDispatcherHelper(); if (helper instanceof URITemplateHelper) { URITemplateHelper templateHelper = (URITemplateHelper) helper; - Map variables = new HashMap(); + Map variables = new HashMap(); if (templateHelper.getUriTemplate().matches(url, variables)) { - for (Map.Entry entry : variables.entrySet()) { + for (Map.Entry entry : variables.entrySet()) { synCtx.setProperty(RESTConstants.REST_URI_VARIABLE_PREFIX + entry.getKey(), entry.getValue()); } + synCtx.setProperty(RESTConstants.SELECTED_RESOURCE, r); return r; } } diff --git a/modules/core/src/main/java/org/apache/synapse/api/dispatch/URLMappingBasedDispatcher.java b/modules/core/src/main/java/org/apache/synapse/api/dispatch/URLMappingBasedDispatcher.java index 5a45551b6b..6a0e2639df 100644 --- a/modules/core/src/main/java/org/apache/synapse/api/dispatch/URLMappingBasedDispatcher.java +++ b/modules/core/src/main/java/org/apache/synapse/api/dispatch/URLMappingBasedDispatcher.java @@ -23,6 +23,7 @@ import org.apache.synapse.MessageContext; import org.apache.synapse.api.ApiUtils; import org.apache.synapse.api.Resource; +import org.apache.synapse.rest.RESTConstants; import java.util.ArrayList; import java.util.Collection; @@ -55,6 +56,7 @@ public Resource findResource(MessageContext synCtx, Collection resourc if (log.isDebugEnabled()) { log.debug("Found exact URL match for: " + url); } + synCtx.setProperty(RESTConstants.SELECTED_RESOURCE, filteredResources.get(i)); return filteredResources.get(i); } } @@ -72,6 +74,7 @@ public Resource findResource(MessageContext synCtx, Collection resourc if (log.isDebugEnabled()) { log.debug("Found path match for: " + url + " with matching length: " + maxLength); } + synCtx.setProperty(RESTConstants.SELECTED_RESOURCE, matchedResource); return matchedResource; } @@ -80,6 +83,7 @@ public Resource findResource(MessageContext synCtx, Collection resourc if (log.isDebugEnabled()) { log.debug("Found extension match for: " + url); } + synCtx.setProperty(RESTConstants.SELECTED_RESOURCE, filteredResources.get(i)); return filteredResources.get(i); } } diff --git a/modules/core/src/main/java/org/apache/synapse/rest/RESTConstants.java b/modules/core/src/main/java/org/apache/synapse/rest/RESTConstants.java index 8c41f33b3c..3dbda87712 100644 --- a/modules/core/src/main/java/org/apache/synapse/rest/RESTConstants.java +++ b/modules/core/src/main/java/org/apache/synapse/rest/RESTConstants.java @@ -91,5 +91,6 @@ public static enum METHODS { */ public static final String IS_PROMETHEUS_ENGAGED = "IS_PROMETHEUS_ENGAGED"; public static final String PROCESSED_API = "PROCESSED_API"; + public static final String SELECTED_RESOURCE = "SELECTED_RESOURCE"; } From 23c60201f0315a4b08d13efeea7742adfb16cf8b Mon Sep 17 00:00:00 2001 From: Chamika Sudusinghe <44718392+chamikasudusinghe@users.noreply.github.com> Date: Thu, 22 Jun 2023 10:26:51 +0530 Subject: [PATCH 2/6] util to identify the selected api --- .../java/org/apache/synapse/api/ApiUtils.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java b/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java index a7a6ecde00..784fff4577 100644 --- a/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java +++ b/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java @@ -25,6 +25,9 @@ import org.apache.synapse.MessageContext; import org.apache.synapse.SynapseConstants; import org.apache.synapse.SynapseException; +import org.apache.synapse.api.version.ContextVersionStrategy; +import org.apache.synapse.api.version.DefaultStrategy; +import org.apache.synapse.api.version.URLBasedVersionStrategy; import org.apache.synapse.core.axis2.Axis2MessageContext; import org.apache.synapse.rest.RESTConstants; import org.apache.synapse.api.dispatch.DefaultDispatcher; @@ -185,6 +188,66 @@ public static Set getAcceptableResources(Map resourc return acceptableResources; } + public static API getSelectedAPI(MessageContext synCtx) { + API selectedApi; + API defaultAPI = null; + //getting the API collection from the synapse configuration to find the invoked API + Collection apiSet = synCtx.getEnvironment().getSynapseConfiguration().getAPIs(); + //Since swapping elements are not possible with sets, Collection is converted to a List + List defaultStrategyApiSet = new ArrayList(apiSet); + //To avoid apiSet being modified concurrently + List duplicateApiSet = new ArrayList<>(apiSet); + //identiy the api using canProcess method + for (API api : duplicateApiSet) { + if (identifySelectedAPI(api, synCtx, defaultStrategyApiSet)) { + selectedApi = api; + return selectedApi; + } + } + for (API api : defaultStrategyApiSet) { + api.setLogSetterValue(); + if (api.canProcess(synCtx)) { + if (log.isDebugEnabled()) { + log.debug("Located specific API: " + api.getName() + " for processing message"); + } + selectedApi = api; + return selectedApi; + } + } + if (defaultAPI != null && defaultAPI.canProcess(synCtx)) { + defaultAPI.setLogSetterValue(); + return defaultAPI; + } + return null; + } + + public static boolean identifySelectedAPI(API api, MessageContext synCtx, List defaultStrategyApiSet) { + API defaultAPI = null; + api.setLogSetterValue(); + if ("/".equals(api.getContext())) { + defaultAPI = api; + } else if (api.getVersionStrategy().getClass().getName().equals(DefaultStrategy.class.getName())) { + //APIs whose VersionStrategy is bound to an instance of DefaultStrategy, should be skipped and processed at + // last.Otherwise they will be always chosen to process the request without matching the version. + defaultStrategyApiSet.add(api); + } else if (api.getVersionStrategy().getClass().getName().equals(ContextVersionStrategy.class.getName()) + || api.getVersionStrategy().getClass().getName().equals(URLBasedVersionStrategy.class.getName())) { + api.setLogSetterValue(); + if (api.canProcess(synCtx)) { + if (log.isDebugEnabled()) { + log.debug("Located specific API: " + api.getName() + " for processing message"); + } + return true; + } + } else if (api.canProcess(synCtx)) { + if (log.isDebugEnabled()) { + log.debug("Located specific API: " + api.getName() + " for processing message"); + } + return true; + } + return false; + } + public static List getDispatchers() { return dispatchers; } From 11dca3a21f181ea4a62868addea9de0304a3caaa Mon Sep 17 00:00:00 2001 From: tharikaGitHub Date: Thu, 22 Feb 2024 20:10:25 +0530 Subject: [PATCH 3/6] Remove wild card import --- .../src/main/java/org/apache/synapse/api/ApiUtils.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java b/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java index 784fff4577..bf688bb79d 100644 --- a/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java +++ b/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java @@ -42,7 +42,12 @@ import java.net.URISyntaxException; import java.net.URL; import java.net.URLDecoder; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; public class ApiUtils { From 156ef92a8c9131b33e8bbb57eafa585d7e2f9f9b Mon Sep 17 00:00:00 2001 From: tharikaGitHub Date: Fri, 1 Mar 2024 12:00:33 +0530 Subject: [PATCH 4/6] Fix review comments --- .../core/src/main/java/org/apache/synapse/api/ApiUtils.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java b/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java index bf688bb79d..8d81e6c6b2 100644 --- a/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java +++ b/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java @@ -195,7 +195,6 @@ public static Set getAcceptableResources(Map resourc public static API getSelectedAPI(MessageContext synCtx) { API selectedApi; - API defaultAPI = null; //getting the API collection from the synapse configuration to find the invoked API Collection apiSet = synCtx.getEnvironment().getSynapseConfiguration().getAPIs(); //Since swapping elements are not possible with sets, Collection is converted to a List @@ -219,10 +218,6 @@ public static API getSelectedAPI(MessageContext synCtx) { return selectedApi; } } - if (defaultAPI != null && defaultAPI.canProcess(synCtx)) { - defaultAPI.setLogSetterValue(); - return defaultAPI; - } return null; } From acc1acd62242916c5311e8315d79375578c6e22d Mon Sep 17 00:00:00 2001 From: tharikaGitHub Date: Fri, 1 Mar 2024 13:20:06 +0530 Subject: [PATCH 5/6] Remove unnecessary variable selectedApi --- .../src/main/java/org/apache/synapse/api/ApiUtils.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java b/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java index 8d81e6c6b2..faa8e551ee 100644 --- a/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java +++ b/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java @@ -194,7 +194,6 @@ public static Set getAcceptableResources(Map resourc } public static API getSelectedAPI(MessageContext synCtx) { - API selectedApi; //getting the API collection from the synapse configuration to find the invoked API Collection apiSet = synCtx.getEnvironment().getSynapseConfiguration().getAPIs(); //Since swapping elements are not possible with sets, Collection is converted to a List @@ -204,8 +203,7 @@ public static API getSelectedAPI(MessageContext synCtx) { //identiy the api using canProcess method for (API api : duplicateApiSet) { if (identifySelectedAPI(api, synCtx, defaultStrategyApiSet)) { - selectedApi = api; - return selectedApi; + return api; } } for (API api : defaultStrategyApiSet) { @@ -214,8 +212,7 @@ public static API getSelectedAPI(MessageContext synCtx) { if (log.isDebugEnabled()) { log.debug("Located specific API: " + api.getName() + " for processing message"); } - selectedApi = api; - return selectedApi; + return api; } } return null; From 69179d04fa62be1bf92820f3808d9e8694d7fff6 Mon Sep 17 00:00:00 2001 From: tharikaGitHub Date: Fri, 1 Mar 2024 15:15:19 +0530 Subject: [PATCH 6/6] Fix doc comments --- .../src/main/java/org/apache/synapse/api/ApiUtils.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java b/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java index faa8e551ee..7533f2b6a2 100644 --- a/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java +++ b/modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java @@ -193,6 +193,12 @@ public static Set getAcceptableResources(Map resourc return acceptableResources; } + /** + * This method is used to locate the specific API that has been invoked from the collection of all APIs. + * + * @param synCtx MessageContext of the request + * @return Selected API + */ public static API getSelectedAPI(MessageContext synCtx) { //getting the API collection from the synapse configuration to find the invoked API Collection apiSet = synCtx.getEnvironment().getSynapseConfiguration().getAPIs(); @@ -200,7 +206,7 @@ public static API getSelectedAPI(MessageContext synCtx) { List defaultStrategyApiSet = new ArrayList(apiSet); //To avoid apiSet being modified concurrently List duplicateApiSet = new ArrayList<>(apiSet); - //identiy the api using canProcess method + //identify the api using canProcess method for (API api : duplicateApiSet) { if (identifySelectedAPI(api, synCtx, defaultStrategyApiSet)) { return api; @@ -218,7 +224,7 @@ public static API getSelectedAPI(MessageContext synCtx) { return null; } - public static boolean identifySelectedAPI(API api, MessageContext synCtx, List defaultStrategyApiSet) { + private static boolean identifySelectedAPI(API api, MessageContext synCtx, List defaultStrategyApiSet) { API defaultAPI = null; api.setLogSetterValue(); if ("/".equals(api.getContext())) {