private APIInfoDTO doGetAPIInfo(String context, String apiVersion) throws APISecurityException { APIInfoDTO apiInfoDTO = new APIInfoDTO(); ArrayList<URITemplate> uriTemplates = getAllURITemplates(context, apiVersion); apiInfoDTO.setApiName(context); apiInfoDTO.setContext(context); apiInfoDTO.setVersion(apiVersion); apiInfoDTO.setResources(new LinkedHashSet<ResourceInfoDTO>()); ResourceInfoDTO resourceInfoDTO = null; VerbInfoDTO verbInfoDTO = null; // The following map is used to retrieve already created ResourceInfoDTO rather than iterating - // the resource Set in apiInfoDTO. LinkedHashMap<String, ResourceInfoDTO> resourcesMap = new LinkedHashMap<String, ResourceInfoDTO>(); for (URITemplate uriTemplate : uriTemplates) { resourceInfoDTO = resourcesMap.get(uriTemplate.getUriTemplate()); if (null == resourceInfoDTO) { resourceInfoDTO = new ResourceInfoDTO(); resourceInfoDTO.setUrlPattern(uriTemplate.getUriTemplate()); resourceInfoDTO.setHttpVerbs(new LinkedHashSet()); apiInfoDTO.getResources().add(resourceInfoDTO); resourcesMap.put(uriTemplate.getUriTemplate(), resourceInfoDTO); } verbInfoDTO = new VerbInfoDTO(); verbInfoDTO.setHttpVerb(uriTemplate.getHTTPVerb()); verbInfoDTO.setAuthType(uriTemplate.getAuthType()); verbInfoDTO.setThrottling(uriTemplate.getThrottlingTier()); verbInfoDTO.setThrottlingConditions(uriTemplate.getThrottlingConditions()); verbInfoDTO.setConditionGroups(uriTemplate.getConditionGroups()); verbInfoDTO.setApplicableLevel(uriTemplate.getApplicableLevel()); resourceInfoDTO.getHttpVerbs().add(verbInfoDTO); } return apiInfoDTO; }
private APIInfoDTO doGetAPIInfo(String context, String apiVersion) { APIInfoDTO apiInfoDTO = new APIInfoDTO(); try { ArrayList<URITemplate> uriTemplates = getAllURITemplates(context, apiVersion); apiInfoDTO.setApiName(context); apiInfoDTO.setContext(context); apiInfoDTO.setVersion(apiVersion); apiInfoDTO.setResources(new HashSet<ResourceInfoDTO>()); ResourceInfoDTO resourceInfoDTO = null; VerbInfoDTO verbInfoDTO = null; int i = 0; for (URITemplate uriTemplate : uriTemplates) { if (resourceInfoDTO != null && resourceInfoDTO.getUrlPattern().equalsIgnoreCase(uriTemplate.getUriTemplate())) { HashSet<VerbInfoDTO> verbs = (HashSet<VerbInfoDTO>) resourceInfoDTO.getHttpVerbs(); verbInfoDTO = new VerbInfoDTO(); verbInfoDTO.setHttpVerb(uriTemplate.getHTTPVerb()); verbInfoDTO.setAuthType(uriTemplate.getAuthType()); verbs.add(verbInfoDTO); resourceInfoDTO.setHttpVerbs(verbs); apiInfoDTO.getResources().add(resourceInfoDTO); } else { resourceInfoDTO = new ResourceInfoDTO(); resourceInfoDTO.setUrlPattern(uriTemplate.getUriTemplate()); verbInfoDTO = new VerbInfoDTO(); verbInfoDTO.setHttpVerb(uriTemplate.getHTTPVerb()); verbInfoDTO.setAuthType(uriTemplate.getAuthType()); HashSet<VerbInfoDTO> httpVerbs2 = new HashSet(); httpVerbs2.add(verbInfoDTO); resourceInfoDTO.setHttpVerbs(httpVerbs2); apiInfoDTO.getResources().add(resourceInfoDTO); } } } catch (APIManagementException e) { log.error("Loading URI templates for " + context + ":" + apiVersion + " failed", e); } catch (APISecurityException e) { log.error("Loading URI templates for " + context + ":" + apiVersion + " failed", e); } return apiInfoDTO; }
/** * @param context API context of API * @param apiVersion Version of API * @param requestPath Incoming request path * @param httpMethod http method of request * @return verbInfoDTO which contains throttling tier for given resource and verb+resource key */ public VerbInfoDTO getVerbInfoDTOFromAPIData( String context, String apiVersion, String requestPath, String httpMethod) throws APISecurityException { String cacheKey = context + ':' + apiVersion; APIInfoDTO apiInfoDTO = null; if (isGatewayAPIResourceValidationEnabled) { apiInfoDTO = (APIInfoDTO) getResourceCache().get(cacheKey); } if (apiInfoDTO == null) { apiInfoDTO = doGetAPIInfo(context, apiVersion); getResourceCache().put(cacheKey, apiInfoDTO); } // Match the case where the direct api context is matched if ("/".equals(requestPath)) { String requestCacheKey = context + '/' + apiVersion + requestPath + ':' + httpMethod; // Get decision from cache. VerbInfoDTO matchingVerb = null; if (isGatewayAPIResourceValidationEnabled) { matchingVerb = (VerbInfoDTO) getResourceCache().get(requestCacheKey); } // On a cache hit if (matchingVerb != null) { matchingVerb.setRequestKey(requestCacheKey); return matchingVerb; } else { if (apiInfoDTO.getResources() != null) { for (ResourceInfoDTO resourceInfoDTO : apiInfoDTO.getResources()) { String urlPattern = resourceInfoDTO.getUrlPattern(); // If the request patch is '/', it can only be matched with a resource whose url-context // is '/*' if ("/*".equals(urlPattern)) { for (VerbInfoDTO verbDTO : resourceInfoDTO.getHttpVerbs()) { if (verbDTO.getHttpVerb().equals(httpMethod)) { // Store verb in cache getResourceCache().put(requestCacheKey, verbDTO); verbDTO.setRequestKey(requestCacheKey); return verbDTO; } } } } } } } // Remove the ending '/' from request requestPath = RESTUtils.trimTrailingSlashes(requestPath); while (requestPath.length() > 1) { String requestCacheKey = context + '/' + apiVersion + requestPath + ':' + httpMethod; // Get decision from cache. VerbInfoDTO matchingVerb = null; if (isGatewayAPIResourceValidationEnabled) { matchingVerb = (VerbInfoDTO) getResourceCache().get(requestCacheKey); } // On a cache hit if (matchingVerb != null) { matchingVerb.setRequestKey(requestCacheKey); return matchingVerb; } // On a cache miss else { for (ResourceInfoDTO resourceInfoDTO : apiInfoDTO.getResources()) { String urlPattern = resourceInfoDTO.getUrlPattern(); if (urlPattern.endsWith("/*")) { // Remove the ending '/*' urlPattern = urlPattern.substring(0, urlPattern.length() - 2); } // If the urlPattern ends with a '/', remove that as well. urlPattern = RESTUtils.trimTrailingSlashes(urlPattern); if (requestPath.endsWith(urlPattern)) { for (VerbInfoDTO verbDTO : resourceInfoDTO.getHttpVerbs()) { if (verbDTO.getHttpVerb().equals(httpMethod)) { // Store verb in cache getResourceCache().put(requestCacheKey, verbDTO); verbDTO.setRequestKey(requestCacheKey); return verbDTO; } } } } } // Remove the section after the last occurrence of the '/' character int index = requestPath.lastIndexOf('/'); requestPath = requestPath.substring(0, index <= 0 ? 0 : index); } // nothing found. return the highest level of security return null; }
public VerbInfoDTO findMatchingVerb(MessageContext synCtx) throws ResourceNotFoundException, APISecurityException { VerbInfoDTO verb = null; // This function is used by more than one handler. If on one execution of this function, it has // found and placed // the matching verb in the cache, the same can be re-used from all handlers since all handlers // share the same // MessageContext. The API_RESOURCE_CACHE_KEY property will be set in the MessageContext to // indicate that the // verb has been put into the cache. String resourceCacheKey = (String) synCtx.getProperty(APIConstants.API_RESOURCE_CACHE_KEY); if (resourceCacheKey != null) { verb = (VerbInfoDTO) getResourceCache().get(resourceCacheKey); // Cache hit if (verb != null) { if (log.isDebugEnabled()) { log.debug("Found resource in Cache for key: ".concat(resourceCacheKey)); } return verb; } if (log.isDebugEnabled()) { log.debug("Resource not found in cache for key: ".concat(resourceCacheKey)); } } String resourceString = (String) synCtx.getProperty(APIConstants.API_ELECTED_RESOURCE); String apiContext = (String) synCtx.getProperty(RESTConstants.REST_API_CONTEXT); String apiVersion = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API_VERSION); String fullRequestPath = (String) synCtx.getProperty(RESTConstants.REST_FULL_REQUEST_PATH); String apiName = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API); String requestPath = Utils.getRequestPath(synCtx, fullRequestPath, apiContext, apiVersion); if ("".equals(requestPath)) { requestPath = "/"; } if (log.isDebugEnabled()) { log.debug("Setting REST_SUB_REQUEST_PATH in msg context: ".concat(requestPath)); } synCtx.setProperty(RESTConstants.REST_SUB_REQUEST_PATH, requestPath); String httpMethod = (String) ((Axis2MessageContext) synCtx) .getAxis2MessageContext() .getProperty(Constants.Configuration.HTTP_METHOD); if (resourceString == null) { API selectedApi = synCtx.getConfiguration().getAPI(apiName); Resource selectedResource = null; if (selectedApi != null) { Resource[] selectedAPIResources = selectedApi.getResources(); Set<Resource> acceptableResources = new HashSet<Resource>(); for (Resource resource : selectedAPIResources) { // If the requesting method is OPTIONS or if the Resource contains the requesting method if (RESTConstants.METHOD_OPTIONS.equals(httpMethod) || (resource.getMethods() != null && Arrays.asList(resource.getMethods()).contains(httpMethod))) { acceptableResources.add(resource); } } if (acceptableResources.size() > 0) { for (RESTDispatcher dispatcher : RESTUtils.getDispatchers()) { Resource resource = dispatcher.findResource(synCtx, acceptableResources); if (resource != null && Arrays.asList(resource.getMethods()).contains(httpMethod)) { selectedResource = resource; break; } } } } if (selectedResource == null) { // No matching resource found. String msg = "Could not find matching resource for " + requestPath; log.error(msg); throw new ResourceNotFoundException(msg); } resourceString = selectedResource.getDispatcherHelper().getString(); resourceCacheKey = APIUtil.getResourceInfoDTOCacheKey(apiContext, apiVersion, resourceString, httpMethod); if (log.isDebugEnabled()) { log.debug("Selected Resource: ".concat(resourceString)); } // Set the elected resource synCtx.setProperty(APIConstants.API_ELECTED_RESOURCE, resourceString); } verb = (VerbInfoDTO) getResourceCache().get(resourceCacheKey); // Cache hit if (verb != null) { if (log.isDebugEnabled()) { log.debug("Got Resource from cache for key: ".concat(resourceCacheKey)); } // Set cache key in the message context so that it can be used by the subsequent handlers. synCtx.setProperty(APIConstants.API_RESOURCE_CACHE_KEY, resourceCacheKey); return verb; } if (log.isDebugEnabled()) { log.debug("Cache miss for Resource for key: ".concat(resourceCacheKey)); } String apiCacheKey = APIUtil.getAPIInfoDTOCacheKey(apiContext, apiVersion); APIInfoDTO apiInfoDTO = null; apiInfoDTO = (APIInfoDTO) getResourceCache().get(apiCacheKey); // Cache miss if (apiInfoDTO == null) { if (log.isDebugEnabled()) { log.debug("Could not find API object in cache for key: ".concat(apiCacheKey)); } apiInfoDTO = doGetAPIInfo(apiContext, apiVersion); getResourceCache().put(apiCacheKey, apiInfoDTO); } if (apiInfoDTO.getResources() != null) { for (ResourceInfoDTO resourceInfoDTO : apiInfoDTO.getResources()) { if ((resourceString.trim()).equalsIgnoreCase(resourceInfoDTO.getUrlPattern().trim())) { for (VerbInfoDTO verbDTO : resourceInfoDTO.getHttpVerbs()) { if (verbDTO.getHttpVerb().equals(httpMethod)) { if (log.isDebugEnabled()) { log.debug("Putting resource object in cache with key: ".concat(resourceCacheKey)); } verbDTO.setRequestKey(resourceCacheKey); // Store verb in cache getResourceCache().put(resourceCacheKey, verbDTO); // Set cache key in the message context so that it can be used by the subsequent // handlers. synCtx.setProperty(APIConstants.API_RESOURCE_CACHE_KEY, resourceCacheKey); return verbDTO; } } } } } return null; }
public String getResourceAuthenticationScheme( String context, String apiVersion, String requestPath, String httpMethod) { String cacheKey = context + ":" + apiVersion; APIInfoDTO apiInfoDTO = null; if (isGatewayAPIKeyValidationEnabled) { apiInfoDTO = (APIInfoDTO) resourceCache.get(cacheKey); } if (apiInfoDTO == null) { apiInfoDTO = doGetAPIInfo(context, apiVersion); resourceCache.put(cacheKey, apiInfoDTO); } // Match the case where the direct api context is matched if ("/".equals(requestPath)) { String requestCacheKey = context + "/" + apiVersion + requestPath + ":" + httpMethod; // Get decision from cache. VerbInfoDTO matchingVerb = null; if (isGatewayAPIKeyValidationEnabled) { matchingVerb = (VerbInfoDTO) resourceCache.get(requestCacheKey); } // On a cache hit if (matchingVerb != null) { return matchingVerb.getAuthType(); } else { for (ResourceInfoDTO resourceInfoDTO : apiInfoDTO.getResources()) { String urlPattern = resourceInfoDTO.getUrlPattern(); // If the request patch is '/', it can only be matched with a resource whose url-context // is '/*' if ("/*".equals(urlPattern)) { for (VerbInfoDTO verbDTO : resourceInfoDTO.getHttpVerbs()) { if (verbDTO.getHttpVerb().equals(httpMethod)) { // Store verb in cache resourceCache.put(requestCacheKey, verbDTO); return verbDTO.getAuthType(); } } } } } } // Remove the ending '/' from request requestPath = RESTUtils.trimTrailingSlashes(requestPath); while (requestPath.length() > 1) { String requestCacheKey = context + "/" + apiVersion + requestPath + ":" + httpMethod; // Get decision from cache. VerbInfoDTO matchingVerb = null; if (isGatewayAPIKeyValidationEnabled) { matchingVerb = (VerbInfoDTO) resourceCache.get(requestCacheKey); } // On a cache hit if (matchingVerb != null) { return matchingVerb.getAuthType(); } // On a cache miss else { for (ResourceInfoDTO resourceInfoDTO : apiInfoDTO.getResources()) { String urlPattern = resourceInfoDTO.getUrlPattern(); if (urlPattern.endsWith("/*")) { // Remove the ending '/*' urlPattern = urlPattern.substring(0, urlPattern.length() - 2); } // If the urlPattern ends with a '/', remove that as well. urlPattern = RESTUtils.trimTrailingSlashes(urlPattern); if (requestPath.endsWith(urlPattern)) { for (VerbInfoDTO verbDTO : resourceInfoDTO.getHttpVerbs()) { if (verbDTO.getHttpVerb().equals(httpMethod)) { // Store verb in cache resourceCache.put(requestCacheKey, verbDTO); return verbDTO.getAuthType(); } } } } } // Remove the section after the last occurrence of the '/' character int index = requestPath.lastIndexOf("/"); requestPath = requestPath.substring(0, index <= 0 ? 0 : index); } // nothing found. return the highest level of security return APIConstants.NO_MATCHING_AUTH_SCHEME; }