@@ -81,7 +81,9 @@ dependencies {
|
|||||||
|
|
||||||
// Although Mifos (at the time of writing) doesn't have any compile time dep. on this,
|
// Although Mifos (at the time of writing) doesn't have any compile time dep. on this,
|
||||||
// it's useful to have this for the Spring Boot TestRestTemplate http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-rest-templates-test-utility
|
// it's useful to have this for the Spring Boot TestRestTemplate http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-rest-templates-test-utility
|
||||||
[group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3.5']
|
[group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3.5'],
|
||||||
|
// Once we've switched to Java 8 this dep can be removed.
|
||||||
|
[group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.0']
|
||||||
)
|
)
|
||||||
testCompile 'junit:junit:4.11',
|
testCompile 'junit:junit:4.11',
|
||||||
'junit:junit-dep:4.11',
|
'junit:junit-dep:4.11',
|
||||||
|
|||||||
@@ -81,7 +81,9 @@ dependencies {
|
|||||||
|
|
||||||
// Although Mifos (at the time of writing) doesn't have any compile time dep. on this,
|
// Although Mifos (at the time of writing) doesn't have any compile time dep. on this,
|
||||||
// it's useful to have this for the Spring Boot TestRestTemplate http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-rest-templates-test-utility
|
// it's useful to have this for the Spring Boot TestRestTemplate http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-rest-templates-test-utility
|
||||||
[group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3.5']
|
[group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3.5'],
|
||||||
|
// Once we've switched to Java 8 this dep can be removed.
|
||||||
|
[group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.0']
|
||||||
)
|
)
|
||||||
testCompile 'junit:junit:4.11',
|
testCompile 'junit:junit:4.11',
|
||||||
'junit:junit-dep:4.11',
|
'junit:junit-dep:4.11',
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.commands.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the command type for the annotated class.<br/>
|
||||||
|
* <br/>
|
||||||
|
* The entity name (e.g. CLIENT, SAVINGSACCOUNT, LOANPRODUCT) and the action (e.g. CREATE, DELETE) must be given.
|
||||||
|
*
|
||||||
|
* @author Markus Geiss
|
||||||
|
* @version 1.0
|
||||||
|
* @since 15.06
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Documented
|
||||||
|
public @interface CommandType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the entity for this {@link CommandType}.
|
||||||
|
*/
|
||||||
|
String entity();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name of the action for this {@link CommandType}.
|
||||||
|
*/
|
||||||
|
String action();
|
||||||
|
}
|
||||||
+85
@@ -0,0 +1,85 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.commands.provider;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.mifosplatform.commands.annotation.CommandType;
|
||||||
|
import org.mifosplatform.commands.exception.UnsupportedCommandException;
|
||||||
|
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link CommandHandlerProvider} provides {@link NewCommandSourceHandler}s for a given entity and action.<br/>
|
||||||
|
* <br/>
|
||||||
|
* A {@link NewCommandSourceHandler} can be registered and the annotation {@link CommandType} is used to determine
|
||||||
|
* the entity and the action the handler is capable to process.
|
||||||
|
*
|
||||||
|
* @author Markus Geiss
|
||||||
|
* @version 1.0
|
||||||
|
* @since 15.06
|
||||||
|
* @see NewCommandSourceHandler
|
||||||
|
* @see CommandType
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Scope("singleton")
|
||||||
|
public class CommandHandlerProvider implements ApplicationContextAware {
|
||||||
|
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
private HashMap<String, String> registeredHandlers;
|
||||||
|
|
||||||
|
CommandHandlerProvider() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a handler for the given entity and action.<br/>
|
||||||
|
* <br/>
|
||||||
|
* Throws an {@link UnsupportedCommandException} if no handler
|
||||||
|
* for the given entity, action combination can be found.
|
||||||
|
* @param entity the entity to lookup the handler, must be given.
|
||||||
|
* @param action the action to lookup the handler, must be given.
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public NewCommandSourceHandler getHandler (@Nonnull final String entity, @Nonnull final String action) {
|
||||||
|
Preconditions.checkArgument(StringUtils.isNoneEmpty(entity), "An entity must be given!");
|
||||||
|
Preconditions.checkArgument(StringUtils.isNoneEmpty(action), "An action must be given!");
|
||||||
|
|
||||||
|
final String key = entity + "|" + action;
|
||||||
|
if (!this.registeredHandlers.containsKey(key)) {
|
||||||
|
throw new UnsupportedCommandException(key);
|
||||||
|
}
|
||||||
|
return (NewCommandSourceHandler)this.applicationContext.getBean(this.registeredHandlers.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeHandlerRegistry() {
|
||||||
|
if (this.registeredHandlers == null) {
|
||||||
|
this.registeredHandlers = new HashMap<>();
|
||||||
|
|
||||||
|
final String[] commandHandlerBeans = this.applicationContext.getBeanNamesForAnnotation(CommandType.class);
|
||||||
|
if (ArrayUtils.isNotEmpty(commandHandlerBeans)) {
|
||||||
|
for (final String commandHandlerName : commandHandlerBeans) {
|
||||||
|
final CommandType commandType = this.applicationContext.getType(commandHandlerName).getAnnotation(CommandType.class);
|
||||||
|
this.registeredHandlers.put(commandType.entity() + "|" + commandType.action(), commandHandlerName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
this.applicationContext = applicationContext;
|
||||||
|
this.initializeHandlerRegistry();
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
-1
@@ -14,6 +14,7 @@ import org.mifosplatform.commands.domain.CommandWrapper;
|
|||||||
import org.mifosplatform.commands.exception.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
|
import org.mifosplatform.commands.exception.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
|
||||||
import org.mifosplatform.commands.exception.UnsupportedCommandException;
|
import org.mifosplatform.commands.exception.UnsupportedCommandException;
|
||||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||||
|
import org.mifosplatform.commands.provider.CommandHandlerProvider;
|
||||||
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
|
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
@@ -38,12 +39,14 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
|||||||
private final ToApiJsonSerializer<CommandProcessingResult> toApiResultJsonSerializer;
|
private final ToApiJsonSerializer<CommandProcessingResult> toApiResultJsonSerializer;
|
||||||
private CommandSourceRepository commandSourceRepository;
|
private CommandSourceRepository commandSourceRepository;
|
||||||
private final ConfigurationDomainService configurationDomainService;
|
private final ConfigurationDomainService configurationDomainService;
|
||||||
|
private final CommandHandlerProvider commandHandlerProvider;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public SynchronousCommandProcessingService(final PlatformSecurityContext context, final ApplicationContext applicationContext,
|
public SynchronousCommandProcessingService(final PlatformSecurityContext context, final ApplicationContext applicationContext,
|
||||||
final ToApiJsonSerializer<Map<String, Object>> toApiJsonSerializer,
|
final ToApiJsonSerializer<Map<String, Object>> toApiJsonSerializer,
|
||||||
final ToApiJsonSerializer<CommandProcessingResult> toApiResultJsonSerializer,
|
final ToApiJsonSerializer<CommandProcessingResult> toApiResultJsonSerializer,
|
||||||
final CommandSourceRepository commandSourceRepository, final ConfigurationDomainService configurationDomainService) {
|
final CommandSourceRepository commandSourceRepository, final ConfigurationDomainService configurationDomainService,
|
||||||
|
final CommandHandlerProvider commandHandlerProvider) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.applicationContext = applicationContext;
|
this.applicationContext = applicationContext;
|
||||||
@@ -52,6 +55,7 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
|||||||
this.commandSourceRepository = commandSourceRepository;
|
this.commandSourceRepository = commandSourceRepository;
|
||||||
this.commandSourceRepository = commandSourceRepository;
|
this.commandSourceRepository = commandSourceRepository;
|
||||||
this.configurationDomainService = configurationDomainService;
|
this.configurationDomainService = configurationDomainService;
|
||||||
|
this.commandHandlerProvider = commandHandlerProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -62,6 +66,10 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
|||||||
final boolean rollbackTransaction = this.configurationDomainService.isMakerCheckerEnabledForTask(wrapper.taskPermissionName());
|
final boolean rollbackTransaction = this.configurationDomainService.isMakerCheckerEnabledForTask(wrapper.taskPermissionName());
|
||||||
|
|
||||||
final NewCommandSourceHandler handler = findCommandHandler(wrapper);
|
final NewCommandSourceHandler handler = findCommandHandler(wrapper);
|
||||||
|
|
||||||
|
// TODO remove line 64 and uncomment following statement once all handlers are refactored
|
||||||
|
// final NewCommandSourceHandler handler = this.commandHandlerProvider.getHandler(wrapper.entityName(), wrapper.actionName());
|
||||||
|
|
||||||
final CommandProcessingResult result = handler.processCommand(command);
|
final CommandProcessingResult result = handler.processCommand(command);
|
||||||
|
|
||||||
final AppUser maker = this.context.authenticatedUser(wrapper);
|
final AppUser maker = this.context.authenticatedUser(wrapper);
|
||||||
@@ -124,6 +132,8 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
|||||||
.withEntityId(commandSourceResult.getResourceId()).build();
|
.withEntityId(commandSourceResult.getResourceId()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO remove this method once all handlers are refactored
|
||||||
|
@Deprecated
|
||||||
private NewCommandSourceHandler findCommandHandler(final CommandWrapper wrapper) {
|
private NewCommandSourceHandler findCommandHandler(final CommandWrapper wrapper) {
|
||||||
NewCommandSourceHandler handler = null;
|
NewCommandSourceHandler handler = null;
|
||||||
|
|
||||||
|
|||||||
+3
@@ -5,7 +5,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.portfolio.client.handler;
|
package org.mifosplatform.portfolio.client.handler;
|
||||||
|
|
||||||
|
import org.mifosplatform.commands.annotation.CommandType;
|
||||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||||
|
import org.mifosplatform.commands.provider.CommandHandlerProvider;
|
||||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
import org.mifosplatform.portfolio.client.service.ClientWritePlatformService;
|
import org.mifosplatform.portfolio.client.service.ClientWritePlatformService;
|
||||||
@@ -14,6 +16,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@CommandType(entity = "CLIENT", action = "CREATE")
|
||||||
public class CreateClientCommandHandler implements NewCommandSourceHandler {
|
public class CreateClientCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
private final ClientWritePlatformService clientWritePlatformService;
|
private final ClientWritePlatformService clientWritePlatformService;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
<context:component-scan
|
<context:component-scan
|
||||||
base-package="org.mifosplatform.accounting.*,
|
base-package="org.mifosplatform.accounting.*,
|
||||||
|
org.mifosplatform.commands.provider.*,
|
||||||
org.mifosplatform.commands.handler.*,
|
org.mifosplatform.commands.handler.*,
|
||||||
org.mifosplatform.commands.service.*,
|
org.mifosplatform.commands.service.*,
|
||||||
org.mifosplatform.commands.*,
|
org.mifosplatform.commands.*,
|
||||||
|
|||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.commands.provider;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mifosplatform.commands.exception.UnsupportedCommandException;
|
||||||
|
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||||
|
import org.mifosplatform.infrastructure.configuration.spring.TestsWithoutDatabaseAndNoJobsConfiguration;
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@WebAppConfiguration
|
||||||
|
@ContextConfiguration(classes = TestsWithoutDatabaseAndNoJobsConfiguration.class)
|
||||||
|
public class CommandHandlerProviderTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CommandHandlerProvider commandHandlerProvider;
|
||||||
|
|
||||||
|
public CommandHandlerProviderTest() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldRegisterHandler() {
|
||||||
|
try {
|
||||||
|
final Long testCommandId = 815L;
|
||||||
|
|
||||||
|
final NewCommandSourceHandler registeredHandler = this.commandHandlerProvider.getHandler("HUMAN", "UPDATE");
|
||||||
|
|
||||||
|
final CommandProcessingResult result =
|
||||||
|
registeredHandler.processCommand(
|
||||||
|
JsonCommand.fromExistingCommand(testCommandId, null, null, null, null, null, null, null, null));
|
||||||
|
Assert.assertEquals(testCommandId, result.commandId());
|
||||||
|
} catch (UnsupportedCommandException ucex) {
|
||||||
|
Assert.fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UnsupportedCommandException.class)
|
||||||
|
public void shouldThrowUnsupportedCommandException() {
|
||||||
|
this.commandHandlerProvider.getHandler("WHATEVER", "DOSOMETHING");
|
||||||
|
}
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.commands.provider;
|
||||||
|
|
||||||
|
import org.mifosplatform.commands.annotation.CommandType;
|
||||||
|
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@CommandType(entity = "HUMAN", action = "UPDATE")
|
||||||
|
public class ValidCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
|
public ValidCommandHandler() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult processCommand(JsonCommand command) {
|
||||||
|
return CommandProcessingResult.commandOnlyResult(command.commandId());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user