Skip to content

Commit

Permalink
feat: adding Javadoc
Browse files Browse the repository at this point in the history
  • Loading branch information
Changolaxtra committed Dec 14, 2023
1 parent 9458b64 commit f054adf
Show file tree
Hide file tree
Showing 13 changed files with 85 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Annotation to mark the desired rate limited methods.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface ApiRateLimited {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import java.lang.annotation.Target;
import org.springframework.context.annotation.ComponentScan;

/**
* Annotation used to enable the Component Scan of the Beans for the library package.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@ComponentScan(basePackages = "com.changolaxtra.cloud.ratelimiter")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
* Aspect component to intercept the @ApiRateLimited annotation.
*/
@Slf4j
@Aspect
@Component
Expand All @@ -22,12 +25,21 @@ public class ApiRateLimitedAspect {
private final PlanLimitStorage planLimitStorage;
private final RateLimiterConfiguration rateLimiterConfiguration;

/**
* Constructor.
*/
public ApiRateLimitedAspect(final PlanLimitStorage planLimitStorage,
final RateLimiterConfiguration rateLimiterConfiguration) {
this.planLimitStorage = planLimitStorage;
this.rateLimiterConfiguration = rateLimiterConfiguration;
}

/**
* Around pointcut to intercept the @ApiRateLimited annotation that verifies if there are tokens
* available to proceed with the request.
*
* @return the normal result of the method or HTTP 403 Entity if there are no tokens available.
*/
@Around("@annotation(com.changolaxtra.cloud.ratelimiter.annotations.ApiRateLimited)")
public Object rateLimitCheck(final ProceedingJoinPoint joinPoint) throws Throwable {
final String apiKey = getApiKey();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

/**
* Spring Boot initializer class to create the default {@link RateLimitPolicy}.
*/
@Slf4j
@Component
public class DefaultPlanLimitInitializer implements InitializingBean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

/**
* Holder class to inject the needed properties to read the API Key header and create the default
* policy.
*/
@Getter
@Configuration
public class RateLimiterConfiguration {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/**
* Spring Boot configuration class to initialize the {@link EmbeddedStorageManager}.
*/
@Slf4j
@Configuration
public class StorageManagerConfiguration {

/**
* Creates the default {@link EmbeddedStorageManager} bean to be available for injection.
*/
@Bean
public EmbeddedStorageManager.Default embeddedStorageManager() {
final EmbeddedStorageManager.Default storageManager =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,34 @@
import com.changolaxtra.cloud.ratelimiter.core.policy.RateLimitPolicy;
import lombok.EqualsAndHashCode;

/**
* Model class to store the relation between an API Key and the {@link RateLimitPolicy}.
*/
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class PlanLimitBucket {

@EqualsAndHashCode.Include
private final String apiKey;
private final TokenBucket tokenBucket;

/**
* Constructor.
*/
public PlanLimitBucket(final RateLimitPolicy rateLimitPolicy) {
this.apiKey = rateLimitPolicy.getApiKey();
this.tokenBucket = new TokenBucket(rateLimitPolicy);
}

/**
* Gets the API Key.
*/
public String getApiKey() {
return apiKey;
}

/**
* Verifies if the internal Bucket has available tokens to process the request.
*/
public boolean isAllowed() {
return tokenBucket.isAllowed();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,25 @@
import java.util.Set;
import lombok.Getter;

/**
* Root Storage model for {@link PlanLimitBucket}.
*/
@Getter
public class PlanLimitDataRoot {

private final Set<PlanLimitBucket> planLimitBuckets;

/**
* Constructor.
*/
public PlanLimitDataRoot() {
planLimitBuckets = new HashSet<>();
}

/**
* Adds a {@link PlanLimitBucket} to the root collection, if the {@link PlanLimitBucket} already
* exists in the collection it will be replaced.
*/
public boolean addPlanLimitBucket(final PlanLimitBucket planLimitBucket) {
return planLimitBuckets.add(planLimitBucket);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

import com.changolaxtra.cloud.ratelimiter.core.policy.RateLimitPolicy;

/**
* Core TokenBucket class that contains the logic to verify if there are tokens available to process
* the request.
*/
public class TokenBucket {

private final long numberOfRequests;
Expand All @@ -12,6 +16,9 @@ public class TokenBucket {
private long nextRefillTime;
private long numberOfTokenAvailable;

/**
* Constructor.
*/
public TokenBucket(final RateLimitPolicy rateLimitPolicy) {
this.maxBucketSize = rateLimitPolicy.getAllowedRequests();
this.numberOfRequests = rateLimitPolicy.getAllowedRequests();
Expand All @@ -20,6 +27,9 @@ public TokenBucket(final RateLimitPolicy rateLimitPolicy) {
this.refill();
}

/**
* Verifies if the Bucket has available tokens to process the request.
*/
public boolean isAllowed() {
return isUnlimited || processLimitedRequest();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
import lombok.Getter;
import lombok.ToString;

/**
* Model to create Limit policies that holds the configuration for the PlanLimitBucket including the
* API Key.
*/
@Getter
@Builder
@AllArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.changolaxtra.cloud.ratelimiter.exception;

/**
* {@link RuntimeException} for rate limit errors.
*/
public class RateLimitException extends RuntimeException {

public RateLimitException(final String message) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@
import org.eclipse.store.storage.embedded.types.EmbeddedStorageManager;
import org.springframework.stereotype.Repository;

/**
* Implementation of {@link PlanLimitStorage} using {@link EmbeddedStorageManager} as main storage.
*/
@Repository
public class EmbeddedPlanLimitStorage implements PlanLimitStorage {

private final EmbeddedStorageManager.Default embeddedStorageManager;

/**
* Constructor.
*/
public EmbeddedPlanLimitStorage(final EmbeddedStorageManager.Default embeddedStorageManager) {
this.embeddedStorageManager = embeddedStorageManager;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@

import com.changolaxtra.cloud.ratelimiter.core.PlanLimitBucket;

/**
* Contract for to read and write {@link PlanLimitBucket} in the storage.
*/
public interface PlanLimitStorage {

/**
* Retrieves the {@link PlanLimitBucket} using the API Key.
*/
PlanLimitBucket getPlanLimit(String apiKey);

/**
* Save or Update the {@link PlanLimitBucket} in the storage.
*/
boolean saveOrUpdate(PlanLimitBucket planLimitBucket);
}

0 comments on commit f054adf

Please sign in to comment.