diff --git a/remora-control/README.md b/remora-control/README.md index 5570120..c1b00a4 100644 --- a/remora-control/README.md +++ b/remora-control/README.md @@ -692,6 +692,8 @@ Expected response: { "filterName" : "ingnoredStreams", "filterClass" : "class com.jkoolcloud.remora.filters.ClassNameFilter", + "invokeCount" : 1001, + "excludeCount" : 1, "properties" : {"mode" : "EXCLUDE", "regex" : false, "classNames" : ["java.net.SocketInputStream","java.util.jar.JarVerifier$VerifierStream"] @@ -700,6 +702,8 @@ Expected response: { "filterName" : "ingnoredMysqlStreams", "filterClass" : "class com.jkoolcloud.remora.filters.ClassNameFilter", + "invokeCount" : 1231, + "excludeCount" : 0, "properties" : {"mode" : "EXCLUDE", "regex" : true, "classNames" : ["com\.mysql.*"] diff --git a/remora-control/src/main/java/com/jkoolcloud/remora/takes/TKFilters.java b/remora-control/src/main/java/com/jkoolcloud/remora/takes/TKFilters.java index cb856cb..9ba74da 100644 --- a/remora-control/src/main/java/com/jkoolcloud/remora/takes/TKFilters.java +++ b/remora-control/src/main/java/com/jkoolcloud/remora/takes/TKFilters.java @@ -28,22 +28,25 @@ import org.takes.rs.RsText; import com.jkoolcloud.remora.core.utils.ReflectionUtils; -import com.jkoolcloud.remora.filters.AdviceFilter; import com.jkoolcloud.remora.filters.FilterManager; +import com.jkoolcloud.remora.filters.StatisticEnabledFilter; public class TKFilters implements Take { public static final String FILTER_RESPONSE_TEMPLATE = "'{'\n" // + " \"filterName\" : \"{0}\",\n"// + " \"filterClass\" : \"{1}\",\n" // - + " \"properties\" : '{'{2}'}\n"// + + " \"invokeCount\" : {2},\n" // + + " \"excludeCount\" : {3},\n" // + + + " \"properties\" : '{'{4}'}\n"// + "'}'"; @Override public Response act(Request req) throws Exception { StringBuilder response = new StringBuilder(); response.append("["); - Map filters = FilterManager.INSTANCE.getAll(); + Map filters = FilterManager.INSTANCE.getAll(); response.append(filters.entrySet().stream().map(stringAdviceFilterEntry -> { List properties = ReflectionUtils.getConfigurableFields(stringAdviceFilterEntry.getValue()); @@ -54,7 +57,10 @@ public Response act(Request req) throws Exception { .collect(Collectors.joining(",\n")); return format(FILTER_RESPONSE_TEMPLATE, stringAdviceFilterEntry.getKey(), - stringAdviceFilterEntry.getValue().getClass(), JSONUtils.addPadding(4, collect)); + stringAdviceFilterEntry.getValue().getClass(), + JSONUtils.quote(stringAdviceFilterEntry.getValue().getInvokedCount()), + JSONUtils.quote(stringAdviceFilterEntry.getValue().getExcludedCount()), + JSONUtils.addPadding(4, collect)); }).collect(Collectors.joining(",\n"))); response.append("\n]"); return new RsText(response.toString()); diff --git a/remora-control/src/main/java/com/jkoolcloud/remora/takes/TkNewFilter.java b/remora-control/src/main/java/com/jkoolcloud/remora/takes/TkNewFilter.java index 90b0d63..130c512 100644 --- a/remora-control/src/main/java/com/jkoolcloud/remora/takes/TkNewFilter.java +++ b/remora-control/src/main/java/com/jkoolcloud/remora/takes/TkNewFilter.java @@ -28,8 +28,8 @@ import org.tinylog.TaggedLogger; import com.jkoolcloud.remora.RemoraConfig; -import com.jkoolcloud.remora.filters.AdviceFilter; import com.jkoolcloud.remora.filters.FilterManager; +import com.jkoolcloud.remora.filters.StatisticEnabledFilter; public class TkNewFilter implements Take { @@ -45,9 +45,9 @@ public Response act(Request req) throws Exception { String filterClass = TakesUtils.getValueForKey("class", body); String filterName = TakesUtils.getValueForKey("name", body); - AdviceFilter filterInstance = null; + StatisticEnabledFilter filterInstance = null; try { - filterInstance = (AdviceFilter) Class.forName(filterClass).newInstance(); + filterInstance = (StatisticEnabledFilter) Class.forName(filterClass).newInstance(); for (Field field : Arrays.asList(filterInstance.getClass().getDeclaredFields())) { if (field.isAnnotationPresent(RemoraConfig.Configurable.class)) { try { diff --git a/remora-control/src/test/java/com/jkoolcloud/remora/takes/TKFiltersTest.java b/remora-control/src/test/java/com/jkoolcloud/remora/takes/TKFiltersTest.java index 76e76e4..b022180 100644 --- a/remora-control/src/test/java/com/jkoolcloud/remora/takes/TKFiltersTest.java +++ b/remora-control/src/test/java/com/jkoolcloud/remora/takes/TKFiltersTest.java @@ -32,6 +32,10 @@ public class TKFiltersTest { @Test public void act() throws Exception { ClassNameFilter filter = new ClassNameFilter(); + for (int i = 0; i <= 1000; i++) { + filter.countInvoked(); + } + filter.countExcluded(); filter.classNames = Arrays.asList(new String[] { "a.b.c", "a.c.b", "c.b.a" }); filter.mode = AdviceFilter.Mode.INCLUDE; FilterManager.INSTANCE.add("TESTFILTER1", filter); diff --git a/remora-core/src/main/java/com/jkoolcloud/remora/RemoraConfig.java b/remora-core/src/main/java/com/jkoolcloud/remora/RemoraConfig.java index fdf2687..c8d2fae 100644 --- a/remora-core/src/main/java/com/jkoolcloud/remora/RemoraConfig.java +++ b/remora-core/src/main/java/com/jkoolcloud/remora/RemoraConfig.java @@ -36,6 +36,7 @@ import com.jkoolcloud.remora.filters.AdviceFilter; import com.jkoolcloud.remora.filters.FilterManager; +import com.jkoolcloud.remora.filters.StatisticEnabledFilter; public enum RemoraConfig { INSTANCE; @@ -160,7 +161,7 @@ protected void configureFilters() { try { String filterClass = config.getProperty(PREFIX + filterName + SUFFIX); Class aClass = Class.forName(filterClass); - AdviceFilter adviceFilter = (AdviceFilter) aClass.newInstance(); + StatisticEnabledFilter adviceFilter = (StatisticEnabledFilter) aClass.newInstance(); for (Field field : aClass.getFields()) { if (field.isAnnotationPresent(Configurable.class)) { diff --git a/remora-core/src/main/java/com/jkoolcloud/remora/filters/AdviceFilter.java b/remora-core/src/main/java/com/jkoolcloud/remora/filters/AdviceFilter.java index d469b74..5540f53 100644 --- a/remora-core/src/main/java/com/jkoolcloud/remora/filters/AdviceFilter.java +++ b/remora-core/src/main/java/com/jkoolcloud/remora/filters/AdviceFilter.java @@ -20,16 +20,29 @@ public interface AdviceFilter { + void countExcluded(); + + void countInvoked(); + boolean maches(Object thiz, Method method, Object... arguments); Mode getMode(); default boolean intercept(Object thiz, Method method, Object... arguments) { + countInvoked(); + boolean maches = maches(thiz, method, arguments); + if (getMode().equals(Mode.INCLUDE)) { - return maches(thiz, method, arguments); + if (!maches) { + countExcluded(); + } + return maches; } if (getMode().equals(Mode.EXCLUDE)) { - return !maches(thiz, method, arguments); + if (maches) { + countExcluded(); + } + return !maches; } return true; } diff --git a/remora-core/src/main/java/com/jkoolcloud/remora/filters/ClassNameFilter.java b/remora-core/src/main/java/com/jkoolcloud/remora/filters/ClassNameFilter.java index 149bc29..1b1fafd 100644 --- a/remora-core/src/main/java/com/jkoolcloud/remora/filters/ClassNameFilter.java +++ b/remora-core/src/main/java/com/jkoolcloud/remora/filters/ClassNameFilter.java @@ -22,7 +22,7 @@ import com.jkoolcloud.remora.RemoraConfig; -public class ClassNameFilter implements AdviceFilter { +public class ClassNameFilter extends StatisticEnabledFilter { @RemoraConfig.Configurable public List classNames = new ArrayList<>(); diff --git a/remora-core/src/main/java/com/jkoolcloud/remora/filters/FilterManager.java b/remora-core/src/main/java/com/jkoolcloud/remora/filters/FilterManager.java index 7712ba2..ebc9f81 100644 --- a/remora-core/src/main/java/com/jkoolcloud/remora/filters/FilterManager.java +++ b/remora-core/src/main/java/com/jkoolcloud/remora/filters/FilterManager.java @@ -24,14 +24,14 @@ public enum FilterManager { INSTANCE; - Map filters = new HashMap<>(10); + Map filters = new HashMap<>(10); public List get(List list) { return filters.entrySet().stream().filter(entry -> list.contains(entry.getKey())).map(entry -> entry.getValue()) .collect(Collectors.toList()); } - public void add(String filterName, AdviceFilter filter) { + public void add(String filterName, StatisticEnabledFilter filter) { filters.put(filterName, filter); } @@ -39,7 +39,7 @@ public AdviceFilter get(String filterName) { return filters.get(filterName); } - public Map getAll() { + public Map getAll() { return filters; } diff --git a/remora-core/src/main/java/com/jkoolcloud/remora/filters/LimitingFilter.java b/remora-core/src/main/java/com/jkoolcloud/remora/filters/LimitingFilter.java index 04334cb..0261810 100644 --- a/remora-core/src/main/java/com/jkoolcloud/remora/filters/LimitingFilter.java +++ b/remora-core/src/main/java/com/jkoolcloud/remora/filters/LimitingFilter.java @@ -17,13 +17,10 @@ package com.jkoolcloud.remora.filters; import java.lang.reflect.Method; -import java.util.concurrent.atomic.AtomicInteger; import com.jkoolcloud.remora.RemoraConfig; -public class LimitingFilter implements AdviceFilter { - AtomicInteger count = new AtomicInteger(0); - +public class LimitingFilter extends StatisticEnabledFilter { @RemoraConfig.Configurable public Integer everyNth = 2; @@ -32,11 +29,10 @@ public class LimitingFilter implements AdviceFilter { @Override public boolean maches(Object thiz, Method method, Object... arguments) { - if (count.get() == 0) { - count.set(everyNth); + if (everyNth <= 1) { + return true; } - int i = count.decrementAndGet(); - if (i == 0) { + if (getInvokedCount() % everyNth != 0) { return false; } else { return true; diff --git a/remora-core/src/main/java/com/jkoolcloud/remora/filters/StatisticEnabledFilter.java b/remora-core/src/main/java/com/jkoolcloud/remora/filters/StatisticEnabledFilter.java new file mode 100644 index 0000000..1dd731a --- /dev/null +++ b/remora-core/src/main/java/com/jkoolcloud/remora/filters/StatisticEnabledFilter.java @@ -0,0 +1,44 @@ +/* + * Copyright 2019-2020 NASTEL TECHNOLOGIES, 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 com.jkoolcloud.remora.filters; + +import java.util.concurrent.atomic.AtomicLong; + +public abstract class StatisticEnabledFilter implements AdviceFilter { + + private AtomicLong invokedCount = new AtomicLong(); + private AtomicLong excludedCount = new AtomicLong(); + + @Override + public void countExcluded() { + excludedCount.incrementAndGet(); + } + + @Override + public void countInvoked() { + invokedCount.incrementAndGet(); + } + + public long getInvokedCount() { + return invokedCount.get(); + } + + public long getExcludedCount() { + return excludedCount.get(); + } + +} diff --git a/remora-core/src/test/java/com/jkoolcloud/remora/filters/LimitingFilterTest.java b/remora-core/src/test/java/com/jkoolcloud/remora/filters/LimitingFilterTest.java index fd07414..65179a2 100644 --- a/remora-core/src/test/java/com/jkoolcloud/remora/filters/LimitingFilterTest.java +++ b/remora-core/src/test/java/com/jkoolcloud/remora/filters/LimitingFilterTest.java @@ -16,8 +16,7 @@ package com.jkoolcloud.remora.filters; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import org.junit.Test; @@ -27,16 +26,18 @@ public class LimitingFilterTest { public void maches() throws NoSuchMethodException { LimitingFilter filter = new LimitingFilter(); filter.everyNth = 5; - assertTrue(filter.maches(this, getClass().getMethod("maches"))); - assertTrue(filter.maches(this, getClass().getMethod("maches"))); - assertTrue(filter.maches(this, getClass().getMethod("maches"))); - assertTrue(filter.maches(this, getClass().getMethod("maches"))); - assertFalse(filter.maches(this, getClass().getMethod("maches"))); - assertTrue(filter.maches(this, getClass().getMethod("maches"))); - assertTrue(filter.maches(this, getClass().getMethod("maches"))); - assertTrue(filter.maches(this, getClass().getMethod("maches"))); - assertTrue(filter.maches(this, getClass().getMethod("maches"))); - assertFalse(filter.maches(this, getClass().getMethod("maches"))); + assertTrue(filter.intercept(this, getClass().getMethod("maches"))); + assertTrue(filter.intercept(this, getClass().getMethod("maches"))); + assertTrue(filter.intercept(this, getClass().getMethod("maches"))); + assertTrue(filter.intercept(this, getClass().getMethod("maches"))); + assertFalse(filter.intercept(this, getClass().getMethod("maches"))); + assertTrue(filter.intercept(this, getClass().getMethod("maches"))); + assertTrue(filter.intercept(this, getClass().getMethod("maches"))); + assertTrue(filter.intercept(this, getClass().getMethod("maches"))); + assertTrue(filter.intercept(this, getClass().getMethod("maches"))); + assertFalse(filter.intercept(this, getClass().getMethod("maches"))); + assertEquals(10, filter.getInvokedCount()); + assertEquals(2, filter.getExcludedCount()); } } \ No newline at end of file