DATAGEODE-122 - Refactor Function annotation configuration to be smarter in resolving Apache Geode objects on startup.

Renames OnMember, OnMembers, OnRegion, OnServer and OnServers *ExecutionBeanDefinitionBuilder classes to *FunctionExecutionBeanDefinitionBuilder.
This commit is contained in:
John Blum
2018-06-12 19:42:55 -07:00
parent b02cc9803e
commit d351617ef1
32 changed files with 707 additions and 382 deletions

View File

@@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -82,8 +83,8 @@ public class FunctionGemfireAdminTemplateUnitTests {
this.template = spy(new FunctionGemfireAdminTemplate(this.mockClientCache));
when(this.template.newGemfireFunctionOperations(any(ClientCache.class)))
.thenReturn(this.mockFunctionOperations);
doReturn(this.mockFunctionOperations).when(this.template)
.newGemfireFunctionOperations(any(ClientCache.class));
when(this.mockIndex.getName()).thenReturn("MockIndex");
when(this.mockRegion.getName()).thenReturn("MockRegion");

View File

@@ -0,0 +1,98 @@
/*
* Copyright 2018 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.springframework.data.gemfire.function.config;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
/**
* Unit tests for {@link MemberBasedFunctionExecutionBeanDefinitionBuilder}.
*
* @author John Blum
* @see org.junit.Test
* @see org.mockito.Mock
* @see org.mockito.Mockito
* @see org.mockito.junit.MockitoJUnitRunner
* @see org.springframework.data.gemfire.function.config.MemberBasedFunctionExecutionBeanDefinitionBuilder
* @since 1.0.0
*/
@RunWith(MockitoJUnitRunner.class)
public class MemberBasedFunctionExecutionBeanDefinitionBuilderUnitTests {
@Mock
private FunctionExecutionConfiguration mockFunctionExecutionConfiguration;
private MemberBasedFunctionExecutionBeanDefinitionBuilder beanDefinitionBuilder;
@Before
public void setup() {
this.beanDefinitionBuilder =
new TestMemberBasedFunctionExecutionBeanDefinitionBuilder(this.mockFunctionExecutionConfiguration);
}
@Test
public void getGemfireFunctionOperationsBeanDefinitionBuilderIsSuccessful() {
when(this.mockFunctionExecutionConfiguration.getAttribute(eq("groups")))
.thenReturn(" TestGroupOne, TestGroupTwo ");
BeanDefinitionBuilder builder =
this.beanDefinitionBuilder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
assertThat(builder).isNotNull();
BeanDefinition beanDefinition = builder.getRawBeanDefinition();
assertThat(beanDefinition).isNotNull();
assertThat(beanDefinition.getBeanClassName()).isEqualTo(Object.class.getName());
assertThat(beanDefinition.getConstructorArgumentValues().getArgumentCount()).isEqualTo(1);
ConstructorArgumentValues.ValueHolder constructorArgumentValue =
beanDefinition.getConstructorArgumentValues().getArgumentValue(0, String[].class);
assertThat(constructorArgumentValue).isNotNull();
assertThat((String[]) constructorArgumentValue.getValue()).containsExactly("TestGroupOne", "TestGroupTwo");
verify(this.mockFunctionExecutionConfiguration, times(1))
.getAttribute(eq("groups"));
}
private static final class TestMemberBasedFunctionExecutionBeanDefinitionBuilder
extends MemberBasedFunctionExecutionBeanDefinitionBuilder {
private TestMemberBasedFunctionExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
super(configuration);
}
@Override
protected Class<?> getGemfireOperationsClass() {
return Object.class;
}
}
}

View File

