Skip to content

Commit

Permalink
Merge pull request #2150 from tharikaGitHub/common-criteria-features
Browse files Browse the repository at this point in the history
Add a new method to identify the invoked API
  • Loading branch information
isudana authored Mar 1, 2024
2 parents e4a27d8 + 69179d0 commit 7f18134
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 28 deletions.
28 changes: 5 additions & 23 deletions modules/core/src/main/java/org/apache/synapse/api/API.java
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,10 @@ public Resource[] getResources() {
return resources.values().toArray(new Resource[resources.size()]);
}

public Map<String, Resource> getResourcesMap() {
return resources;
}

public void addHandler(Handler handler) {
handlers.add(handler);
}
Expand Down Expand Up @@ -443,12 +447,7 @@ public void process(MessageContext synCtx) {
msgCtx.getIncomingTransportName() + "://" + hostHeader);
}

Set<Resource> acceptableResources = new LinkedHashSet<Resource>();
for (Resource r : resources.values()) {
if (isBound(r, synCtx) && r.canProcess(synCtx)) {
acceptableResources.add(r);
}
}
Set<Resource> acceptableResources = ApiUtils.getAcceptableResources(resources, synCtx);

boolean processed = false;
if (!acceptableResources.isEmpty()) {
Expand Down Expand Up @@ -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<String> 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
Expand Down
99 changes: 96 additions & 3 deletions modules/core/src/main/java/org/apache/synapse/api/ApiUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -40,7 +43,11 @@
import java.net.URL;
import java.net.URLDecoder;
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 {

Expand Down Expand Up @@ -158,6 +165,92 @@ 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<String> 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<Resource> getAcceptableResources(Map<String, Resource> resources, MessageContext synCtx) {
Set<Resource> acceptableResources = new LinkedHashSet<Resource>();
for (Resource r : resources.values()) {
if (isBound(r, synCtx) && r.canProcess(synCtx)) {
acceptableResources.add(r);
}
}
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<API> apiSet = synCtx.getEnvironment().getSynapseConfiguration().getAPIs();
//Since swapping elements are not possible with sets, Collection is converted to a List
List<API> defaultStrategyApiSet = new ArrayList<API>(apiSet);
//To avoid apiSet being modified concurrently
List<API> duplicateApiSet = new ArrayList<>(apiSet);
//identify the api using canProcess method
for (API api : duplicateApiSet) {
if (identifySelectedAPI(api, synCtx, defaultStrategyApiSet)) {
return api;
}
}
for (API api : defaultStrategyApiSet) {
api.setLogSetterValue();
if (api.canProcess(synCtx)) {
if (log.isDebugEnabled()) {
log.debug("Located specific API: " + api.getName() + " for processing message");
}
return api;
}
}
return null;
}

private 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<RESTDispatcher> getDispatchers() {
return dispatchers;
}
Expand All @@ -177,10 +270,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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -28,6 +29,7 @@ public class DefaultDispatcher implements RESTDispatcher {
public Resource findResource(MessageContext synCtx, Collection<Resource> resources) {
for (Resource resource : resources) {
if (resource.getDispatcherHelper() == null) {
synCtx.setProperty(RESTConstants.SELECTED_RESOURCE, resource);
return resource;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@ public Resource findResource(MessageContext synCtx, Collection<Resource> resourc
DispatcherHelper helper = r.getDispatcherHelper();
if (helper instanceof URITemplateHelper) {
URITemplateHelper templateHelper = (URITemplateHelper) helper;
Map<String,String> variables = new HashMap<String,String>();
Map<String, String> variables = new HashMap<String, String>();
if (templateHelper.getUriTemplate().matches(url, variables)) {
for (Map.Entry<String,String> entry : variables.entrySet()) {
for (Map.Entry<String, String> entry : variables.entrySet()) {
synCtx.setProperty(RESTConstants.REST_URI_VARIABLE_PREFIX + entry.getKey(),
entry.getValue());
}
synCtx.setProperty(RESTConstants.SELECTED_RESOURCE, r);
return r;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -55,6 +56,7 @@ public Resource findResource(MessageContext synCtx, Collection<Resource> resourc
if (log.isDebugEnabled()) {
log.debug("Found exact URL match for: " + url);
}
synCtx.setProperty(RESTConstants.SELECTED_RESOURCE, filteredResources.get(i));
return filteredResources.get(i);
}
}
Expand All @@ -72,6 +74,7 @@ public Resource findResource(MessageContext synCtx, Collection<Resource> resourc
if (log.isDebugEnabled()) {
log.debug("Found path match for: " + url + " with matching length: " + maxLength);
}
synCtx.setProperty(RESTConstants.SELECTED_RESOURCE, matchedResource);
return matchedResource;
}

Expand All @@ -80,6 +83,7 @@ public Resource findResource(MessageContext synCtx, Collection<Resource> resourc
if (log.isDebugEnabled()) {
log.debug("Found extension match for: " + url);
}
synCtx.setProperty(RESTConstants.SELECTED_RESOURCE, filteredResources.get(i));
return filteredResources.get(i);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";

}

0 comments on commit 7f18134

Please sign in to comment.