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..5ad211ebbb 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 @@ -53,12 +53,12 @@ import org.apache.synapse.util.logging.LoggingUtils; import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; import java.util.Map; import java.util.List; import java.util.LinkedHashMap; import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.Collection; import java.util.Set; import java.util.HashSet; @@ -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); } @@ -276,20 +280,13 @@ public boolean canProcess(MessageContext synCtx) { return false; } } else { - String path = ApiUtils.getFullRequestPath(synCtx); - if (null == synCtx.getProperty(RESTConstants.IS_PROMETHEUS_ENGAGED) && - (!ApiUtils.matchApiPath(path, context))) { - auditDebug("API context: " + context + " does not match request URI: " + path); - return false; - } - - if(!versionStrategy.isMatchingVersion(synCtx)){ + if (!ApiUtils.identifyApi(this, synCtx)) { return false; } + ApiUtils.getFullRequestPath(synCtx); org.apache.axis2.context.MessageContext msgCtx = ((Axis2MessageContext) synCtx).getAxis2MessageContext(); - if (host != null || port != -1) { String hostHeader = getHostHeader(msgCtx); if (hostHeader != null) { @@ -443,12 +440,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 +522,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/AbstractApiHandler.java b/modules/core/src/main/java/org/apache/synapse/api/AbstractApiHandler.java index d8a04b387b..8896496a76 100644 --- a/modules/core/src/main/java/org/apache/synapse/api/AbstractApiHandler.java +++ b/modules/core/src/main/java/org/apache/synapse/api/AbstractApiHandler.java @@ -51,19 +51,30 @@ protected boolean dispatchToAPI(Collection apiSet, MessageContext synCtx) { Object apiObject = synCtx.getProperty(RESTConstants.PROCESSED_API); if (apiObject != null) { - if (identifyAPI((API) apiObject, synCtx, defaultStrategyApiSet)) { + if (startProcess((API) apiObject, synCtx, defaultStrategyApiSet)) { return true; } } else { //To avoid apiSet being modified concurrently List duplicateApiSet = new ArrayList(apiSet); - for (API api : duplicateApiSet) { - if (identifyAPI(api, synCtx, defaultStrategyApiSet)) { + API identifiedApi = (API) synCtx.getProperty(RESTConstants.IDENTIFIED_API); + //If normal path this goes to else, if logging enabled then goes inside the if method. + if (identifiedApi != null + && duplicateApiSet.contains(identifiedApi)) { + if (startProcess(identifiedApi, synCtx, defaultStrategyApiSet)) { return true; } + } else { + for (API api : duplicateApiSet) { + if (startProcess(api, synCtx, defaultStrategyApiSet)) { + return true; + } + } } } - + if(synCtx.getProperty(RESTConstants.IDENTIFIED_API) != null) { + synCtx.getPropertyKeySet().remove(RESTConstants.IDENTIFIED_API); + } for (API api : defaultStrategyApiSet) { api.setLogSetterValue(); if (api.canProcess(synCtx)) { @@ -110,7 +121,7 @@ protected void apiProcessNonDefaultStrategy(MessageContext synCtx, API api) { } } - protected boolean identifyAPI(API api, MessageContext synCtx, List defaultStrategyApiSet) { + protected boolean startProcess(API api, MessageContext synCtx, List defaultStrategyApiSet) { API defaultAPI = null; api.setLogSetterValue(); if ("/".equals(api.getContext())) { 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..a1ff77f83d 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,10 @@ 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.api.version.VersionStrategy; import org.apache.synapse.core.axis2.Axis2MessageContext; import org.apache.synapse.rest.RESTConstants; import org.apache.synapse.api.dispatch.DefaultDispatcher; @@ -39,8 +43,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 +161,57 @@ public static String getSubRequestPath(MessageContext synCtx) { return (String) synCtx.getProperty(RESTConstants.REST_SUB_REQUEST_PATH); } + public static boolean identifyApi(API api, MessageContext synCtx) { + if (synCtx.getProperty(RESTConstants.IDENTIFIED_API) == null) { + String path = ApiUtils.getFullRequestPath(synCtx); + if (null == synCtx.getProperty(RESTConstants.IS_PROMETHEUS_ENGAGED) && + (!ApiUtils.matchApiPath(path, api.getContext()))) { + log.debug("API context: " + api.getContext() + " does not match request URI: " + path); + return false; + } + if (null != synCtx.getProperty(RESTConstants.IS_PROMETHEUS_ENGAGED) && + (!ApiUtils.matchApiPath(path, api.getContext()))) { + log.debug("API context: " + api.getContext() + " does not match request URI: " + path); + return false; + } + if (!api.getVersionStrategy().isMatchingVersion(synCtx)) { + return false; + } + synCtx.setProperty(RESTConstants.IDENTIFIED_API, api); + return true; + } else { + return true; + } + } + + /** + * 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 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 +231,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..6a31677f4b 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,7 @@ 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 IDENTIFIED_API = "IDENTIFIED_API"; + public static final String SELECTED_RESOURCE = "SELECTED_RESOURCE"; }