@@ -16,40 +16,30 @@
package org.springframework.data.gemfire.function.config;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.data.gemfire.config.xml.GemfireConstants;
/**
* The ServerBasedExecutionBeanDefinitionBuilderTest class is test suite of test cases testing the contract
* and functionality of the ServerBasedExecutionBeanDefinitionBuilder class.
* Unit tests for {@link ServerBasedFunctionExecutionBeanDefinitionBuilder}.
*
* @author John Blum
* @see org.junit.Test
* @see org.mockito.Mockito
* @see org.springframework.data.gemfire.function.config.ServerBasedExecutionBeanDefinitionBuilder
* @see org.springframework.data.gemfire.function.config.ServerBasedFunctionExecutionBeanDefinitionBuilder
* @since 1.7.0
*/
public class ServerBasedExecutionBeanDefinitionBuilderTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
public class ServerBasedFunctionExecutionBeanDefinitionBuilderUnitTests {
@Test
@SuppressWarnings("unchecked")
@@ -59,11 +49,11 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
mock(FunctionExecutionConfiguration.class, "MockFunctionExecutionConfiguration");
when(mockFunctionExecutionConfiguration.getAttribute(eq("cache"))).thenReturn(null);
when(mockFunctionExecutionConfiguration.getAttribute(eq("pool"))).thenReturn(" ");
when(mockFunctionExecutionConfiguration.getAttribute(eq("pool"))).thenReturn("");
when(mockFunctionExecutionConfiguration.getFunctionExecutionInterface()).thenAnswer(invocation -> Object.class);
ServerBasedExecutionBeanDefinitionBuilder builder =
new ServerBasedExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
ServerBasedFunctionExecutionBeanDefinitionBuilder builder =
new ServerBasedFunctionExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
@Override
protected Class<?> getGemfireFunctionOperationsClass() {
@@ -71,21 +61,25 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
}
};
BeanDefinitionBuilder beanDefinitionBuilder = builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
BeanDefinitionBuilder beanDefinitionBuilder =
builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
assertThat(beanDefinitionBuilder, is(notNullValue()));
assertThat(beanDefinitionBuilder).isNotNull();
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
assertThat(beanDefinition, is(notNullValue()));
assertThat(beanDefinition.getBeanClass(), is(equalTo(Object.class)));
assertThat(String.valueOf(beanDefinition.getConstructorArgumentValues()
.getArgumentValue(0, RuntimeBeanReference.class).getValue()),
containsString(GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME));
assertThat(beanDefinition).isNotNull();
assertThat(beanDefinition.getBeanClass()).isEqualTo(Object.class);
ConstructorArgumentValues.ValueHolder constructorArgumentValue =
beanDefinition.getConstructorArgumentValues().getArgumentValue(0, RuntimeBeanReference.class);
assertThat(constructorArgumentValue).isNotNull();
assertThat(((RuntimeBeanReference) constructorArgumentValue.getValue()).getBeanName()).isEqualTo("gemfireCache");
assertThat(beanDefinition.getPropertyValues().getPropertyValue("pool")).isNull();
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("cache"));
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("pool"));
verify(mockFunctionExecutionConfiguration, times(1)).getFunctionExecutionInterface();
}
@Test
@@ -96,11 +90,10 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
mock(FunctionExecutionConfiguration.class, "MockFunctionExecutionConfiguration");
when(mockFunctionExecutionConfiguration.getAttribute(eq("cache"))).thenReturn("TestCache");
when(mockFunctionExecutionConfiguration.getAttribute(eq("pool"))).thenReturn(" ");
when(mockFunctionExecutionConfiguration.getFunctionExecutionInterface()).thenAnswer(invocation -> Object.class);
when(mockFunctionExecutionConfiguration.getAttribute(eq("pool"))).thenReturn(" ");
ServerBasedExecutionBeanDefinitionBuilder builder =
new ServerBasedExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
ServerBasedFunctionExecutionBeanDefinitionBuilder builder =
new ServerBasedFunctionExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
@Override
protected Class<?> getGemfireFunctionOperationsClass() {
@@ -108,20 +101,25 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
}
};
BeanDefinitionBuilder beanDefinitionBuilder = builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
BeanDefinitionBuilder beanDefinitionBuilder =
builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
assertThat(beanDefinitionBuilder, is(notNullValue()));
assertThat(beanDefinitionBuilder).isNotNull();
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
assertThat(beanDefinition, is(notNullValue()));
assertThat(beanDefinition.getBeanClass(), is(equalTo(Object.class)));
assertThat(String.valueOf(beanDefinition.getConstructorArgumentValues()
.getArgumentValue(0, RuntimeBeanReference.class).getValue()), containsString("TestCache"));
assertThat(beanDefinition).isNotNull();
assertThat(beanDefinition.getBeanClass()).isEqualTo(Object.class);
ConstructorArgumentValues.ValueHolder constructorArgumentValue =
beanDefinition.getConstructorArgumentValues().getArgumentValue(0, RuntimeBeanReference.class);
assertThat(constructorArgumentValue).isNotNull();
assertThat(((RuntimeBeanReference) constructorArgumentValue.getValue()).getBeanName()).isEqualTo("TestCache");
assertThat(beanDefinition.getPropertyValues().getPropertyValue("pool")).isNull();
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("cache"));
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("pool"));
verify(mockFunctionExecutionConfiguration, times(1)).getFunctionExecutionInterface();
}
@Test
@@ -133,10 +131,9 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
when(mockFunctionExecutionConfiguration.getAttribute(eq("cache"))).thenReturn(null);
when(mockFunctionExecutionConfiguration.getAttribute(eq("pool"))).thenReturn("TestPool");
when(mockFunctionExecutionConfiguration.getFunctionExecutionInterface()).thenAnswer(invocation -> Object.class);
ServerBasedExecutionBeanDefinitionBuilder builder =
new ServerBasedExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
ServerBasedFunctionExecutionBeanDefinitionBuilder builder =
new ServerBasedFunctionExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
@Override
protected Class<?> getGemfireFunctionOperationsClass() {
@@ -144,20 +141,29 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
}
};
BeanDefinitionBuilder beanDefinitionBuilder = builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
BeanDefinitionBuilder beanDefinitionBuilder =
builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
assertThat(beanDefinitionBuilder, is(notNullValue()));
assertThat(beanDefinitionBuilder).isNotNull();
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
assertThat(beanDefinition, is(notNullValue()));
assertThat(beanDefinition.getBeanClass(), is(equalTo(Object.class)));
assertThat(String.valueOf(beanDefinition.getConstructorArgumentValues()
.getArgumentValue(0, RuntimeBeanReference.class).getValue()), containsString("TestPool"));
assertThat(beanDefinition).isNotNull();
assertThat(beanDefinition.getBeanClass()).isEqualTo(Object.class);
ConstructorArgumentValues.ValueHolder constructorArgumentValue =
beanDefinition.getConstructorArgumentValues().getArgumentValue(0, RuntimeBeanReference.class);
assertThat(constructorArgumentValue).isNotNull();
assertThat(((RuntimeBeanReference) constructorArgumentValue.getValue()).getBeanName()).isEqualTo("gemfireCache");
PropertyValue propertyValue = beanDefinition.getPropertyValues().getPropertyValue("pool");
assertThat(propertyValue).isNotNull();
assertThat(((RuntimeBeanReference) propertyValue.getValue()).getBeanName()).isEqualTo("TestPool");
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("cache"));
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("pool"));
verify(mockFunctionExecutionConfiguration, times(1)).getFunctionExecutionInterface();
}
@Test
@@ -169,10 +175,9 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
when(mockFunctionExecutionConfiguration.getAttribute(eq("cache"))).thenReturn("TestCache");
when(mockFunctionExecutionConfiguration.getAttribute(eq("pool"))).thenReturn("TestPool");
when(mockFunctionExecutionConfiguration.getFunctionExecutionInterface()).thenAnswer(invocation -> Object.class);
ServerBasedExecutionBeanDefinitionBuilder builder =
new ServerBasedExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
ServerBasedFunctionExecutionBeanDefinitionBuilder builder =
new ServerBasedFunctionExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
@Override
protected Class<?> getGemfireFunctionOperationsClass() {
@@ -180,15 +185,29 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
}
};
expectedException.expect(IllegalStateException.class);
expectedException.expectCause(is(nullValue(Throwable.class)));
expectedException.expectMessage(is(equalTo("Invalid configuration for interface [java.lang.Object];"
+ " cannot specify both 'pool' and 'cache'")));
builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
BeanDefinitionBuilder beanDefinitionBuilder =
builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
assertThat(beanDefinitionBuilder).isNotNull();
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
assertThat(beanDefinition).isNotNull();
assertThat(beanDefinition.getBeanClass()).isEqualTo(Object.class);
ConstructorArgumentValues.ValueHolder constructorArgumentValue =
beanDefinition.getConstructorArgumentValues().getArgumentValue(0, RuntimeBeanReference.class);
assertThat(constructorArgumentValue).isNotNull();
assertThat(((RuntimeBeanReference) constructorArgumentValue.getValue()).getBeanName()).isEqualTo("TestCache");
PropertyValue propertyValue = beanDefinition.getPropertyValues().getPropertyValue("pool");
assertThat(propertyValue).isNotNull();
assertThat(((RuntimeBeanReference) propertyValue.getValue()).getBeanName()).isEqualTo("TestPool");
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("cache"));
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("pool"));
verify(mockFunctionExecutionConfiguration, times(1)).getFunctionExecutionInterface();
}
}

