Permalink
Browse files

Major refactoring of the code. Got rid of guard-specific annotations,…

… callbacks, interceptors, config, replacing with general versions. This makes it much simpler to add new guards. Also now there is a @GuardedBy annotation that can take a list of guards, which means that now we can have multiple guards of the same type, such as multiple rate limiters for different timescales.
  • Loading branch information...
1 parent 5474d2e commit 4e21e63803b92e382f91311a8a5ce0aa1885c8e0 @williewheeler committed May 20, 2012
Showing with 958 additions and 1,086 deletions.
  1. +9 −0 TODO
  2. +37 −0 kite-lib/src/main/java/org/zkybase/kite/AbstractGuard.java
  3. +28 −0 kite-lib/src/main/java/org/zkybase/kite/Guard.java
  4. +25 −0 kite-lib/src/main/java/org/zkybase/kite/GuardCallback.java
  5. +34 −37 kite-lib/src/main/java/org/zkybase/kite/{annotation/GuardedByThrottle.java → GuardedBy.java}
  6. +0 −37 kite-lib/src/main/java/org/zkybase/kite/annotation/GuardedByCircuitBreaker.java
  7. +0 −44 kite-lib/src/main/java/org/zkybase/kite/circuitbreaker/CircuitBreakerCallback.java
  8. +0 −77 ...lib/src/main/java/org/zkybase/kite/circuitbreaker/interceptor/AnnotationCircuitBreakerSource.java
  9. +0 −85 kite-lib/src/main/java/org/zkybase/kite/circuitbreaker/interceptor/CircuitBreakerInterceptor.java
  10. +0 −50 kite-lib/src/main/java/org/zkybase/kite/circuitbreaker/interceptor/CircuitBreakerSource.java
  11. +0 −92 kite-lib/src/main/java/org/zkybase/kite/circuitbreaker/interceptor/CircuitBreakerSourcePointcut.java
  12. +22 −67 kite-lib/src/main/java/org/zkybase/kite/config/xml/AnnotationConfigParser.java
  13. +2 −4 kite-lib/src/main/java/org/zkybase/kite/config/xml/CircuitBreakerParser.java
  14. +6 −11 .../src/main/java/org/zkybase/kite/config/xml/{ThrottleParser.java → ConcurrencyThrottleParser.java}
  15. +10 −11 ...n/java/org/zkybase/kite/config/xml/{CircuitBreakerAdviceParser.java → GuardListAdviceParser.java}
  16. +3 −4 kite-lib/src/main/java/org/zkybase/kite/config/xml/KiteNamespaceHandler.java
  17. +0 −69 kite-lib/src/main/java/org/zkybase/kite/config/xml/ThrottleAdviceParser.java
  18. +2 −4 kite-lib/src/main/java/org/zkybase/kite/{circuitbreaker → exception}/CircuitOpenException.java
  19. +4 −8 ...-lib/src/main/java/org/zkybase/kite/{throttle → exception}/ConcurrencyLimitExceededException.java
  20. +33 −41 ...rg/zkybase/kite/{throttle/interceptor/DefaultThrottleSource.java → exception/GuardException.java}
  21. +35 −0 kite-lib/src/main/java/org/zkybase/kite/exception/RateLimitExceededException.java
  22. +11 −24 kite-lib/src/main/java/org/zkybase/kite/{circuitbreaker → guard}/CircuitBreakerTemplate.java
  23. +13 −18 ...n/java/org/zkybase/kite/{throttle/ThrottleTemplate.java → guard/ConcurrencyThrottleTemplate.java}
  24. +50 −0 kite-lib/src/main/java/org/zkybase/kite/guard/RateLimitingThrottleTemplate.java
  25. +82 −0 kite-lib/src/main/java/org/zkybase/kite/interceptor/AnnotationGuardListSource.java
  26. +39 −41 ...itbreaker/interceptor/DefaultCircuitBreakerSource.java → interceptor/DefaultGuardListSource.java}
  27. +126 −0 kite-lib/src/main/java/org/zkybase/kite/interceptor/GuardListInterceptor.java
  28. +39 −47 ...va/org/zkybase/kite/{throttle/interceptor/ThrottleSource.java → interceptor/GuardListSource.java}
  29. +79 −73 ...ite/{throttle/interceptor/ThrottleSourcePointcut.java → interceptor/GuardListSourcePointcut.java}
  30. +0 −47 kite-lib/src/main/java/org/zkybase/kite/throttle/ThrottleCallback.java
  31. +0 −108 kite-lib/src/main/java/org/zkybase/kite/throttle/interceptor/AnnotationThrottleSource.java
  32. +0 −74 kite-lib/src/main/java/org/zkybase/kite/throttle/interceptor/ThrottleInterceptor.java
  33. +2 −2 kite-lib/src/main/resources/META-INF/spring.schemas
  34. +219 −0 kite-lib/src/main/resources/kite/config/kite-1.0-a3.xsd
  35. +25 −6 samples/src/main/java/org/zkybase/kite/samples/service/impl/MessageServiceImpl.java
  36. +18 −3 samples/src/main/java/org/zkybase/kite/samples/service/impl/UserServiceImpl.java
  37. +5 −2 samples/src/main/resources/spring/beans-kite.xml
