Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2014 JBoss Inc
   *
   * 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 io.apiman.gateway.engine.policies;
 
 
 import java.util.Map;

Policy that enforces rate limits.

Author(s):
eric.wittmann@redhat.com
 
     
     private static final String NO_USER_AVAILABLE = new String();
     private static final String NO_APPLICATION_AVAILABLE = new String();
     
     private static final String DEFAULT_LIMIT_HEADER = "X-RateLimit-Limit"//$NON-NLS-1$
     private static final String DEFAULT_REMAINING_HEADER = "X-RateLimit-Remaining"//$NON-NLS-1$
     private static final String DEFAULT_RESET_HEADER = "X-RateLimit-Reset"//$NON-NLS-1$
     
    
Constructor.
 
     public RateLimitingPolicy() {
     }

    

See also:
io.apiman.gateway.engine.policy.AbstractPolicy#getConfigurationClass()
 
     @Override
         return RateLimitingConfig.class;
     }
    
    
 
     @Override
     protected void doApply(final ServiceRequest requestfinal IPolicyContext contextfinal RateLimitingConfig config,
             final IPolicyChain<ServiceRequestchain) {
         String bucketId = createBucketId(requestconfig);
         final RateBucketPeriod period = getPeriod(config);
 
         if (bucketId == ) {
             IPolicyFailureFactoryComponent failureFactory = context.getComponent(IPolicyFailureFactoryComponent.class);
             PolicyFailure failure = failureFactory.createFailure(....format("RateLimitingPolicy.NoUser")); //$NON-NLS-1$
             chain.doFailure(failure);
             return;
         }
         if (bucketId == ) {
             IPolicyFailureFactoryComponent failureFactory = context.getComponent(IPolicyFailureFactoryComponent.class);
             PolicyFailure failure = failureFactory.createFailure(....format("RateLimitingPolicy.NoApp")); //$NON-NLS-1$
             chain.doFailure(failure);
             return;
         }
         
         IRateLimiterComponent rateLimiter = context.getComponent(IRateLimiterComponent.class);
         rateLimiter.accept(bucketIdperiodconfig.getLimit(), new IAsyncResultHandler<RateLimitResponse>() {
             @Override
             public void handle(IAsyncResult<RateLimitResponseresult) {
                 if (result.isError()) {
                     chain.throwError(result.getError());
                 } else {
                     RateLimitResponse rtr = result.getResult();
                     
                     Map<StringStringresponseHeaders = new HashMap<>();
                     String limitHeader = config.getHeaderLimit();
                     if (limitHeader == null) {
                        limitHeader = ;
                    }
                    String remainingHeader = config.getHeaderRemaining();
                    if (remainingHeader == null) {
                        remainingHeader = ;
                    }
                    String resetHeader = config.getHeaderReset();
                    if (resetHeader == null) {
                        resetHeader = ;
                    }
                    responseHeaders.put(limitHeader, String.valueOf(config.getLimit()));
                    responseHeaders.put(remainingHeader, String.valueOf(rtr.getRemaining()));
                    responseHeaders.put(resetHeader, String.valueOf(rtr.getReset()));
                    if (rtr.isAccepted()) {
                        context.setAttribute("rate-limit-response-headers"responseHeaders); //$NON-NLS-1$
                        chain.doApply(request);
                    } else {
                        IPolicyFailureFactoryComponent failureFactory = context.getComponent(IPolicyFailureFactoryComponent.class);
                        PolicyFailure failure = failureFactory.createFailure(....format("RateLimitingPolicy.RateExceeded")); //$NON-NLS-1$
                        failure.getHeaders().putAll(responseHeaders);
                        failure.setResponseCode(429);
                        chain.doFailure(failure);
                    }
                }
            }
        });
    }
    
    
    @Override
    protected void doApply(ServiceResponse responseIPolicyContext contextRateLimitingConfig config,
            IPolicyChain<ServiceResponsechain) {
        Map<StringStringheaders = context.getAttribute("rate-limit-response-headers"null); //$NON-NLS-1$
        if (headers != null) {
            response.getHeaders().putAll(headers);
        }
        super.doApply(responsecontextconfigchain);
    }

    
Creates the ID of the rate bucket to use. The ID is composed differently depending on the configuration of the policy.

Parameters:
request
config
    private String createBucketId(ServiceRequest requestRateLimitingConfig config) {
        StringBuilder builder = new StringBuilder();
        if (request.getContract() == null) {
            builder.append("PUBLIC||"); //$NON-NLS-1$
            builder.append("||"); //$NON-NLS-1$
            builder.append(request.getServiceOrgId());
            builder.append("||"); //$NON-NLS-1$
            builder.append(request.getServiceId());
            builder.append("||"); //$NON-NLS-1$
            builder.append(request.getServiceVersion());
            if (config.getGranularity() == .) {
                String header = config.getUserHeader();
                if (!request.getHeaders().containsKey(header)) {
                    return ;
                }
                String user = request.getHeaders().get(header);
                builder.append("||"); //$NON-NLS-1$
                builder.append(user);
            } else if (config.getGranularity() == .) {
            } else {
                return ;
            }
        } else {
            builder.append(request.getApiKey());
            if (config.getGranularity() == .) {
                String header = config.getUserHeader();
                String user = request.getHeaders().get(header);
                if (user == null) {
                    return ;
                } else {
                    builder.append("||USER||"); //$NON-NLS-1$
                    builder.append(request.getContract().getApplication().getOrganizationId());
                    builder.append("||"); //$NON-NLS-1$
                    builder.append(request.getContract().getApplication().getApplicationId());
                    builder.append("||"); //$NON-NLS-1$
                    builder.append(user);
                }
            } else if (config.getGranularity() == .) {
                builder.append(request.getApiKey());
                builder.append("||APP||"); //$NON-NLS-1$
                builder.append(request.getContract().getApplication().getOrganizationId());
                builder.append("||"); //$NON-NLS-1$
                builder.append(request.getContract().getApplication().getApplicationId());
            } else {
                builder.append(request.getApiKey());
                builder.append("||SERVICE||"); //$NON-NLS-1$
                builder.append(request.getContract().getService().getOrganizationId());
                builder.append("||"); //$NON-NLS-1$
                builder.append(request.getContract().getService().getServiceId());
            }
        }
        return builder.toString();
    }

    
Gets the appropriate bucket period from the config.

Parameters:
config
    private RateBucketPeriod getPeriod(RateLimitingConfig config) {
        RateLimitingPeriod period = config.getPeriod();
        switch (period) {
        case :
            return .;
        case :
            return .;
        case :
            return .;
        case :
            return .;
        case :
            return .;
        case :
            return .;
        default:
            return .;
        }
    }
New to GrepCode? Check out our FAQ X