View File

@@ -12,15 +12,9 @@
*/
package org.springframework.data.gemfire.function.execution;
/**
* @author David Turanski
*
*/
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -36,79 +30,90 @@ import org.junit.Test;
import org.springframework.data.gemfire.function.annotation.FunctionId;
/**
* Unit tests for {@link GemfireFunctionProxyFactoryBean}.
*
* @author David Turanski
*
* @author John Blum
* @see org.junit.Test
* @see org.mockito.Mockito
* @see org.aopalliance.intercept.MethodInvocation
* @see org.springframework.data.gemfire.function.execution.GemfireFunctionProxyFactoryBean
*/
public class GemfireFunctionProxyFactoryBeanTests {
public class GemfireFunctionProxyFactoryBeanUnitTests {
private GemfireFunctionOperations functionOperations;
@Before
public void setUp() {
functionOperations = mock(GemfireFunctionOperations.class);
this.functionOperations = mock(GemfireFunctionOperations.class);
}
@Test
public void testInvokeAndExtractWithAnnotatedFunctionId() throws Throwable {
public void invoke() throws Throwable {
MethodInvocation invocation = new TestMethodInvocation(IFoo.class)
.withMethodNameAndArgTypes("collections",List.class);
GemfireFunctionProxyFactoryBean proxy = new GemfireFunctionProxyFactoryBean(IFoo.class,functionOperations);
when(this.functionOperations.executeAndExtract("collections",invocation.getArguments()))
.thenReturn(Arrays.asList(1, 2, 3));
MethodInvocation invocation = new TestInvocation(IFoo.class).withMethodNameAndArgTypes("oneArg",String.class);
GemfireFunctionProxyFactoryBean proxy = new GemfireFunctionProxyFactoryBean(IFoo.class, this.functionOperations);
int results = 1;
when(functionOperations.executeAndExtract("oneArg",invocation.getArguments())).thenReturn(results);
Object result = proxy.invoke(invocation);
verify(functionOperations).executeAndExtract("oneArg",invocation.getArguments());
assertTrue(result.getClass().getName(), result instanceof Integer);
assertEquals(1,result);
assertThat(result).isInstanceOf(List.class);
assertThat((List) result).hasSize(3);
verify(this.functionOperations, times(1))
.executeAndExtract("collections",invocation.getArguments());
}
@SuppressWarnings({ "rawtypes" })
@Test
public void testInvoke() throws Throwable {
public void invokeAndExtractWithAnnotatedFunctionId() throws Throwable {
MethodInvocation invocation = new TestMethodInvocation(IFoo.class)
.withMethodNameAndArgTypes("oneArg", String.class);
GemfireFunctionProxyFactoryBean proxy = new GemfireFunctionProxyFactoryBean(IFoo.class, functionOperations);
when(this.functionOperations.executeAndExtract("oneArg",invocation.getArguments())).thenReturn(1);
MethodInvocation invocation = new TestInvocation(IFoo.class).withMethodNameAndArgTypes("collections",List.class);
GemfireFunctionProxyFactoryBean proxy = new GemfireFunctionProxyFactoryBean(IFoo.class, this.functionOperations);
List results = Arrays.asList(new Integer[]{1,2,3});
when(functionOperations.executeAndExtract("collections",invocation.getArguments())).thenReturn(results);
Object result = proxy.invoke(invocation);
verify(functionOperations).executeAndExtract("collections",invocation.getArguments()); ;
assertTrue(result instanceof List);
assertEquals(3,((List<?>)result).size());
assertThat(result).describedAs(result.getClass().getName()).isInstanceOf(Integer.class);
assertThat(result).isEqualTo(1);
verify(this.functionOperations, times(1))
.executeAndExtract("oneArg", invocation.getArguments());
}
@SuppressWarnings("unused")
private static class TestMethodInvocation implements MethodInvocation {
static class TestInvocation implements MethodInvocation {
private Class<?> type;
private Class<?>[] argTypes;
private Class<?> clazz;
private String methodName;
private Object[] arguments;
public TestInvocation(Class<?> clazz) {
this.clazz = clazz;
private String methodName;
public TestMethodInvocation(Class<?> type) {
this.type = type;
}
public TestInvocation withArguments(Object ...arguments){
public TestMethodInvocation withArguments(Object ...arguments){
this.arguments = arguments;
return this;
}
public TestMethodInvocation withMethodNameAndArgTypes(String methodName,Class<?>... argTypes) {
public TestInvocation withMethodNameAndArgTypes(String methodName,Class<?>... argTypes) {
this.methodName = methodName;
this.argTypes = argTypes;
return this;
}
@@ -117,7 +122,6 @@ public class GemfireFunctionProxyFactoryBeanTests {
*/
@Override
public Object[] getArguments() {
// TODO Auto-generated method stub
return this.arguments;
}
@@ -126,7 +130,6 @@ public class GemfireFunctionProxyFactoryBeanTests {
*/
@Override
public Object proceed() throws Throwable {
// TODO Auto-generated method stub
return null;
}
@@ -135,7 +138,6 @@ public class GemfireFunctionProxyFactoryBeanTests {
*/
@Override
public Object getThis() {
// TODO Auto-generated method stub
return null;
}
@@ -144,7 +146,6 @@ public class GemfireFunctionProxyFactoryBeanTests {
*/
@Override
public AccessibleObject getStaticPart() {
// TODO Auto-generated method stub
return null;
}
@@ -153,35 +154,27 @@ public class GemfireFunctionProxyFactoryBeanTests {
*/
@Override
public Method getMethod() {
Method method = null;
try {
method = clazz.getMethod(methodName, argTypes);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return method;
}
try {
return this.type.getMethod(methodName, argTypes);
}
catch (NoSuchMethodException | SecurityException cause) {
return null;
}
}
}
@SuppressWarnings("unused")
public interface IFoo {
@FunctionId("oneArg")
public abstract Integer oneArg(String key);
Integer oneArg(String key);
public abstract Integer twoArg(String akey, String bkey);
Integer twoArg(String akey, String bkey);
public abstract List<Integer> collections(List<Integer> args);
List<Integer> collections(List<Integer> args);
public abstract Map<String, Integer> getMapWithNoArgs();
Map<String, Integer> getMapWithNoArgs();
}
}