View
9 TODO
@@ -0,0 +1,9 @@
+========================================================================================================================
+[DONE]
+
+Allow multiple breakers of a given type to be applied to a method. For example, we should be able to place multiple
+rate-limiting throttles on a method: one allowing 60 requests per minute, and another allowing 1800 per hour. Right now
+this isn't possible using the annotations. This would work:
+
+@GuardedBy({ "messageServiceBreaker", "perMinuteRateLimitingThrottle", "perHourRateLimitingThrottle" })
+========================================================================================================================
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010 the original author or authors.
+ *
+ * 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 org.zkybase.kite;
+
+import org.springframework.beans.factory.BeanNameAware;
+import org.springframework.jmx.export.annotation.ManagedAttribute;
+
+/**
+ * @version $Id$
+ * @author Willie Wheeler (willie.wheeler@gmail.com)
+ */
+public abstract class AbstractGuard implements Guard, BeanNameAware {
+ private String name;
+
+ @ManagedAttribute(description = "Guard name")
+ public String getName() { return name; }
+
+ /* (non-Javadoc)
+ * @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
+ */
+ @Override
+ public void setBeanName(String beanName) { this.name = beanName; }
+
+}
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2010 the original author or authors.
+ *
+ * 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 org.zkybase.kite;
+
+
+/**
+ * @author Willie Wheeler (willie.wheeler@gmail.com)
+ * @since 1.0
+ */
+public interface Guard {
+
+ String getName();
+
+ <T> T execute(GuardCallback<T> action) throws Throwable;
+}
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2010 the original author or authors.
+ *
+ * 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 org.zkybase.kite;
+
+/**
+ * @author Willie Wheeler (willie.wheeler@gmail.com)
+ * @since 1.0
+ */
+public interface GuardCallback<T> {
+
+ T doInGuard() throws Throwable;
+}
@@ -1,37 +1,34 @@
-/*
- * Copyright (c) 2010 the original author or authors.
- *
- * 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 org.zkybase.kite.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation indicating that the annotated class or method is guarded by the referenced throttle (i.e., the
- * annotation's value).
- *
- * @author Willie Wheeler
- * @since 1.0
- */
-@Target({ ElementType.METHOD })
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface GuardedByThrottle {
-
- String value() default "";
-}
+/*
+ * Copyright (c) 2010 the original author or authors.
+ *
+ * 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 org.zkybase.kite;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author Willie Wheeler (willie.wheeler@gmail.com)
+ * @since 1.0
+ */
+@Target({ ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface GuardedBy {
+
+ String[] value() default "";
+}
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2010 the original author or authors.
- *
- * 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 org.zkybase.kite.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation indicating that the annotated class or method is guarded by the referenced circuit breaker (i.e., the
- * annotation's value).
- *
- * @author Willie Wheeler
- * @since 1.0
- */
-@Target({ ElementType.METHOD })
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface GuardedByCircuitBreaker {
-
- String value() default "";
-}
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2010 the original author or authors.
- *
- * 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 org.zkybase.kite.circuitbreaker;
-
-/**
- * Callback interface for code to run using a circuit breaker. To be used with {@link CircuitBreakerTemplate}'s
- * execution methods, often as anonymous classes within a method implementation.
- *
- * @param <T>
- * result object type
- *
- * @author Willie Wheeler
- * @since 1.0
- * @see CircuitBreakerTemplate
- */
-public interface CircuitBreakerCallback<T> {
-
- /**
- * <p>
- * Gets called by CircuitBreakerTemplate.execute.
- * </p>
- * <p>
- * Allows for returning a result object created within the callback.
- * </p>
- *
- * @return a result object, or <code>null</code> if none
- * @throws Exception
- * as generated by the template method implementation
- */
- T doInCircuitBreaker() throws Exception;
-}
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2010 the original author or authors.
- *
- * 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 org.zkybase.kite.circuitbreaker.interceptor;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.core.BridgeMethodResolver;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-import org.zkybase.kite.annotation.GuardedByCircuitBreaker;
-import org.zkybase.kite.circuitbreaker.CircuitBreakerTemplate;
-
-
-// TODO Consider implementing breaker cache. See Spring's
-// AbstractFallbackTransactionAttributeSource
-
-/**
- * @version $Id: AnnotationCircuitBreakerSource.java 75 2010-03-29 07:34:59Z willie.wheeler $
- * @author Willie Wheeler
- */
-@SuppressWarnings("serial")
-public class AnnotationCircuitBreakerSource
- implements CircuitBreakerSource, BeanFactoryAware, Serializable {
-
- private static final Class<GuardedByCircuitBreaker> ANN_CLASS = GuardedByCircuitBreaker.class;
-// private static Logger log = LoggerFactory.getLogger(AnnotationCircuitBreakerSource.class);
-
- private BeanFactory beanFactory;
-
- /**
- * @param beanFactory
- */
- public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
- this.beanFactory = beanFactory;
- }
-
- public CircuitBreakerTemplate getBreaker(Method method, Class<?> targetClass) {
- Assert.notNull(method, "method can't be null");
-
- // Method may be on an interface, but we need annotations from the
- // target class. If target class is null, method will be unchanged.
- Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
-
- // If we are dealing with a method with generic parameters, find the
- // original, bridged method.
- specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
-
- CircuitBreakerTemplate breaker = parseAnnotation(specificMethod);
- return (breaker != null ? breaker : parseAnnotation(method));
- }
-
- // Based on SpringTransactionAnnotationParser. Don't worry about meta-
- // annotations here, because GuardedByCircuitBreaker is allowed only on
- // methods.
- private CircuitBreakerTemplate parseAnnotation(Method method) {
- GuardedByCircuitBreaker ann = method.getAnnotation(ANN_CLASS);
- return (ann == null ? null :
- beanFactory.getBean(ann.value(), CircuitBreakerTemplate.class));
- }
-}
Oops, something went wrong.

0 comments on commit 4e21e63

Please sign in to comment.