You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by aw...@apache.org on 2019/04/30 08:24:34 UTC

[fineract-cn-group] branch develop updated (3fa8488 -> 91baf56)

This is an automated email from the ASF dual-hosted git repository.

awasum pushed a change to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git.


    from 3fa8488  Merge pull request #9 from Izakey/develop
     new f6c1911  FINCN-148 build with travis-ci.com and upload artifacts to Artifactory
     new 1af5beb  FINCN-148 build with travis-ci.com and upload artifacts to Artifactory
     new 91baf56  Merge pull request #10 from aasaru/artifactory

The 40 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .travis.yml                 | 30 +++++++++++++++++++
 README.md                   |  2 +-
 api/build.gradle            |  3 +-
 build.gradle                | 10 ++++++-
 component-test/build.gradle |  6 ++--
 service/build.gradle        |  5 ++--
 shared.gradle               | 17 +++++++++++
 travis.sh                   | 71 +++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 137 insertions(+), 7 deletions(-)
 create mode 100644 .travis.yml
 create mode 100755 travis.sh


[fineract-cn-group] 20/40: Merge pull request #5 from Izakey/develop

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 30c2f64551a105013a98e65764f1b7e4129d4d1f
Merge: 85c7d63 892d1db
Author: Isaac Kamga <u2...@gmail.com>
AuthorDate: Mon Apr 23 19:27:51 2018 +0100

    Merge pull request #5 from Izakey/develop
    
    Document the Group API

 service/build.gradle                               |  20 +-
 service/src/doc/asciidoc/api-docs.adoc             |  89 +++
 .../curl-request.adoc                              |   4 +
 .../http-request.adoc                              |  10 +
 .../http-response.adoc                             |   5 +
 .../httpie-request.adoc                            |   4 +
 .../should-activate-command/curl-request.adoc      |   4 +
 .../should-activate-command/http-request.adoc      |  10 +
 .../should-activate-command/http-response.adoc     |   5 +
 .../should-activate-command/httpie-request.adoc    |   4 +
 .../should-create-group/curl-request.adoc          |   4 +
 .../should-create-group/http-request.adoc          |  10 +
 .../should-create-group/http-response.adoc         |   5 +
 .../should-create-group/httpie-request.adoc        |   4 +
 .../curl-request.adoc                              |   4 +
 .../http-request.adoc                              |  10 +
 .../http-response.adoc                             |   5 +
 .../httpie-request.adoc                            |   4 +
 .../should-update-leaders/curl-request.adoc        |   4 +
 .../should-update-leaders/http-request.adoc        |  10 +
 .../should-update-leaders/http-response.adoc       |   5 +
 .../should-update-leaders/httpie-request.adoc      |   4 +
 .../should-update-members/curl-request.adoc        |   4 +
 .../should-update-members/http-request.adoc        |  10 +
 .../should-update-members/http-response.adoc       |   5 +
 .../should-update-members/httpie-request.adoc      |   4 +
 service/src/doc/html5/html5/api-docs.html          | 648 +++++++++++++++++++++
 .../org/apache/fineract/cn/group/TestGroup.java    | 335 +++++++++++
 .../fineract/cn/group/TestGroupDefinition.java     | 181 ++++++
 .../listener/GroupDefinitionEventListener.java     |  50 ++
 .../cn/group/listener/GroupEventListener.java      |  70 +++
 .../cn/group/listener/MigrationEventListener.java  |  50 ++
 .../cn/group/util/GroupDefinitionGenerator.java    |  44 ++
 .../fineract/cn/group/util/GroupGenerator.java     |  62 ++
 34 files changed, 1686 insertions(+), 1 deletion(-)


[fineract-cn-group] 33/40: running ./gradlew licenseFormat

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit b9f1f399e91c33a509e85fd1110c4aba12542b9e
Author: kengneruphine <ru...@gmail.com>
AuthorDate: Tue Aug 14 15:48:58 2018 +0100

    running ./gradlew licenseFormat
---
 .../cn/group/internal/command/UpdateGroupCommand.java  | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateGroupCommand.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateGroupCommand.java
index 5951ba3..c0a5ed9 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateGroupCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateGroupCommand.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.fineract.cn.group.internal.command;
 
 import org.apache.fineract.cn.group.api.v1.domain.Group;


[fineract-cn-group] 34/40: implementing Unit test on Group and GroupDefinition

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 4b1b30b9e40180b7f6c4005d11c342cc51ec70a1
Author: kengneruphine <ru...@gmail.com>
AuthorDate: Thu Sep 6 13:25:12 2018 +0100

    implementing Unit test on Group and GroupDefinition
---
 .../org/apache/fineract/cn/group/TestGroup.java    | 23 ++++++++++++++++
 .../fineract/cn/group/TestGroupDefinition.java     | 31 +++++++++++++++++++++-
 .../listener/GroupDefinitionEventListener.java     | 11 ++++++++
 3 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/component-test/src/main/java/org/apache/fineract/cn/group/TestGroup.java b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroup.java
index 1307d66..1b485f9 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/group/TestGroup.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroup.java
@@ -262,6 +262,29 @@ public class TestGroup {
     Assert.assertEquals(anotherEmployee.getIdentifier(), fetchedGroup.getAssignedEmployee());
   }
 
+  @Test
+  public void shouldUpdateGroup() throws Exception{
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.testSubject.createGroup(randomGroup);
+
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    randomGroup.setName(RandomStringUtils.randomAlphanumeric(256));
+
+    this.testSubject.updateGroup(randomGroup.getIdentifier(), randomGroup);
+
+    this.eventRecorder.wait(EventConstants.PUT_GROUP,randomGroup.getIdentifier());
+
+    final Group updatedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(randomGroup.getName(), updatedGroup.getName());
+
+
+  }
+
   @Configuration
   @EnableEventRecording
   @EnableFeignClients(basePackages = {"org.apache.fineract.cn.group.api.v1.client"})
diff --git a/component-test/src/main/java/org/apache/fineract/cn/group/TestGroupDefinition.java b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroupDefinition.java
index 608cf64..e7a75f0 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/group/TestGroupDefinition.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroupDefinition.java
@@ -54,6 +54,7 @@ import org.springframework.test.context.junit4.SpringRunner;
 
 @RunWith(SpringRunner.class)
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
+
 public class TestGroupDefinition {
   private static final String APP_NAME = "group-v1";
   private static final String TEST_USER = "ranefer";
@@ -92,7 +93,7 @@ public class TestGroupDefinition {
 
   @After
   public void cleanTest() {
-    TenantContextHolder.clear();
+   //TenantContextHolder.clear();
     userContext.close();
   }
 
@@ -127,6 +128,34 @@ public class TestGroupDefinition {
     Assert.assertNull(fetchedGroupDefinition.getLastModifiedOn());
   }
 
+
+  @Test
+  public void shouldUpdateGroupDefinition() throws Exception{
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final GroupDefinition updatedGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    updatedGroupDefinition.setIdentifier(randomGroupDefinition.getIdentifier());
+
+    this.testSubject.updateGroupDefinition(updatedGroupDefinition.getIdentifier(),updatedGroupDefinition);
+
+    this.eventRecorder.wait(EventConstants.PUT_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final GroupDefinition fetchedGroupDefinition = this.testSubject.findGroupDefinition(updatedGroupDefinition.getIdentifier());
+    Assert.assertNotNull(fetchedGroupDefinition);
+    Assert.assertEquals(updatedGroupDefinition.getIdentifier(), fetchedGroupDefinition.getIdentifier());
+    Assert.assertEquals(updatedGroupDefinition.getDescription(), fetchedGroupDefinition.getDescription());
+    Assert.assertEquals(updatedGroupDefinition.getMinimalSize(), fetchedGroupDefinition.getMinimalSize());
+    Assert.assertEquals(updatedGroupDefinition.getMaximalSize(), fetchedGroupDefinition.getMaximalSize());
+    Assert.assertNotNull(fetchedGroupDefinition.getCycle());
+    Assert.assertEquals(updatedGroupDefinition.getCycle().getNumberOfMeetings(), fetchedGroupDefinition.getCycle().getNumberOfMeetings());
+    Assert.assertEquals(updatedGroupDefinition.getCycle().getFrequency(), fetchedGroupDefinition.getCycle().getFrequency());
+  }
+
+
+
   @Configuration
   @EnableEventRecording
   @EnableFeignClients(basePackages = {"org.apache.fineract.cn.group.api.v1.client"})
diff --git a/component-test/src/main/java/org/apache/fineract/cn/group/listener/GroupDefinitionEventListener.java b/component-test/src/main/java/org/apache/fineract/cn/group/listener/GroupDefinitionEventListener.java
index 13dad62..42452a5 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/group/listener/GroupDefinitionEventListener.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/listener/GroupDefinitionEventListener.java
@@ -47,4 +47,15 @@ public class GroupDefinitionEventListener {
                                        final String payload) {
     this.eventRecorder.event(tenant, EventConstants.POST_GROUP_DEFINITION, payload, String.class);
   }
+
+  @JmsListener(
+          subscription = EventConstants.DESTINATION,
+          destination = EventConstants.DESTINATION,
+          selector = EventConstants.SELECTOR_PUT_GROUP_DEFINITION
+  )
+  public void onGroupDefinitionUpdated(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                                       final String payload) {
+    this.eventRecorder.event(tenant, EventConstants.PUT_GROUP_DEFINITION, payload, String.class);
+  }
+
 }


[fineract-cn-group] 31/40: modifying the implementation of updateGroupDefinition in the GroupAggregate.java file

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 7df8dc5acc9e33806ee633c3ba429f164e5cfc88
Author: kengneruphine <ru...@gmail.com>
AuthorDate: Sat Jul 7 15:10:08 2018 +0100

    modifying the implementation of updateGroupDefinition in the GroupAggregate.java file
---
 .../command/UpdateGroupDefinitionCommand.java      |  9 ++-----
 .../internal/command/handler/GroupAggregate.java   | 29 +++++++++++-----------
 .../group/rest/GroupDefinitionRestController.java  | 18 ++++++++++----
 3 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateGroupDefinitionCommand.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateGroupDefinitionCommand.java
index cb9c481..7254ba3 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateGroupDefinitionCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateGroupDefinitionCommand.java
@@ -22,19 +22,14 @@ import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
 
 public class UpdateGroupDefinitionCommand {
 
-    private final String identifier;
+
     private final GroupDefinition groupDefinition;
 
-    public UpdateGroupDefinitionCommand(final String identifier, final GroupDefinition groupDefinition) {
+    public UpdateGroupDefinitionCommand( final GroupDefinition groupDefinition) {
         super();
-        this.identifier = identifier;
         this.groupDefinition = groupDefinition;
     }
 
-    public String identifier() {
-        return this.identifier;
-    }
-
     public GroupDefinition groupDefinition() {
         return this.groupDefinition;
     }
diff --git a/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
index b4a93d6..bc631b5 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
@@ -140,19 +140,19 @@ public class GroupAggregate {
   @CommandHandler
   @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_GROUP_DEFINITION)
   public String updateDefinition(final UpdateGroupDefinitionCommand updateGroupDefinitionCommand) {
-      final GroupDefinition updatedGroupDefinition = updateGroupDefinitionCommand.groupDefinition();
-      final Cycle cycle = updatedGroupDefinition.getCycle();
-      this.groupDefinitionRepository.findByIdentifier(updateGroupDefinitionCommand.identifier())
-          .ifPresent(groupDefinitionEntity -> {
-                groupDefinitionEntity.setDescription(updatedGroupDefinition.getDescription());
-                groupDefinitionEntity.setMinimalSize(updatedGroupDefinition.getMinimalSize());
-                groupDefinitionEntity.setMaximalSize(updatedGroupDefinition.getMaximalSize());
+      final GroupDefinition groupDefinition = updateGroupDefinitionCommand.groupDefinition();
+      final Cycle cycle = groupDefinition.getCycle();
+      final GroupDefinitionEntity groupDefinitionEntity = findGroupDefinitionEntityOrThrow(groupDefinition.getIdentifier());
+
+                groupDefinitionEntity.setDescription(groupDefinition.getDescription());
+                groupDefinitionEntity.setMinimalSize(groupDefinition.getMinimalSize());
+                groupDefinitionEntity.setMaximalSize(groupDefinition.getMaximalSize());
                 groupDefinitionEntity.setNumberOfMeetings(cycle.getNumberOfMeetings());
                 groupDefinitionEntity.setFrequency(cycle.getFrequency());
                 groupDefinitionEntity.setAdjustment(cycle.getAdjustment());
                 this.groupDefinitionRepository.save(groupDefinitionEntity);
-          });
-         return updatedGroupDefinition.getIdentifier();
+
+         return groupDefinition.getIdentifier();
       }
 
   @Transactional
@@ -191,12 +191,6 @@ public class GroupAggregate {
   @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_GROUP)
   public String updateGroup(final UpdateGroupCommand updateGroupCommand) {
       final Group group = updateGroupCommand.group();
-      //final GroupDefinitionEntity groupDefinitionEntity =
-        //      this.groupDefinitionRepository.findByIdentifier(group.getGroupDefinitionIdentifier())
-          //            .orElseThrow(
-            //                  () -> ServiceException.notFound("Group definition {0} not found.", group.getGroupDefinitionIdentifier())
-              //        );
-
       final AddressEntity savedAddress = this.addressRepository.save(AddressMapper.map(group.getAddress()));
       final GroupEntity groupEntity = findGroupEntityOrThrow(group.getIdentifier());
 
@@ -426,4 +420,9 @@ public class GroupAggregate {
         return this.groupRepository.findByIdentifier(identifier)
                 .orElseThrow(() -> ServiceException.notFound("Group ''{0}'' not found", identifier));
     }
+
+    private GroupDefinitionEntity findGroupDefinitionEntityOrThrow(String identifier) {
+        return this.groupDefinitionRepository.findByIdentifier(identifier)
+                .orElseThrow(() -> ServiceException.notFound("GroupDefinition ''{0}'' not found", identifier));
+    }
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
index 6bd9ecb..d878938 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
@@ -122,11 +122,19 @@ public class GroupDefinitionRestController {
   public
   @ResponseBody
   ResponseEntity<Void> updateGroupDefinition(@PathVariable("identifier") final String identifier, @RequestBody final GroupDefinition groupDefinition) {
-    if (this.groupDefinitionService.groupDefinitionExists(identifier)) {
-      this.commandGateway.process(new UpdateGroupDefinitionCommand(identifier, groupDefinition));
-    } else {
-      throw ServiceException.notFound("Group Definition {0} not found.", identifier);
-    }
+    this.groupDefinitionService.findByIdentifier(identifier)
+            .orElseThrow(() -> ServiceException.notFound("Group Definition {0} not found.", identifier));
+
+    this.commandGateway.process(new UpdateGroupDefinitionCommand(groupDefinition));
+
     return ResponseEntity.accepted().build();
   }
+
+    // if (this.groupDefinitionService.groupDefinitionExists(identifier)) {
+     // this.commandGateway.process(new UpdateGroupDefinitionCommand(identifier, groupDefinition));
+    //} else {
+      //throw ServiceException.notFound("Group Definition {0} not found.", identifier);
+    //}
+    //return ResponseEntity.accepted().build();
+ // }
 }


[fineract-cn-group] 30/40: modifying the implementation of updateGroupDefinition

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 9484cac9da7c7cd79f3ab41ba38784116228b546
Author: kengneruphine <ru...@gmail.com>
AuthorDate: Sat Jul 7 11:35:25 2018 +0100

    modifying the implementation of updateGroupDefinition
---
 .../internal/command/handler/GroupAggregate.java   | 32 +++++++++++-----------
 .../group/rest/GroupDefinitionRestController.java  |  2 +-
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
index 409aa66..b4a93d6 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
@@ -138,22 +138,22 @@ public class GroupAggregate {
 
   @Transactional
   @CommandHandler
-  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_GROUP)
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_GROUP_DEFINITION)
   public String updateDefinition(final UpdateGroupDefinitionCommand updateGroupDefinitionCommand) {
-    final GroupDefinition updatedGroupDefinition = updateGroupDefinitionCommand.groupDefinition();
-    final Cycle cycle = updatedGroupDefinition.getCycle();
-    this.groupDefinitionRepository.findByIdentifier(updateGroupDefinitionCommand.identifier())
-            .ifPresent(groupDefinitionEntity -> {
-              groupDefinitionEntity.setDescription(updatedGroupDefinition.getDescription());
-              groupDefinitionEntity.setMinimalSize(updatedGroupDefinition.getMinimalSize());
-              groupDefinitionEntity.setMaximalSize(updatedGroupDefinition.getMaximalSize());
-              groupDefinitionEntity.setNumberOfMeetings(cycle.getNumberOfMeetings());
-              groupDefinitionEntity.setFrequency(cycle.getFrequency());
-              groupDefinitionEntity.setAdjustment(cycle.getAdjustment());
-              this.groupDefinitionRepository.save(groupDefinitionEntity);
-            });
-    return updateGroupDefinitionCommand.identifier();
-  }
+      final GroupDefinition updatedGroupDefinition = updateGroupDefinitionCommand.groupDefinition();
+      final Cycle cycle = updatedGroupDefinition.getCycle();
+      this.groupDefinitionRepository.findByIdentifier(updateGroupDefinitionCommand.identifier())
+          .ifPresent(groupDefinitionEntity -> {
+                groupDefinitionEntity.setDescription(updatedGroupDefinition.getDescription());
+                groupDefinitionEntity.setMinimalSize(updatedGroupDefinition.getMinimalSize());
+                groupDefinitionEntity.setMaximalSize(updatedGroupDefinition.getMaximalSize());
+                groupDefinitionEntity.setNumberOfMeetings(cycle.getNumberOfMeetings());
+                groupDefinitionEntity.setFrequency(cycle.getFrequency());
+                groupDefinitionEntity.setAdjustment(cycle.getAdjustment());
+                this.groupDefinitionRepository.save(groupDefinitionEntity);
+          });
+         return updatedGroupDefinition.getIdentifier();
+      }
 
   @Transactional
   @CommandHandler
@@ -312,7 +312,7 @@ public class GroupAggregate {
 
   @Transactional
   @CommandHandler
-  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_GROUP)
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_MEETING)
   public String signOffMeeting(final SignOffMeetingCommand signOffMeetingCommand) {
     this.groupRepository.findByIdentifier(signOffMeetingCommand.groupIdentifier())
         .ifPresent(groupEntity -> {
diff --git a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
index f520273..6bd9ecb 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
@@ -121,7 +121,7 @@ public class GroupDefinitionRestController {
   )
   public
   @ResponseBody
-  ResponseEntity<Void> updateDefinition(@PathVariable("identifier") final String identifier, @RequestBody final GroupDefinition groupDefinition) {
+  ResponseEntity<Void> updateGroupDefinition(@PathVariable("identifier") final String identifier, @RequestBody final GroupDefinition groupDefinition) {
     if (this.groupDefinitionService.groupDefinitionExists(identifier)) {
       this.commandGateway.process(new UpdateGroupDefinitionCommand(identifier, groupDefinition));
     } else {


[fineract-cn-group] 26/40: adding UpdateGroupdefinition in Group aggregate

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 57e94d31668c0e23ead4921409af7441995bae28
Author: kengneruphine <ru...@gmail.com>
AuthorDate: Thu Jun 28 11:17:56 2018 +0100

    adding UpdateGroupdefinition in Group aggregate
---
 .../fineract/cn/group/api/v1/EventConstants.java   |  2 ++
 .../internal/command/handler/GroupAggregate.java   | 41 ++++++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/api/src/main/java/org/apache/fineract/cn/group/api/v1/EventConstants.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/EventConstants.java
index 435ac6d..99c5feb 100644
--- a/api/src/main/java/org/apache/fineract/cn/group/api/v1/EventConstants.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/EventConstants.java
@@ -29,6 +29,8 @@ public interface EventConstants {
 
   String POST_GROUP_DEFINITION = "post-group-definition";
   String SELECTOR_POST_GROUP_DEFINITION = SELECTOR_NAME + " = '" + POST_GROUP_DEFINITION + "'";
+  String PUT_GROUP_DEFINITION = "put-group-definition";
+  String SELECTOR_PUT_GROUP_DEFINITION = SELECTOR_NAME + " = '" + PUT_GROUP_DEFINITION + "'";
 
   String POST_GROUP = "post-group";
   String SELECTOR_POST_GROUP = SELECTOR_NAME + " = '" + POST_GROUP + "'";
diff --git a/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
index 2ddf42f..9402729 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
@@ -29,6 +29,7 @@ import org.apache.fineract.cn.group.internal.command.ActivateGroupCommand;
 import org.apache.fineract.cn.group.internal.command.CloseGroupCommand;
 import org.apache.fineract.cn.group.internal.command.CreateGroupCommand;
 import org.apache.fineract.cn.group.internal.command.CreateGroupDefinitionCommand;
+import org.apache.fineract.cn.group.internal.command.UpdateGroupDefinitionCommand;
 import org.apache.fineract.cn.group.internal.command.ReopenGroupCommand;
 import org.apache.fineract.cn.group.internal.command.SignOffMeetingCommand;
 import org.apache.fineract.cn.group.internal.command.UpdateAssignedEmployeeCommand;
@@ -53,6 +54,7 @@ import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.temporal.ChronoField;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 import org.apache.fineract.cn.api.util.UserContextHolder;
@@ -112,6 +114,45 @@ public class GroupAggregate {
 
     return groupDefinition.getIdentifier();
   }
+//
+//    @Transactional
+//    @CommandHandler
+//    @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_GROUP_DEFINITION)
+//    public String updateDefinition1(final UpdateGroupDefinitionCommand updateGroupDefinitionCommand) {
+//      final GroupDefinition updatedGroupDefinition = updateGroupDefinitionCommand.groupDefinition();
+//
+//        final Optional<GroupDefinitionEntity> groupDefinitionEntity = this.groupDefinitionRepository.findByIdentifier(updateGroupDefinitionCommand.identifier());
+//      groupDefinitionEntity.setDescription(updatedGroupDefinition.getDescription());
+//        groupDefinitionEntity.setMinimalSize(updatedGroupDefinition.getMinimalSize());
+//        groupDefinitionEntity.setMaximalSize(updatedGroupDefinition.getMaximalSize());
+//        final Cycle cycle = updatedGroupDefinition.getCycle();
+//        groupDefinitionEntity.setNumberOfMeetings(cycle.getNumberOfMeetings());
+//        groupDefinitionEntity.setFrequency(cycle.getFrequency());
+//        groupDefinitionEntity.setAdjustment(cycle.getAdjustment());
+//
+//        this.groupDefinitionRepository.save(groupDefinitionEntity);
+//
+//        return updatedGroupDefinition.getIdentifier();
+//    }
+
+  @Transactional
+  @CommandHandler
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_GROUP)
+  public String updateDefinition(final UpdateGroupDefinitionCommand updateGroupDefinitionCommand) {
+    final GroupDefinition updatedGroupDefinition = updateGroupDefinitionCommand.groupDefinition();
+    final Cycle cycle = updatedGroupDefinition.getCycle();
+    this.groupDefinitionRepository.findByIdentifier(updateGroupDefinitionCommand.identifier())
+            .ifPresent(groupDefinitionEntity -> {
+              groupDefinitionEntity.setDescription(updatedGroupDefinition.getDescription());
+              groupDefinitionEntity.setMinimalSize(updatedGroupDefinition.getMinimalSize());
+              groupDefinitionEntity.setMaximalSize(updatedGroupDefinition.getMaximalSize());
+              groupDefinitionEntity.setNumberOfMeetings(cycle.getNumberOfMeetings());
+              groupDefinitionEntity.setFrequency(cycle.getFrequency());
+              groupDefinitionEntity.setAdjustment(cycle.getAdjustment());
+              this.groupDefinitionRepository.save(groupDefinitionEntity);
+            });
+    return updateGroupDefinitionCommand.identifier();
+  }
 
   @Transactional
   @CommandHandler


[fineract-cn-group] 05/40: Merge pull request #2 from mgeiss/develop

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit c759a24270439822653b38ce01937c7899e3de32
Merge: 815fb0c c8f9390
Author: Markus Geiß <ma...@apache.org>
AuthorDate: Wed Apr 26 20:07:16 2017 +0200

    Merge pull request #2 from mgeiss/develop
    
    added path configurer to allow dots in url

 .../src/main/java/io/mifos/group/service/GroupConfiguration.java | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)


[fineract-cn-group] 02/40: Changing name of GroupManager.

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 6cc0359265164844a91ab50407136df3de6b2407
Author: myrle-krantz <mk...@mifos.org>
AuthorDate: Fri Mar 17 18:12:38 2017 +0100

    Changing name of GroupManager.
---
 HEADER                                             |  2 +-
 .../client/{GroupClient.java => GroupManager.java} |  2 +-
 build.gradle                                       |  7 +++
 .../src/main/java/io/mifos/group/TestGroup.java    | 50 +++++++++++-----------
 .../java/io/mifos/group/TestGroupDefinition.java   |  8 ++--
 shared.gradle                                      | 10 ++++-
 6 files changed, 46 insertions(+), 33 deletions(-)

diff --git a/HEADER b/HEADER
index 76f9222..4b2eadf 100644
--- a/HEADER
+++ b/HEADER
@@ -1,4 +1,4 @@
-Copyright ${year} ${name}
+Copyright ${year} ${name}.
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupClient.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupManager.java
similarity index 99%
rename from api/src/main/java/io/mifos/group/api/v1/client/GroupClient.java
rename to api/src/main/java/io/mifos/group/api/v1/client/GroupManager.java
index f1e44b9..63f2075 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupClient.java
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupManager.java
@@ -40,7 +40,7 @@ import java.util.Set;
 
 @SuppressWarnings("unused")
 @FeignClient(name="group-v1", path="/group/v1", configuration=CustomFeignClientsConfiguration.class)
-public interface GroupClient {
+public interface GroupManager {
 
   @RequestMapping(
       value = "/definitions",
diff --git a/build.gradle b/build.gradle
index b8c09e6..b30bd55 100644
--- a/build.gradle
+++ b/build.gradle
@@ -27,3 +27,10 @@ task prepareForTest {
     dependsOn publishToMavenLocal
     dependsOn gradle.includedBuild('component-test').task(':build')
 }
+
+task licenseFormat {
+    group 'all'
+    dependsOn gradle.includedBuild('api').task(':licenseFormat')
+    dependsOn gradle.includedBuild('service').task(':licenseFormat')
+    dependsOn gradle.includedBuild('component-test').task(':licenseFormat')
+}
diff --git a/component-test/src/main/java/io/mifos/group/TestGroup.java b/component-test/src/main/java/io/mifos/group/TestGroup.java
index 91110f9..caa15ed 100644
--- a/component-test/src/main/java/io/mifos/group/TestGroup.java
+++ b/component-test/src/main/java/io/mifos/group/TestGroup.java
@@ -24,7 +24,7 @@ import io.mifos.core.test.fixture.mariadb.MariaDBInitializer;
 import io.mifos.core.test.listener.EnableEventRecording;
 import io.mifos.core.test.listener.EventRecorder;
 import io.mifos.group.api.v1.EventConstants;
-import io.mifos.group.api.v1.client.GroupClient;
+import io.mifos.group.api.v1.client.GroupManager;
 import io.mifos.group.api.v1.domain.AssignedEmployeeHolder;
 import io.mifos.group.api.v1.domain.Attendee;
 import io.mifos.group.api.v1.domain.Group;
@@ -81,7 +81,7 @@ public class TestGroup {
   public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
           = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
   @Autowired
-  private GroupClient groupClient;
+  private GroupManager testSubject;
   @Autowired
   private EventRecorder eventRecorder;
 
@@ -113,17 +113,17 @@ public class TestGroup {
   public void shouldCreateGroup() throws Exception {
     final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
 
-    this.groupClient.createGroupDefinition(randomGroupDefinition);
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
 
     this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
 
     final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
 
-    this.groupClient.createGroup(randomGroup);
+    this.testSubject.createGroup(randomGroup);
 
     this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
 
-    final Group fetchedGroup = this.groupClient.findGroup(randomGroup.getIdentifier());
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
     Assert.assertEquals(randomGroup.getIdentifier(), fetchedGroup.getIdentifier());
     Assert.assertEquals(randomGroup.getGroupDefinitionIdentifier(), fetchedGroup.getGroupDefinitionIdentifier());
     Assert.assertEquals(randomGroup.getName(), fetchedGroup.getName());
@@ -143,14 +143,14 @@ public class TestGroup {
   @Test
   public void shouldActivateCommand() throws Exception {
     final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
-    this.groupClient.createGroupDefinition(randomGroupDefinition);
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
     this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
 
     final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
-    this.groupClient.createGroup(randomGroup);
+    this.testSubject.createGroup(randomGroup);
     this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
 
-    final Group fetchedGroup = this.groupClient.findGroup(randomGroup.getIdentifier());
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
     Assert.assertEquals(Group.Status.PENDING.name(), fetchedGroup.getStatus());
 
     final GroupCommand activate = new GroupCommand();
@@ -159,13 +159,13 @@ public class TestGroup {
     activate.setCreatedBy(TestGroup.TEST_USER);
     activate.setCreatedOn(ZonedDateTime.now(Clock.systemUTC()).format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
 
-    this.groupClient.processGroupCommand(randomGroup.getIdentifier(), activate);
+    this.testSubject.processGroupCommand(randomGroup.getIdentifier(), activate);
     this.eventRecorder.wait(EventConstants.ACTIVATE_GROUP, randomGroup.getIdentifier());
 
-    final Group activatedGroup = this.groupClient.findGroup(randomGroup.getIdentifier());
+    final Group activatedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
     Assert.assertEquals(Group.Status.ACTIVE.name(), activatedGroup.getStatus());
 
-    final List<GroupCommand> groupCommands = this.groupClient.fetchGroupCommands(activatedGroup.getIdentifier());
+    final List<GroupCommand> groupCommands = this.testSubject.fetchGroupCommands(activatedGroup.getIdentifier());
     Assert.assertTrue(groupCommands.size() == 1);
     final GroupCommand groupCommand = groupCommands.get(0);
     Assert.assertEquals(activate.getAction(), groupCommand.getAction());
@@ -173,7 +173,7 @@ public class TestGroup {
     Assert.assertEquals(activate.getCreatedBy(), groupCommand.getCreatedBy());
     Assert.assertNotNull(groupCommand.getCreatedOn());
 
-    final List<Meeting> meetings = this.groupClient.fetchMeetings(activatedGroup.getIdentifier(), Boolean.FALSE);
+    final List<Meeting> meetings = this.testSubject.fetchMeetings(activatedGroup.getIdentifier(), Boolean.FALSE);
     Assert.assertNotNull(meetings);
     Assert.assertEquals(randomGroupDefinition.getCycle().getNumberOfMeetings(), Integer.valueOf(meetings.size()));
 
@@ -191,37 +191,37 @@ public class TestGroup {
         .collect(Collectors.toSet())
     );
 
-    this.groupClient.closeMeeting(activatedGroup.getIdentifier(), signOffMeeting);
+    this.testSubject.closeMeeting(activatedGroup.getIdentifier(), signOffMeeting);
     this.eventRecorder.wait(EventConstants.PUT_GROUP, activatedGroup.getIdentifier());
   }
 
   @Test
   public void shouldUpdateLeaders() throws Exception {
     final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
-    this.groupClient.createGroupDefinition(randomGroupDefinition);
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
     this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
 
     final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
-    this.groupClient.createGroup(randomGroup);
+    this.testSubject.createGroup(randomGroup);
     this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
 
     final int currentLeadersSize = randomGroup.getLeaders().size();
     randomGroup.getLeaders().add(RandomStringUtils.randomAlphanumeric(32));
-    this.groupClient.updateLeaders(randomGroup.getIdentifier(), randomGroup.getLeaders());
+    this.testSubject.updateLeaders(randomGroup.getIdentifier(), randomGroup.getLeaders());
     this.eventRecorder.wait(EventConstants.PUT_GROUP, randomGroup.getIdentifier());
 
-    final Group fetchedGroup = this.groupClient.findGroup(randomGroup.getIdentifier());
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
     Assert.assertEquals((currentLeadersSize + 1), fetchedGroup.getLeaders().size());
   }
 
   @Test
   public void shouldUpdateMembers() throws Exception {
     final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
-    this.groupClient.createGroupDefinition(randomGroupDefinition);
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
     this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
 
     final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
-    this.groupClient.createGroup(randomGroup);
+    this.testSubject.createGroup(randomGroup);
     this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
 
     final int currentMembersSize = randomGroup.getMembers().size();
@@ -229,30 +229,30 @@ public class TestGroup {
         RandomStringUtils.randomAlphanumeric(32),
         RandomStringUtils.randomAlphanumeric(32)
     ));
-    this.groupClient.updateMembers(randomGroup.getIdentifier(), randomGroup.getMembers());
+    this.testSubject.updateMembers(randomGroup.getIdentifier(), randomGroup.getMembers());
     this.eventRecorder.wait(EventConstants.PUT_GROUP, randomGroup.getIdentifier());
 
-    final Group fetchedGroup = this.groupClient.findGroup(randomGroup.getIdentifier());
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
     Assert.assertEquals((currentMembersSize + 2), fetchedGroup.getMembers().size());
   }
 
   @Test
   public void shouldUpdateAssignedEmployee() throws Exception {
     final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
-    this.groupClient.createGroupDefinition(randomGroupDefinition);
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
     this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
 
     final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
-    this.groupClient.createGroup(randomGroup);
+    this.testSubject.createGroup(randomGroup);
     this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
 
     final AssignedEmployeeHolder anotherEmployee = new AssignedEmployeeHolder();
     anotherEmployee.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
 
-    this.groupClient.updateAssignedEmployee(randomGroup.getIdentifier(), anotherEmployee);
+    this.testSubject.updateAssignedEmployee(randomGroup.getIdentifier(), anotherEmployee);
     this.eventRecorder.wait(EventConstants.PUT_GROUP, randomGroup.getIdentifier());
 
-    final Group fetchedGroup = this.groupClient.findGroup(randomGroup.getIdentifier());
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
     Assert.assertEquals(anotherEmployee.getIdentifier(), fetchedGroup.getAssignedEmployee());
   }
 
diff --git a/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java b/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java
index b33ad72..18b7203 100644
--- a/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java
+++ b/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java
@@ -25,7 +25,7 @@ import io.mifos.core.test.fixture.mariadb.MariaDBInitializer;
 import io.mifos.core.test.listener.EnableEventRecording;
 import io.mifos.core.test.listener.EventRecorder;
 import io.mifos.group.api.v1.EventConstants;
-import io.mifos.group.api.v1.client.GroupClient;
+import io.mifos.group.api.v1.client.GroupManager;
 import io.mifos.group.api.v1.domain.GroupDefinition;
 import io.mifos.group.service.GroupConfiguration;
 import io.mifos.group.util.GroupDefinitionGenerator;
@@ -68,7 +68,7 @@ public class TestGroupDefinition {
           = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
 
   @Autowired
-  private GroupClient groupClient;
+  private GroupManager testSubject;
   @Autowired
   private EventRecorder eventRecorder;
 
@@ -100,11 +100,11 @@ public class TestGroupDefinition {
   @Test
   public void shouldCreateGroupDefinition() throws Exception {
     final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
-    this.groupClient.createGroupDefinition(randomGroupDefinition);
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
 
     this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
 
-    final GroupDefinition fetchedGroupDefinition = this.groupClient.findGroupDefinition(randomGroupDefinition.getIdentifier());
+    final GroupDefinition fetchedGroupDefinition = this.testSubject.findGroupDefinition(randomGroupDefinition.getIdentifier());
 
     Assert.assertEquals(randomGroupDefinition.getIdentifier(), fetchedGroupDefinition.getIdentifier());
     Assert.assertEquals(randomGroupDefinition.getDescription(), fetchedGroupDefinition.getDescription());
diff --git a/shared.gradle b/shared.gradle
index c54ad58..79a8238 100644
--- a/shared.gradle
+++ b/shared.gradle
@@ -18,8 +18,10 @@ apply plugin: 'idea'
 apply plugin: 'maven-publish'
 apply plugin: 'io.spring.dependency-management'
 
-sourceCompatibility = JavaVersion.VERSION_1_8
-targetCompatibility = JavaVersion.VERSION_1_8
+tasks.withType(JavaCompile) {
+    sourceCompatibility = JavaVersion.VERSION_1_8
+    targetCompatibility = JavaVersion.VERSION_1_8
+}
 
 repositories {
     jcenter()
@@ -49,6 +51,10 @@ dependencies {
     )
 }
 
+jar {
+    from sourceSets.main.allSource
+}
+
 license {
     header rootProject.file('../HEADER')
     strictCheck true


[fineract-cn-group] 36/40: Document Group management API for savings and loans in groups

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit f252c32b55580b544a110a177fdf3ccad9e2a48c
Author: Isaac Kamga <u2...@gmail.com>
AuthorDate: Fri Sep 7 10:18:18 2018 +0100

    Document Group management API for savings and loans in groups
---
 .gitignore                                         |   3 +
 component-test/build.gradle                        |  15 +-
 .../fineract/cn/group/AbstractGroupTest.java       |  93 +++
 .../fineract/cn/group/GroupApiDocumentation.java   | 717 +++++++++++++++++++++
 .../fineract/cn/group/SuiteTestEnvironment.java    |  45 ++
 .../org/apache/fineract/cn/group/TestGroup.java    | 105 +--
 .../fineract/cn/group/TestGroupDefinition.java     |  79 +--
 .../cn/group/util/GroupDefinitionGenerator.java    |   4 +-
 .../fineract/cn/group/util/GroupGenerator.java     |  32 +-
 9 files changed, 911 insertions(+), 182 deletions(-)

diff --git a/.gitignore b/.gitignore
index 5f934cb..728f592 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,9 @@
 .settings
 **/build/
 **/target/
+api/out/
+component-test/out/
+service/out
 
 # Ignore Gradle GUI config
 gradle-app.setting
diff --git a/component-test/build.gradle b/component-test/build.gradle
index a3a8ccb..e4edf5a 100644
--- a/component-test/build.gradle
+++ b/component-test/build.gradle
@@ -26,6 +26,7 @@ buildscript {
 
     dependencies {
         classpath ("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
+        classpath("org.asciidoctor:asciidoctor-gradle-plugin:1.5.3")
     }
 }
 
@@ -35,6 +36,7 @@ plugins {
 }
 
 apply from: '../shared.gradle'
+apply plugin: 'org.asciidoctor.convert'
 
 dependencies {
     compile(
@@ -43,14 +45,23 @@ dependencies {
             [group: 'org.apache.fineract.cn', name: 'api', version: versions.frameworkapi],
             [group: 'org.apache.fineract.cn', name: 'test', version: versions.frameworktest],
             [group: 'org.apache.fineract.cn.anubis', name: 'test', version: versions.frameworkanubis],
-            [group: 'org.springframework.boot', name: 'spring-boot-starter-test']
+            [group: 'org.springframework.boot', name: 'spring-boot-starter-test'],
+            [group: 'org.springframework.restdocs', name: 'spring-restdocs-mockmvc'],
+            [group: 'junit', name: 'junit', version: '4.12']
     )
 }
 
+asciidoctor {
+    sourceDir 'build/doc/asciidoc/'
+    outputDir 'build/doc/html5'
+    options backend: "html", doctype: "book"
+    attributes "source-highlighter": "highlightjs",
+            'snippets': file('build/doc/generated-snippets/')
+}
 publishing {
     publications {
         mavenJava(MavenPublication) {
             from components.java
         }
     }
-}
+}
\ No newline at end of file
diff --git a/component-test/src/main/java/org/apache/fineract/cn/group/AbstractGroupTest.java b/component-test/src/main/java/org/apache/fineract/cn/group/AbstractGroupTest.java
new file mode 100644
index 0000000..12d8b83
--- /dev/null
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/AbstractGroupTest.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.fineract.cn.group;
+
+import org.apache.fineract.cn.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
+import org.apache.fineract.cn.api.context.AutoUserContext;
+import org.apache.fineract.cn.group.api.v1.EventConstants;
+import org.apache.fineract.cn.group.api.v1.client.GroupManager;
+import org.apache.fineract.cn.test.listener.EnableEventRecording;
+import org.apache.fineract.cn.test.listener.EventRecorder;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.netflix.feign.EnableFeignClients;
+import org.springframework.cloud.netflix.ribbon.RibbonClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
+        classes = {AbstractGroupTest.TestConfiguration.class})
+public class AbstractGroupTest extends SuiteTestEnvironment {
+
+    @Rule
+    public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
+            = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
+    @Autowired
+    GroupManager testSubject;
+
+    @Autowired
+    EventRecorder eventRecorder;
+
+    AutoUserContext userContext;
+
+    @Before
+    public void prepTest() {
+        userContext = this.tenantApplicationSecurityEnvironment.createAutoUserContext(TEST_USER);
+    }
+
+    @After
+    public void cleanTest() {
+        userContext.close();
+    }
+
+    public boolean waitForInitialize() {
+        try {
+            return this.eventRecorder.wait(EventConstants.INITIALIZE, EventConstants.INITIALIZE);
+        } catch (final InterruptedException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    @Configuration
+    @EnableEventRecording
+    @EnableFeignClients(basePackages = {"org.apache.fineract.cn.group.api.v1.client"})
+    @RibbonClient(name = APP_NAME)
+    @Import({GroupConfiguration.class})
+    @ComponentScan("org.apache.fineract.cn.group.listener")
+    public static class TestConfiguration {
+        public TestConfiguration() {
+            super();
+        }
+
+        @Bean()
+        public Logger logger() {
+            return LoggerFactory.getLogger("test-logger");
+        }
+    }
+}
diff --git a/component-test/src/main/java/org/apache/fineract/cn/group/GroupApiDocumentation.java b/component-test/src/main/java/org/apache/fineract/cn/group/GroupApiDocumentation.java
new file mode 100644
index 0000000..1ecd27b
--- /dev/null
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/GroupApiDocumentation.java
@@ -0,0 +1,717 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.fineract.cn.group;
+
+import com.google.gson.Gson;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.fineract.cn.group.api.v1.EventConstants;
+import org.apache.fineract.cn.group.api.v1.domain.*;
+import org.apache.fineract.cn.group.util.GroupDefinitionGenerator;
+import org.apache.fineract.cn.group.util.GroupGenerator;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.restdocs.JUnitRestDocumentation;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import java.time.Clock;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
+import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
+import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
+import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+public class GroupApiDocumentation extends AbstractGroupTest {
+
+  @Rule
+  public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("build/doc/generated-snippets/test-group");
+
+  @Autowired
+  private WebApplicationContext context;
+
+  private MockMvc mockMvc;
+
+  @Before
+  public void setUp ( ) {
+
+    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
+            .apply(documentationConfiguration(this.restDocumentation))
+            .alwaysDo(document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())))
+            .build();
+  }
+
+  @Test
+  public void documentCreateGroup ( ) throws Exception {
+
+    final Cycle groupCycle = new Cycle();
+    groupCycle.setNumberOfMeetings(25);
+    groupCycle.setFrequency(Cycle.Frequency.MONTHLY.name());
+    groupCycle.setAdjustment(Cycle.Adjustment.NEXT_BUSINESS_DAY.name());
+
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    randomGroupDefinition.setIdentifier("grpDef101");
+    randomGroupDefinition.setDescription("Group Defininition 101");
+    randomGroupDefinition.setMinimalSize(Integer.valueOf(5));
+    randomGroupDefinition.setMaximalSize(Integer.valueOf(10));
+    randomGroupDefinition.setCycle(groupCycle);
+
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    Set <String> leadership = new HashSet <>();
+    leadership.add("Nditapa");
+    leadership.add("Imele");
+
+    Set <String> membership = new HashSet <>();
+    membership.add("Kamga");
+    membership.add("Ayuk");
+    membership.add("Awasum");
+
+    final Address address = new Address();
+    address.setStreet("Hospital");
+    address.setCity("Muyuka");
+    address.setRegion("SWR");
+    address.setPostalCode("8050");
+    address.setCountry("Cameroon");
+    address.setCountryCode("CM");
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    randomGroup.setIdentifier("group001");
+    randomGroup.setGroupDefinitionIdentifier(randomGroupDefinition.getIdentifier());
+    randomGroup.setName("ARPOT Group");
+    randomGroup.setOffice("Bambui");
+    randomGroup.setAssignedEmployee("Tabah Tih");
+    randomGroup.setWeekday(Group.Weekday.WEDNESDAY.getValue());
+    randomGroup.setLeaders(leadership);
+    randomGroup.setMembers(membership);
+    randomGroup.setAddress(address);
+
+    Gson serialize = new Gson();
+    this.mockMvc.perform(post("/groups")
+            .accept(MediaType.APPLICATION_JSON_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(serialize.toJson(randomGroup)))
+            .andExpect(status().isAccepted())
+            .andDo(document("document-create-group", preprocessRequest(prettyPrint()),
+                    requestFields(
+                            fieldWithPath("identifier").description("Group Id"),
+                            fieldWithPath("groupDefinitionIdentifier").description("Group definition Id"),
+                            fieldWithPath("name").description("Group's name"),
+                            fieldWithPath("leaders").type("Set<String>").description("Group's leaders"),
+                            fieldWithPath("members").type("Set<String>").description("Group's members"),
+                            fieldWithPath("office").description("Group's office"),
+                            fieldWithPath("assignedEmployee").description("Assigned Employee"),
+                            fieldWithPath("weekday").type("Integer").description("Weekday for group meeting " +
+                                    " \n + " +
+                                    " *enum* _Weekday_ { + \n" +
+                                    "    MONDAY(1), + \n" +
+                                    "    TUESDAY(2), + \n" +
+                                    "    WEDNESDAY(3), + \n" +
+                                    "    THURSDAY(4), + \n" +
+                                    "    FRIDAY(5), + \n" +
+                                    "    SATURDAY(6), + \n" +
+                                    "    SUNDAY(7) + \n " +
+                                    " } \n +"),
+                            fieldWithPath("address.street").description("Office street"),
+                            fieldWithPath("address.city").description("Office city"),
+                            fieldWithPath("address.region").description("Office region"),
+                            fieldWithPath("address.postalCode").description("Office postal code"),
+                            fieldWithPath("address.countryCode").description("Office country code"),
+                            fieldWithPath("address.country").description("Office country")
+                    )));
+  }
+
+  @Test
+  public void documentFindGroup ( ) throws Exception {
+
+    final Cycle groupCycle = new Cycle();
+    groupCycle.setNumberOfMeetings(12);
+    groupCycle.setFrequency(Cycle.Frequency.MONTHLY.name());
+    groupCycle.setAdjustment(Cycle.Adjustment.NEXT_BUSINESS_DAY.name());
+
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    randomGroupDefinition.setDescription("Group Defininition 202");
+    randomGroupDefinition.setMinimalSize(Integer.valueOf(5));
+    randomGroupDefinition.setMaximalSize(Integer.valueOf(10));
+    randomGroupDefinition.setCycle(groupCycle);
+
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    Set <String> leadership = new HashSet <>();
+    leadership.add("Ndi");
+    leadership.add("Mele");
+
+    Set <String> membership = new HashSet <>();
+    membership.add("Kamgue");
+    membership.add("Etta");
+    membership.add("Awasom");
+
+    final Address address = new Address();
+    address.setStreet("Ghana Street");
+    address.setCity("Bamenda");
+    address.setRegion("NWR");
+    address.setPostalCode("8050");
+    address.setCountry("Cameroon");
+    address.setCountryCode("CM");
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    randomGroup.setGroupDefinitionIdentifier(randomGroupDefinition.getIdentifier());
+    randomGroup.setName("SDLE Group");
+    randomGroup.setOffice("Bambui");
+    randomGroup.setAssignedEmployee("Tabah Tih");
+    randomGroup.setWeekday(Group.Weekday.SATURDAY.getValue());
+    randomGroup.setLeaders(leadership);
+    randomGroup.setMembers(membership);
+    randomGroup.setAddress(address);
+
+    this.testSubject.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    this.mockMvc.perform(get("/groups/" + randomGroup.getIdentifier())
+            .accept(MediaType.ALL_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andDo(document("document-find-group", preprocessResponse(prettyPrint()),
+                    responseFields(
+                            fieldWithPath("identifier").description("Group Id"),
+                            fieldWithPath("groupDefinitionIdentifier").description("Group definition Id"),
+                            fieldWithPath("name").description("Group's name"),
+                            fieldWithPath("leaders").type("Set<String>").description("Group's leaders"),
+                            fieldWithPath("members").type("Set<String>").description("Group's members"),
+                            fieldWithPath("office").description("Group's office"),
+                            fieldWithPath("assignedEmployee").description("Assigned Employee"),
+                            fieldWithPath("weekday").type("Integer").description("Weekday for group meeting " +
+                                    " \n + " +
+                                    " *enum* _Weekday_ { + \n" +
+                                    "    MONDAY(1), + \n" +
+                                    "    TUESDAY(2), + \n" +
+                                    "    WEDNESDAY(3), + \n" +
+                                    "    THURSDAY(4), + \n" +
+                                    "    FRIDAY(5), + \n" +
+                                    "    SATURDAY(6), + \n" +
+                                    "    SUNDAY(7) + \n " +
+                                    " } \n +"),
+                            fieldWithPath("address.street").description("Office street"),
+                            fieldWithPath("address.city").description("Office city"),
+                            fieldWithPath("address.region").description("Office region"),
+                            fieldWithPath("address.postalCode").description("Office postal code"),
+                            fieldWithPath("address.countryCode").description("Office country code"),
+                            fieldWithPath("address.country").description("Office country"),
+                            fieldWithPath("status").description("Status " +
+                                    " + \n" +
+                                    "*enum* _Status_ { + \n" +
+                                    "    PENDING, + \n" +
+                                    "    ACTIVE, + \n" +
+                                    "    CLOSED + \n" +
+                                    "  }"),
+                            fieldWithPath("createdOn").description(""),
+                            fieldWithPath("createdBy").description(""),
+                            fieldWithPath("lastModifiedOn").description(""),
+                            fieldWithPath("lastModifiedBy").description("")
+                    )));
+  }
+
+  @Test
+  public void documentUpdateGroup ( ) throws Exception {
+
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.testSubject.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    randomGroup.setName(randomGroup.getName() + "Updated");
+    randomGroup.setWeekday(Group.Weekday.SATURDAY.getValue());
+
+    Gson serialize = new Gson();
+    this.mockMvc.perform(put("/groups/" + randomGroup.getIdentifier())
+            .accept(MediaType.APPLICATION_JSON_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(serialize.toJson(randomGroup)))
+            .andExpect(status().isAccepted())
+            .andDo(document("document-update-group", preprocessRequest(prettyPrint()),
+                    requestFields(
+                            fieldWithPath("identifier").description("Group Id"),
+                            fieldWithPath("groupDefinitionIdentifier").description("Group Definition Id"),
+                            fieldWithPath("name").description("Group's name"),
+                            fieldWithPath("leaders").type("Set<String>").description("Group's leaders"),
+                            fieldWithPath("members").type("Set<String>").description("Group's members"),
+                            fieldWithPath("office").description("Group's office"),
+                            fieldWithPath("assignedEmployee").description("Assigned Employee"),
+                            fieldWithPath("weekday").type("Integer").description("Weekday for group meeting " +
+                                    " \n + " +
+                                    " *enum* _Weekday_ { + \n" +
+                                    "    MONDAY(1), + \n" +
+                                    "    TUESDAY(2), + \n" +
+                                    "    WEDNESDAY(3), + \n" +
+                                    "    THURSDAY(4), + \n" +
+                                    "    FRIDAY(5), + \n" +
+                                    "    SATURDAY(6), + \n" +
+                                    "    SUNDAY(7) + \n " +
+                                    " } \n +"),
+                            fieldWithPath("address.street").description("Office street"),
+                            fieldWithPath("address.city").description("Office city"),
+                            fieldWithPath("address.region").description("Office region"),
+                            fieldWithPath("address.postalCode").description("Office postal code"),
+                            fieldWithPath("address.countryCode").description("Office country code"),
+                            fieldWithPath("address.country").description("Office country")
+                    )));
+  }
+
+  @Test
+  public void documentActivateGroup ( ) throws Exception {
+
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.testSubject.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(Group.Status.PENDING.name(), fetchedGroup.getStatus());
+
+    final GroupCommand activate = new GroupCommand();
+    activate.setAction(GroupCommand.Action.ACTIVATE.name());
+    activate.setNote("Activate Note" + RandomStringUtils.randomAlphanumeric(3));
+    activate.setCreatedBy(SuiteTestEnvironment.TEST_USER);
+    activate.setCreatedOn(ZonedDateTime.now(Clock.systemUTC()).format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
+
+    Gson serialize = new Gson();
+    this.mockMvc.perform(post("/groups/" + randomGroup.getIdentifier() + "/commands")
+            .accept(MediaType.APPLICATION_JSON_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(serialize.toJson(activate)))
+            .andExpect(status().isAccepted())
+            .andDo(document("document-activate-group", preprocessRequest(prettyPrint()),
+                    requestFields(
+                            fieldWithPath("action").description("Action " +
+                                    "" +
+                                    "*enum* _Action_ { + \n" +
+                                    "    ACTIVATE, + \n" +
+                                    "    CLOSE, + \n" +
+                                    "    REOPEN + \n" +
+                                    "  }"),
+                            fieldWithPath("note").description("Group NOte"),
+                            fieldWithPath("createdBy").description("Assigned Employee to Group"),
+                            fieldWithPath("createdOn").type("String").description("Date when group was created")
+                    )));
+  }
+
+  @Test
+  public void documentCloseGroup ( ) throws Exception {
+
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.testSubject.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(Group.Status.PENDING.name(), fetchedGroup.getStatus());
+
+    final GroupCommand activate = new GroupCommand();
+    activate.setAction(GroupCommand.Action.ACTIVATE.name());
+    activate.setNote("Activate Note" + RandomStringUtils.randomAlphanumeric(3));
+    activate.setCreatedBy(SuiteTestEnvironment.TEST_USER);
+    activate.setCreatedOn(ZonedDateTime.now(Clock.systemUTC()).format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
+
+    this.testSubject.processGroupCommand(randomGroup.getIdentifier(), activate);
+    this.eventRecorder.wait(EventConstants.ACTIVATE_GROUP, randomGroup.getIdentifier());
+
+    final GroupCommand close = new GroupCommand();
+    close.setAction(GroupCommand.Action.CLOSE.name());
+    close.setNote("Close Note" + RandomStringUtils.randomAlphanumeric(3));
+    close.setCreatedBy(SuiteTestEnvironment.TEST_USER);
+    close.setCreatedOn(ZonedDateTime.now(Clock.systemUTC()).format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
+
+    Gson serialize = new Gson();
+    this.mockMvc.perform(post("/groups/" + fetchedGroup.getIdentifier() + "/commands")
+            .accept(MediaType.APPLICATION_JSON_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(serialize.toJson(close)))
+            .andExpect(status().isAccepted())
+            .andDo(document("document-close-group", preprocessRequest(prettyPrint()),
+                    requestFields(
+                            fieldWithPath("action").description("Action " +
+                                    "" +
+                                    "*enum* _Action_ { + \n" +
+                                    "    ACTIVATE, + \n" +
+                                    "    CLOSE, + \n" +
+                                    "    REOPEN + \n" +
+                                    "  }"),
+                            fieldWithPath("note").description("Group NOte"),
+                            fieldWithPath("createdBy").description("Assigned Employee to Group"),
+                            fieldWithPath("createdOn").type("String").description("Date when group was created")
+                    )));
+  }
+
+  @Test
+  public void documentReopenGroup ( ) throws Exception {
+
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    randomGroup.setGroupDefinitionIdentifier(randomGroupDefinition.getIdentifier());
+    this.testSubject.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(Group.Status.PENDING.name(), fetchedGroup.getStatus());
+
+    final GroupCommand activate = new GroupCommand();
+    activate.setAction(GroupCommand.Action.ACTIVATE.name());
+    activate.setNote("Activate Note" + RandomStringUtils.randomAlphanumeric(3));
+    activate.setCreatedBy(SuiteTestEnvironment.TEST_USER);
+    activate.setCreatedOn(ZonedDateTime.now(Clock.systemUTC()).format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
+
+    this.testSubject.processGroupCommand(randomGroup.getIdentifier(), activate);
+    this.eventRecorder.wait(EventConstants.ACTIVATE_GROUP, randomGroup.getIdentifier());
+
+    final GroupCommand close = new GroupCommand();
+    close.setAction(GroupCommand.Action.CLOSE.name());
+    close.setNote("Close Note" + RandomStringUtils.randomAlphanumeric(3));
+    close.setCreatedBy(SuiteTestEnvironment.TEST_USER);
+    close.setCreatedOn(ZonedDateTime.now(Clock.systemUTC()).format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
+
+    this.testSubject.processGroupCommand(randomGroup.getIdentifier(), close);
+    this.eventRecorder.wait(EventConstants.CLOSE_GROUP, randomGroup.getIdentifier());
+
+    final GroupCommand reopen = new GroupCommand();
+    reopen.setAction(GroupCommand.Action.REOPEN.name());
+    reopen.setNote("Reopen Note" + RandomStringUtils.randomAlphanumeric(3));
+    reopen.setCreatedBy(SuiteTestEnvironment.TEST_USER);
+    reopen.setCreatedOn(ZonedDateTime.now(Clock.systemUTC()).format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
+
+    Gson serialize = new Gson();
+    this.mockMvc.perform(post("/groups/" + fetchedGroup.getIdentifier() + "/commands")
+            .accept(MediaType.APPLICATION_JSON_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(serialize.toJson(reopen)))
+            .andExpect(status().isAccepted())
+            .andDo(document("document-reopen-group", preprocessRequest(prettyPrint()),
+                    requestFields(
+                            fieldWithPath("action").description("Action " +
+                                    "" +
+                                    "*enum* _Action_ { + \n" +
+                                    "    ACTIVATE, + \n" +
+                                    "    CLOSE, + \n" +
+                                    "    REOPEN + \n" +
+                                    "  }"),
+                            fieldWithPath("note").description("Group NOte"),
+                            fieldWithPath("createdBy").description("Assigned Employee to Group"),
+                            fieldWithPath("createdOn").type("String").description("Date when group was created")
+                    )));
+  }
+
+  @Test
+  public void documentGetGroupCommands ( ) throws Exception {
+
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.testSubject.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(Group.Status.PENDING.name(), fetchedGroup.getStatus());
+
+    final GroupCommand activate = new GroupCommand();
+    activate.setAction(GroupCommand.Action.ACTIVATE.name());
+    activate.setNote("Activate Note " + RandomStringUtils.randomAlphanumeric(3));
+    activate.setCreatedBy(SuiteTestEnvironment.TEST_USER);
+    activate.setCreatedOn(ZonedDateTime.now(Clock.systemUTC()).format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
+
+    this.testSubject.processGroupCommand(randomGroup.getIdentifier(), activate);
+    this.eventRecorder.wait(EventConstants.ACTIVATE_GROUP, randomGroup.getIdentifier());
+
+    final Group activatedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(Group.Status.ACTIVE.name(), activatedGroup.getStatus());
+
+    this.mockMvc.perform(get("/groups/" + activatedGroup.getIdentifier() + "/commands")
+            .accept(MediaType.ALL_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andDo(document("document-get-group-commands", preprocessResponse(prettyPrint()),
+                    responseFields(
+                            fieldWithPath("[].action").description("Action " +
+                                    "" +
+                                    "*enum* _Action_ { + \n" +
+                                    "    ACTIVATE, + \n" +
+                                    "    CLOSE, + \n" +
+                                    "    REOPEN + \n" +
+                                    "  }"),
+                            fieldWithPath("[].note").description("Group NOte"),
+                            fieldWithPath("[].createdBy").description("Assigned Employee to Group"),
+                            fieldWithPath("[].createdOn").type("String").description("Date when group was created")
+                    )));
+  }
+
+  @Test
+  public void documentUpdateLeaders ( ) throws Exception {
+
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.testSubject.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    randomGroup.getLeaders().add(RandomStringUtils.randomAlphanumeric(5));
+
+    Gson gson = new Gson();
+    this.mockMvc.perform(put("/groups/" + randomGroup.getIdentifier() + "/leaders")
+            .accept(MediaType.ALL_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(gson.toJson(randomGroup.getLeaders())))
+            .andExpect(status().isAccepted())
+            .andDo(document("document-update-leaders"));
+  }
+
+  @Test
+  public void documentUpdateMembers ( ) throws Exception {
+
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.testSubject.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    randomGroup.getMembers().addAll(Arrays.asList(
+            "Member" + RandomStringUtils.randomAlphanumeric(3),
+            "Member" + RandomStringUtils.randomAlphanumeric(3)
+    ));
+
+    Gson gson = new Gson();
+    this.mockMvc.perform(put("/groups/" + randomGroup.getIdentifier() + "/members")
+            .accept(MediaType.ALL_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(gson.toJson(randomGroup.getMembers())))
+            .andExpect(status().isAccepted())
+            .andDo(document("document-update-members"));
+  }
+
+  @Test
+  public void documentUpdateAssignedEmployee ( ) throws Exception {
+
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.testSubject.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final AssignedEmployeeHolder anotherEmployee = new AssignedEmployeeHolder();
+    anotherEmployee.setIdentifier("Emply" + RandomStringUtils.randomAlphanumeric(3));
+
+    Gson gson = new Gson();
+    this.mockMvc.perform(put("/groups/" + randomGroup.getIdentifier() + "/employee")
+            .accept(MediaType.ALL_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(gson.toJson(anotherEmployee)))
+            .andExpect(status().isAccepted())
+            .andDo(document("document-update-assigned-employee", preprocessRequest(prettyPrint()),
+                    requestFields(
+                            fieldWithPath("identifier").description("Assigned employee identifier")
+                    )));
+  }
+
+  @Test
+  public void documentFetchMeetings ( ) throws Exception {
+
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.testSubject.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(Group.Status.PENDING.name(), fetchedGroup.getStatus());
+
+    final GroupCommand activate = new GroupCommand();
+    activate.setAction(GroupCommand.Action.ACTIVATE.name());
+    activate.setNote(RandomStringUtils.randomAlphanumeric(256));
+    activate.setCreatedBy(SuiteTestEnvironment.TEST_USER);
+    activate.setCreatedOn(ZonedDateTime.now(Clock.systemUTC()).format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
+
+    this.testSubject.processGroupCommand(randomGroup.getIdentifier(), activate);
+    this.eventRecorder.wait(EventConstants.ACTIVATE_GROUP, randomGroup.getIdentifier());
+
+    final Group activatedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(Group.Status.ACTIVE.name(), activatedGroup.getStatus());
+
+    this.mockMvc.perform(get("/groups/" + activatedGroup.getIdentifier() + "/meetings")
+            .param("upcoming", Boolean.FALSE.toString())
+            .accept(MediaType.ALL_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andDo(document("document-fetch-meetings"));
+  }
+
+  @Test
+  public void documentCloseMeeting ( ) throws Exception {
+
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.testSubject.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(Group.Status.PENDING.name(), fetchedGroup.getStatus());
+
+    final GroupCommand activate = new GroupCommand();
+    activate.setAction(GroupCommand.Action.ACTIVATE.name());
+    activate.setNote(RandomStringUtils.randomAlphanumeric(256));
+    activate.setCreatedBy(SuiteTestEnvironment.TEST_USER);
+    activate.setCreatedOn(ZonedDateTime.now(Clock.systemUTC()).format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
+
+    this.testSubject.processGroupCommand(randomGroup.getIdentifier(), activate);
+    this.eventRecorder.wait(EventConstants.ACTIVATE_GROUP, randomGroup.getIdentifier());
+
+    final Group activatedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(Group.Status.ACTIVE.name(), activatedGroup.getStatus());
+
+    final List <GroupCommand> groupCommands = this.testSubject.fetchGroupCommands(activatedGroup.getIdentifier());
+    Assert.assertTrue(groupCommands.size() == 1);
+    final GroupCommand groupCommand = groupCommands.get(0);
+    Assert.assertEquals(activate.getAction(), groupCommand.getAction());
+    Assert.assertEquals(activate.getNote(), groupCommand.getNote());
+    Assert.assertEquals(activate.getCreatedBy(), groupCommand.getCreatedBy());
+    Assert.assertNotNull(groupCommand.getCreatedOn());
+
+    final List <Meeting> meetings = this.testSubject.fetchMeetings(activatedGroup.getIdentifier(), Boolean.FALSE);
+    Assert.assertNotNull(meetings);
+    Assert.assertEquals(randomGroupDefinition.getCycle().getNumberOfMeetings(), Integer.valueOf(meetings.size()));
+
+    final Meeting meeting2signOff = meetings.get(0);
+    final SignOffMeeting signOffMeeting = new SignOffMeeting();
+    signOffMeeting.setCycle(meeting2signOff.getCurrentCycle());
+    signOffMeeting.setSequence(meeting2signOff.getMeetingSequence());
+    signOffMeeting.setDuration(120L);
+    signOffMeeting.setAttendees(meeting2signOff.getAttendees()
+            .stream()
+            .map(attendee -> {
+              attendee.setStatus(Attendee.Status.ATTENDED.name());
+              return attendee;
+            })
+            .collect(Collectors.toSet())
+    );
+
+    Gson gson = new Gson();
+    this.mockMvc.perform(put("/groups/" + randomGroup.getIdentifier() + "/meetings")
+            .accept(MediaType.ALL_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(gson.toJson(signOffMeeting)))
+            .andExpect(status().isAccepted())
+            .andDo(document("document-close-meeting", preprocessRequest(prettyPrint()),
+                    requestFields(
+                            fieldWithPath("cycle").type("Integer").description("Meetings in cycle"),
+                            fieldWithPath("sequence").type("Integer").description("Meeting sequence"),
+                            fieldWithPath("attendees").type("Set<String>").description("Set of attendees"),
+                            fieldWithPath("duration").type("Long").description("Duration of meeting")
+                    )));
+  }
+
+  @Test
+  public void documentCreateGroupDefinition ( ) throws Exception {
+
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+
+    Gson serialize = new Gson();
+    this.mockMvc.perform(post("/definitions")
+            .accept(MediaType.APPLICATION_JSON_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(serialize.toJson(randomGroupDefinition)))
+            .andExpect(status().isAccepted())
+            .andDo(document("document-create-group-definition", preprocessRequest(prettyPrint()),
+                    requestFields(
+                            fieldWithPath("identifier").description("Group definition Identifier"),
+                            fieldWithPath("description").description("Group definition description"),
+                            fieldWithPath("minimalSize").type("Integer").description("Group's minimum size"),
+                            fieldWithPath("maximalSize").type("Integer").description("Group's maximum size"),
+                            fieldWithPath("cycle").type("Cycle").description("Group definition's cycle")
+                    )));
+  }
+
+  @Test
+  public void documentUpdateGroupDefinition ( ) throws Exception {
+
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    Gson serialize = new Gson();
+    this.mockMvc.perform(put("/definitions/" + randomGroupDefinition.getIdentifier())
+            .accept(MediaType.APPLICATION_JSON_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(serialize.toJson(randomGroupDefinition)))
+            .andExpect(status().isAccepted())
+            .andDo(document("document-update-group-definition", preprocessRequest(prettyPrint()),
+                    requestFields(
+                            fieldWithPath("identifier").type("String").description("Group definition Identifier"),
+                            fieldWithPath("description").type("String").description("Group definition description"),
+                            fieldWithPath("minimalSize").type("Integer").description("Group's minimum size"),
+                            fieldWithPath("maximalSize").type("Integer").description("Group's maximum size"),
+                            fieldWithPath("cycle").type("Cycle").description("Cycle of Meetings " +
+                                    " \n + " +
+                                    " *class* _Cycle_ { + \n" +
+                                    "    private Integer numberOfMeetings; + \n" +
+                                    "    private Frequency frequency; + \n" +
+                                    "    private Adjustment adjustment; + \n" +
+                                    " } \n +")
+                    )));
+  }
+}
diff --git a/component-test/src/main/java/org/apache/fineract/cn/group/SuiteTestEnvironment.java b/component-test/src/main/java/org/apache/fineract/cn/group/SuiteTestEnvironment.java
new file mode 100644
index 0000000..8cd3a8e
--- /dev/null
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/SuiteTestEnvironment.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.fineract.cn.group;
+
+import org.apache.fineract.cn.test.env.TestEnvironment;
+import org.apache.fineract.cn.test.fixture.TenantDataStoreContextTestRule;
+import org.apache.fineract.cn.test.fixture.cassandra.CassandraInitializer;
+import org.apache.fineract.cn.test.fixture.mariadb.MariaDBInitializer;
+import org.junit.ClassRule;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+
+public class SuiteTestEnvironment {
+    static final String APP_NAME = "group-v1";
+    static final String TEST_USER = "ranefer";
+
+    static final TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
+    static final CassandraInitializer cassandraInitializer = new CassandraInitializer();
+    static final MariaDBInitializer mariaDBInitializer = new MariaDBInitializer();
+    static final TenantDataStoreContextTestRule tenantDataStoreContext =
+            TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
+
+    @ClassRule
+    public static TestRule orderClassRules = RuleChain
+            .outerRule(testEnvironment)
+            .around(cassandraInitializer)
+            .around(mariaDBInitializer)
+            .around(tenantDataStoreContext);
+}
\ No newline at end of file
diff --git a/component-test/src/main/java/org/apache/fineract/cn/group/TestGroup.java b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroup.java
index 1b485f9..a78017a 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/group/TestGroup.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroup.java
@@ -29,12 +29,14 @@ import org.apache.fineract.cn.group.api.v1.domain.Meeting;
 import org.apache.fineract.cn.group.api.v1.domain.SignOffMeeting;
 import org.apache.fineract.cn.group.util.GroupDefinitionGenerator;
 import org.apache.fineract.cn.group.util.GroupGenerator;
+
 import java.time.Clock;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
+
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.fineract.cn.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
 import org.apache.fineract.cn.api.context.AutoUserContext;
@@ -65,58 +67,10 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 import org.springframework.test.context.junit4.SpringRunner;
 
-@RunWith(SpringRunner.class)
-@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
-public class TestGroup {
-  private static final String APP_NAME = "group-v1";
-  private static final String TEST_USER = "ranefer";
-
-  private final static TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
-  private final static CassandraInitializer cassandraInitializer = new CassandraInitializer();
-  private final static MariaDBInitializer mariaDBInitializer = new MariaDBInitializer();
-  private final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
-
-  @ClassRule
-  public static TestRule orderClassRules = RuleChain
-          .outerRule(testEnvironment)
-          .around(cassandraInitializer)
-          .around(mariaDBInitializer)
-          .around(tenantDataStoreContext);
-
-  @Rule
-  public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
-          = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
-  @Autowired
-  private GroupManager testSubject;
-  @Autowired
-  private EventRecorder eventRecorder;
-
-  private AutoUserContext userContext;
-
-  public TestGroup() {
-    super();
-  }
-
-  @Before
-  public void prepTest() {
-    userContext = this.tenantApplicationSecurityEnvironment.createAutoUserContext(TestGroup.TEST_USER);
-  }
-
-  @After
-  public void cleanTest() {
-    userContext.close();
-  }
-
-  public boolean waitForInitialize() {
-    try {
-      return this.eventRecorder.wait(EventConstants.INITIALIZE, EventConstants.INITIALIZE);
-    } catch (final InterruptedException e) {
-      throw new IllegalStateException(e);
-    }
-  }
+public class TestGroup extends AbstractGroupTest {
 
   @Test
-  public void shouldCreateGroup() throws Exception {
+  public void shouldCreateGroup ( ) throws Exception {
     final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
 
     this.testSubject.createGroupDefinition(randomGroupDefinition);
@@ -147,7 +101,7 @@ public class TestGroup {
   }
 
   @Test
-  public void shouldActivateCommand() throws Exception {
+  public void shouldActivateCommand ( ) throws Exception {
     final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
     this.testSubject.createGroupDefinition(randomGroupDefinition);
     this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
@@ -171,7 +125,7 @@ public class TestGroup {
     final Group activatedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
     Assert.assertEquals(Group.Status.ACTIVE.name(), activatedGroup.getStatus());
 
-    final List<GroupCommand> groupCommands = this.testSubject.fetchGroupCommands(activatedGroup.getIdentifier());
+    final List <GroupCommand> groupCommands = this.testSubject.fetchGroupCommands(activatedGroup.getIdentifier());
     Assert.assertTrue(groupCommands.size() == 1);
     final GroupCommand groupCommand = groupCommands.get(0);
     Assert.assertEquals(activate.getAction(), groupCommand.getAction());
@@ -179,7 +133,7 @@ public class TestGroup {
     Assert.assertEquals(activate.getCreatedBy(), groupCommand.getCreatedBy());
     Assert.assertNotNull(groupCommand.getCreatedOn());
 
-    final List<Meeting> meetings = this.testSubject.fetchMeetings(activatedGroup.getIdentifier(), Boolean.FALSE);
+    final List <Meeting> meetings = this.testSubject.fetchMeetings(activatedGroup.getIdentifier(), Boolean.FALSE);
     Assert.assertNotNull(meetings);
     Assert.assertEquals(randomGroupDefinition.getCycle().getNumberOfMeetings(), Integer.valueOf(meetings.size()));
 
@@ -189,12 +143,12 @@ public class TestGroup {
     signOffMeeting.setSequence(meeting2signOff.getMeetingSequence());
     signOffMeeting.setDuration(120L);
     signOffMeeting.setAttendees(meeting2signOff.getAttendees()
-        .stream()
-        .map(attendee -> {
-          attendee.setStatus(Attendee.Status.ATTENDED.name());
-          return attendee;
-        })
-        .collect(Collectors.toSet())
+            .stream()
+            .map(attendee -> {
+              attendee.setStatus(Attendee.Status.ATTENDED.name());
+              return attendee;
+            })
+            .collect(Collectors.toSet())
     );
 
     this.testSubject.closeMeeting(activatedGroup.getIdentifier(), signOffMeeting);
@@ -202,7 +156,7 @@ public class TestGroup {
   }
 
   @Test
-  public void shouldUpdateLeaders() throws Exception {
+  public void shouldUpdateLeaders ( ) throws Exception {
     final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
     this.testSubject.createGroupDefinition(randomGroupDefinition);
     this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
@@ -221,7 +175,7 @@ public class TestGroup {
   }
 
   @Test
-  public void shouldUpdateMembers() throws Exception {
+  public void shouldUpdateMembers ( ) throws Exception {
     final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
     this.testSubject.createGroupDefinition(randomGroupDefinition);
     this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
@@ -232,8 +186,8 @@ public class TestGroup {
 
     final int currentMembersSize = randomGroup.getMembers().size();
     randomGroup.getMembers().addAll(Arrays.asList(
-        RandomStringUtils.randomAlphanumeric(32),
-        RandomStringUtils.randomAlphanumeric(32)
+            RandomStringUtils.randomAlphanumeric(32),
+            RandomStringUtils.randomAlphanumeric(32)
     ));
     this.testSubject.updateMembers(randomGroup.getIdentifier(), randomGroup.getMembers());
     this.eventRecorder.wait(EventConstants.PUT_GROUP, randomGroup.getIdentifier());
@@ -243,7 +197,7 @@ public class TestGroup {
   }
 
   @Test
-  public void shouldUpdateAssignedEmployee() throws Exception {
+  public void shouldUpdateAssignedEmployee ( ) throws Exception {
     final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
     this.testSubject.createGroupDefinition(randomGroupDefinition);
     this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
@@ -263,7 +217,7 @@ public class TestGroup {
   }
 
   @Test
-  public void shouldUpdateGroup() throws Exception{
+  public void shouldUpdateGroup ( ) throws Exception {
     final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
     this.testSubject.createGroupDefinition(randomGroupDefinition);
     this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
@@ -277,28 +231,9 @@ public class TestGroup {
 
     this.testSubject.updateGroup(randomGroup.getIdentifier(), randomGroup);
 
-    this.eventRecorder.wait(EventConstants.PUT_GROUP,randomGroup.getIdentifier());
+    this.eventRecorder.wait(EventConstants.PUT_GROUP, randomGroup.getIdentifier());
 
     final Group updatedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
     Assert.assertEquals(randomGroup.getName(), updatedGroup.getName());
-
-
-  }
-
-  @Configuration
-  @EnableEventRecording
-  @EnableFeignClients(basePackages = {"org.apache.fineract.cn.group.api.v1.client"})
-  @RibbonClient(name = APP_NAME)
-  @Import({GroupConfiguration.class})
-  @ComponentScan("org.apache.fineract.cn.group.listener")
-  public static class TestConfiguration {
-    public TestConfiguration() {
-      super();
-    }
-
-    @Bean()
-    public Logger logger() {
-      return LoggerFactory.getLogger("test-logger");
-    }
   }
 }
diff --git a/component-test/src/main/java/org/apache/fineract/cn/group/TestGroupDefinition.java b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroupDefinition.java
index e7a75f0..3a4b652 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/group/TestGroupDefinition.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroupDefinition.java
@@ -52,61 +52,10 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 import org.springframework.test.context.junit4.SpringRunner;
 
-@RunWith(SpringRunner.class)
-@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
-
-public class TestGroupDefinition {
-  private static final String APP_NAME = "group-v1";
-  private static final String TEST_USER = "ranefer";
-
-  private final static TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
-  private final static CassandraInitializer cassandraInitializer = new CassandraInitializer();
-  private final static MariaDBInitializer mariaDBInitializer = new MariaDBInitializer();
-  private final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
-
-  @ClassRule
-  public static TestRule orderClassRules = RuleChain
-          .outerRule(testEnvironment)
-          .around(cassandraInitializer)
-          .around(mariaDBInitializer)
-          .around(tenantDataStoreContext);
-
-  @Rule
-  public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
-          = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
-
-  @Autowired
-  private GroupManager testSubject;
-  @Autowired
-  private EventRecorder eventRecorder;
-
-  private AutoUserContext userContext;
-
-  public TestGroupDefinition() {
-    super();
-  }
-
-  @Before
-  public void prepTest() {
-    userContext = this.tenantApplicationSecurityEnvironment.createAutoUserContext(TestGroupDefinition.TEST_USER);
-  }
-
-  @After
-  public void cleanTest() {
-   //TenantContextHolder.clear();
-    userContext.close();
-  }
-
-  public boolean waitForInitialize() {
-    try {
-      return this.eventRecorder.wait(EventConstants.INITIALIZE, EventConstants.INITIALIZE);
-    } catch (final InterruptedException e) {
-      throw new IllegalStateException(e);
-    }
-  }
+public class TestGroupDefinition extends AbstractGroupTest {
 
   @Test
-  public void shouldCreateGroupDefinition() throws Exception {
+  public void shouldCreateGroupDefinition ( ) throws Exception {
     final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
     this.testSubject.createGroupDefinition(randomGroupDefinition);
 
@@ -128,9 +77,8 @@ public class TestGroupDefinition {
     Assert.assertNull(fetchedGroupDefinition.getLastModifiedOn());
   }
 
-
   @Test
-  public void shouldUpdateGroupDefinition() throws Exception{
+  public void shouldUpdateGroupDefinition ( ) throws Exception {
     final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
     this.testSubject.createGroupDefinition(randomGroupDefinition);
 
@@ -139,7 +87,7 @@ public class TestGroupDefinition {
     final GroupDefinition updatedGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
     updatedGroupDefinition.setIdentifier(randomGroupDefinition.getIdentifier());
 
-    this.testSubject.updateGroupDefinition(updatedGroupDefinition.getIdentifier(),updatedGroupDefinition);
+    this.testSubject.updateGroupDefinition(updatedGroupDefinition.getIdentifier(), updatedGroupDefinition);
 
     this.eventRecorder.wait(EventConstants.PUT_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
 
@@ -153,23 +101,4 @@ public class TestGroupDefinition {
     Assert.assertEquals(updatedGroupDefinition.getCycle().getNumberOfMeetings(), fetchedGroupDefinition.getCycle().getNumberOfMeetings());
     Assert.assertEquals(updatedGroupDefinition.getCycle().getFrequency(), fetchedGroupDefinition.getCycle().getFrequency());
   }
-
-
-
-  @Configuration
-  @EnableEventRecording
-  @EnableFeignClients(basePackages = {"org.apache.fineract.cn.group.api.v1.client"})
-  @RibbonClient(name = APP_NAME)
-  @Import({GroupConfiguration.class})
-  @ComponentScan("org.apache.fineract.cn.group.listener")
-  public static class TestConfiguration {
-    public TestConfiguration() {
-      super();
-    }
-
-    @Bean()
-    public Logger logger() {
-      return LoggerFactory.getLogger("test-logger");
-    }
-  }
 }
diff --git a/component-test/src/main/java/org/apache/fineract/cn/group/util/GroupDefinitionGenerator.java b/component-test/src/main/java/org/apache/fineract/cn/group/util/GroupDefinitionGenerator.java
index 1ecebe8..b66a9df 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/group/util/GroupDefinitionGenerator.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/util/GroupDefinitionGenerator.java
@@ -30,8 +30,8 @@ public class GroupDefinitionGenerator {
 
   public static GroupDefinition createRandomGroupDefinition() {
     final GroupDefinition groupDefinition = new GroupDefinition();
-    groupDefinition.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
-    groupDefinition.setDescription(RandomStringUtils.randomAlphabetic(2048));
+    groupDefinition.setIdentifier("grpDef" + RandomStringUtils.randomAlphanumeric(3));
+    groupDefinition.setDescription("Group Def Descr " + RandomStringUtils.randomAlphabetic(5));
     groupDefinition.setMinimalSize(10);
     groupDefinition.setMaximalSize(30);
     final Cycle cycle = new Cycle();
diff --git a/component-test/src/main/java/org/apache/fineract/cn/group/util/GroupGenerator.java b/component-test/src/main/java/org/apache/fineract/cn/group/util/GroupGenerator.java
index 4d63436..ed05cd1 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/group/util/GroupGenerator.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/util/GroupGenerator.java
@@ -33,30 +33,26 @@ public class GroupGenerator {
 
   public static Group createRandomGroup(final String definitionIdentifier) {
     final Group group = new Group();
-    group.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
+    group.setIdentifier("grp" + RandomStringUtils.randomAlphanumeric(3));
     group.setGroupDefinitionIdentifier(definitionIdentifier);
-    group.setName(RandomStringUtils.randomAlphanumeric(256));
-    group.setOffice(RandomStringUtils.randomAlphanumeric(32));
-    group.setAssignedEmployee(RandomStringUtils.randomAlphanumeric(32));
-    group.setLeaders(new HashSet<>(Arrays.asList(
-        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32)
+    group.setName("groupName" + RandomStringUtils.randomAlphanumeric(2));
+    group.setOffice("office" + RandomStringUtils.randomAlphanumeric(4));
+    group.setAssignedEmployee("employee" + RandomStringUtils.randomAlphanumeric(3));
+    group.setLeaders(new HashSet<>(Arrays.asList("Leader" +
+            RandomStringUtils.randomAlphanumeric(3), "Leader" + RandomStringUtils.randomAlphanumeric(3)
     )));
     group.setMembers(new HashSet<>(Arrays.asList(
-        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
-        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
-        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
-        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
-        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32)
+            "Member" + RandomStringUtils.randomAlphanumeric(3), "Member" + RandomStringUtils.randomAlphanumeric(3)
     )));
     group.setWeekday(Group.Weekday.WEDNESDAY.getValue());
     final Address address = new Address();
-    address.setStreet(RandomStringUtils.randomAlphanumeric(256));
-    address.setCity(RandomStringUtils.randomAlphanumeric(256));
-    address.setRegion(RandomStringUtils.randomAlphanumeric(256));
-    address.setPostalCode(RandomStringUtils.randomAlphanumeric(2));
-    address.setCountry(RandomStringUtils.randomAlphanumeric(256));
-    address.setCountryCode(RandomStringUtils.randomAlphanumeric(2));
+    address.setStreet("street" + RandomStringUtils.randomAlphanumeric(4));
+    address.setCity("city" + RandomStringUtils.randomAlphanumeric(5));
+    address.setRegion("region" + RandomStringUtils.randomAlphanumeric(6));
+    address.setPostalCode(RandomStringUtils.randomAlphanumeric(4));
+    address.setCountry("country" + RandomStringUtils.randomAlphanumeric(6));
+    address.setCountryCode(RandomStringUtils.randomAlphanumeric(2).toUpperCase());
     group.setAddress(address);
     return group;
   }
-}
+}
\ No newline at end of file


[fineract-cn-group] 15/40: Change package names from mifos to apache fineract.

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit a0988fc30c1f3592f496944619035e1c32dc8729
Author: Myrle Krantz <my...@apache.org>
AuthorDate: Mon Apr 16 13:12:53 2018 +0200

    Change package names from mifos to apache fineract.
---
 .../fineract/cn}/group/api/v1/EventConstants.java  |  2 +-
 .../group/api/v1/client/GroupAlreadyExists.java    |  2 +-
 .../v1/client/GroupDefinitionAlreadyExists.java    |  2 +-
 .../api/v1/client/GroupDefinitionNotFound.java     |  2 +-
 .../api/v1/client/GroupDefinitionValidation.java   |  2 +-
 .../cn}/group/api/v1/client/GroupManager.java      | 16 +++---
 .../api/v1/client/GroupNotFoundException.java      |  2 +-
 .../api/v1/client/GroupValidationException.java    |  2 +-
 .../fineract/cn}/group/api/v1/domain/Address.java  |  2 +-
 .../api/v1/domain/AssignedEmployeeHolder.java      |  2 +-
 .../fineract/cn}/group/api/v1/domain/Attendee.java |  2 +-
 .../fineract/cn}/group/api/v1/domain/Cycle.java    |  2 +-
 .../fineract/cn}/group/api/v1/domain/Group.java    |  2 +-
 .../cn}/group/api/v1/domain/GroupCommand.java      |  2 +-
 .../cn}/group/api/v1/domain/GroupDefinition.java   |  2 +-
 .../cn}/group/api/v1/domain/GroupPage.java         |  2 +-
 .../fineract/cn}/group/api/v1/domain/Meeting.java  |  2 +-
 .../cn}/group/api/v1/domain/SignOffMeeting.java    |  2 +-
 .../apache/fineract/cn}/group/TestGroup.java       | 32 +++++------
 .../fineract/cn}/group/TestGroupDefinition.java    | 16 +++---
 .../listener/GroupDefinitionEventListener.java     |  4 +-
 .../cn}/group/listener/GroupEventListener.java     |  4 +-
 .../cn}/group/listener/MigrationEventListener.java |  4 +-
 .../cn}/group/util/GroupDefinitionGenerator.java   |  6 +--
 .../fineract/cn}/group/util/GroupGenerator.java    |  6 +--
 .../cn}/group/service/GroupApplication.java        |  2 +-
 .../cn}/group/service/GroupConfiguration.java      | 12 ++---
 .../cn}/group/service/ServiceConstants.java        |  2 +-
 .../internal/command/ActivateGroupCommand.java     |  4 +-
 .../internal/command/CloseGroupCommand.java        |  4 +-
 .../internal/command/CreateGroupCommand.java       |  4 +-
 .../command/CreateGroupDefinitionCommand.java      |  4 +-
 .../internal/command/InitializeServiceCommand.java |  2 +-
 .../internal/command/ReopenGroupCommand.java       |  4 +-
 .../internal/command/SignOffMeetingCommand.java    |  4 +-
 .../command/UpdateAssignedEmployeeCommand.java     |  2 +-
 .../internal/command/UpdateLeadersCommand.java     |  2 +-
 .../internal/command/UpdateMembersCommand.java     |  2 +-
 .../internal/command/handler/GroupAggregate.java   | 62 +++++++++++-----------
 .../command/handler/MigrationAggregate.java        |  8 +--
 .../service/internal/mapper/AddressMapper.java     |  6 +--
 .../service/internal/mapper/AttendeeMapper.java    |  6 +--
 .../internal/mapper/GroupCommandMapper.java        |  6 +--
 .../internal/mapper/GroupDefinitionMapper.java     |  8 +--
 .../group/service/internal/mapper/GroupMapper.java |  6 +--
 .../service/internal/mapper/MeetingMapper.java     |  6 +--
 .../service/internal/repository/AddressEntity.java |  2 +-
 .../internal/repository/AddressRepository.java     |  2 +-
 .../internal/repository/AttendeeEntity.java        |  2 +-
 .../internal/repository/AttendeeRepository.java    |  2 +-
 .../internal/repository/GroupCommandEntity.java    |  2 +-
 .../repository/GroupCommandRepository.java         |  2 +-
 .../internal/repository/GroupDefinitionEntity.java |  2 +-
 .../repository/GroupDefinitionRepository.java      |  2 +-
 .../service/internal/repository/GroupEntity.java   |  2 +-
 .../internal/repository/GroupRepository.java       |  2 +-
 .../service/internal/repository/MeetingEntity.java |  2 +-
 .../internal/repository/MeetingRepository.java     |  2 +-
 .../internal/service/GroupDefinitionService.java   | 10 ++--
 .../service/internal/service/GroupService.java     | 34 ++++++------
 .../rest/GroupDefinitionRestController.java        | 10 ++--
 .../group/service/rest/GroupRestController.java    | 36 ++++++-------
 .../service/rest/MigrationRestController.java      |  6 +--
 63 files changed, 199 insertions(+), 199 deletions(-)

diff --git a/api/src/main/java/io/mifos/group/api/v1/EventConstants.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/EventConstants.java
similarity index 97%
rename from api/src/main/java/io/mifos/group/api/v1/EventConstants.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/EventConstants.java
index 7a33567..435ac6d 100644
--- a/api/src/main/java/io/mifos/group/api/v1/EventConstants.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/EventConstants.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1;
+package org.apache.fineract.cn.group.api.v1;
 
 @SuppressWarnings("unused")
 public interface EventConstants {
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupAlreadyExists.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupAlreadyExists.java
similarity index 94%
rename from api/src/main/java/io/mifos/group/api/v1/client/GroupAlreadyExists.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupAlreadyExists.java
index fdf09d2..887d7a5 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupAlreadyExists.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupAlreadyExists.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.client;
+package org.apache.fineract.cn.group.api.v1.client;
 
 public class GroupAlreadyExists extends RuntimeException {
 }
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionAlreadyExists.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupDefinitionAlreadyExists.java
similarity index 94%
rename from api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionAlreadyExists.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupDefinitionAlreadyExists.java
index e0f31f9..30430e8 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionAlreadyExists.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupDefinitionAlreadyExists.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.client;
+package org.apache.fineract.cn.group.api.v1.client;
 
 public class GroupDefinitionAlreadyExists extends RuntimeException {
 }
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionNotFound.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupDefinitionNotFound.java
similarity index 94%
rename from api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionNotFound.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupDefinitionNotFound.java
index 7b1c260..a56711e 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionNotFound.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupDefinitionNotFound.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.client;
+package org.apache.fineract.cn.group.api.v1.client;
 
 public class GroupDefinitionNotFound extends RuntimeException {
 }
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionValidation.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupDefinitionValidation.java
similarity index 94%
rename from api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionValidation.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupDefinitionValidation.java
index aa83065..2e0c0d0 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionValidation.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupDefinitionValidation.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.client;
+package org.apache.fineract.cn.group.api.v1.client;
 
 public class GroupDefinitionValidation extends RuntimeException {
 }
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupManager.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupManager.java
similarity index 93%
rename from api/src/main/java/io/mifos/group/api/v1/client/GroupManager.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupManager.java
index f393d58..b64b390 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupManager.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupManager.java
@@ -16,15 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.client;
+package org.apache.fineract.cn.group.api.v1.client;
 
-import io.mifos.group.api.v1.domain.AssignedEmployeeHolder;
-import io.mifos.group.api.v1.domain.Group;
-import io.mifos.group.api.v1.domain.GroupCommand;
-import io.mifos.group.api.v1.domain.GroupDefinition;
-import io.mifos.group.api.v1.domain.GroupPage;
-import io.mifos.group.api.v1.domain.Meeting;
-import io.mifos.group.api.v1.domain.SignOffMeeting;
+import org.apache.fineract.cn.group.api.v1.domain.AssignedEmployeeHolder;
+import org.apache.fineract.cn.group.api.v1.domain.Group;
+import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
+import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
+import org.apache.fineract.cn.group.api.v1.domain.GroupPage;
+import org.apache.fineract.cn.group.api.v1.domain.Meeting;
+import org.apache.fineract.cn.group.api.v1.domain.SignOffMeeting;
 import java.util.List;
 import java.util.Set;
 import org.apache.fineract.cn.api.annotation.ThrowsException;
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupNotFoundException.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupNotFoundException.java
similarity index 94%
rename from api/src/main/java/io/mifos/group/api/v1/client/GroupNotFoundException.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupNotFoundException.java
index ee0999a..1b27678 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupNotFoundException.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupNotFoundException.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.client;
+package org.apache.fineract.cn.group.api.v1.client;
 
 public class GroupNotFoundException extends RuntimeException {
 }
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupValidationException.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupValidationException.java
similarity index 94%
rename from api/src/main/java/io/mifos/group/api/v1/client/GroupValidationException.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupValidationException.java
index caa61f0..1bdc5e7 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupValidationException.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupValidationException.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.client;
+package org.apache.fineract.cn.group.api.v1.client;
 
 public class GroupValidationException extends RuntimeException {
 }
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/Address.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/Address.java
similarity index 97%
rename from api/src/main/java/io/mifos/group/api/v1/domain/Address.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/Address.java
index 16c76f0..7ba47bb 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/Address.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/Address.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.domain;
+package org.apache.fineract.cn.group.api.v1.domain;
 
 import org.hibernate.validator.constraints.NotBlank;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/AssignedEmployeeHolder.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/AssignedEmployeeHolder.java
similarity index 95%
rename from api/src/main/java/io/mifos/group/api/v1/domain/AssignedEmployeeHolder.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/AssignedEmployeeHolder.java
index 6871e5a..7897564 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/AssignedEmployeeHolder.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/AssignedEmployeeHolder.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.domain;
+package org.apache.fineract.cn.group.api.v1.domain;
 
 public class AssignedEmployeeHolder {
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/Attendee.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/Attendee.java
similarity index 96%
rename from api/src/main/java/io/mifos/group/api/v1/domain/Attendee.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/Attendee.java
index e48a45f..3fc7a7a 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/Attendee.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/Attendee.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.domain;
+package org.apache.fineract.cn.group.api.v1.domain;
 
 import org.hibernate.validator.constraints.NotBlank;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/Cycle.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/Cycle.java
similarity index 97%
rename from api/src/main/java/io/mifos/group/api/v1/domain/Cycle.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/Cycle.java
index 05a1c78..e249b48 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/Cycle.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/Cycle.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.domain;
+package org.apache.fineract.cn.group.api.v1.domain;
 
 import javax.validation.constraints.NotNull;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/Group.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/Group.java
similarity index 98%
rename from api/src/main/java/io/mifos/group/api/v1/domain/Group.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/Group.java
index d51751d..4c21ffa 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/Group.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/Group.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.domain;
+package org.apache.fineract.cn.group.api.v1.domain;
 
 import org.hibernate.validator.constraints.NotBlank;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/GroupCommand.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/GroupCommand.java
similarity index 96%
rename from api/src/main/java/io/mifos/group/api/v1/domain/GroupCommand.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/GroupCommand.java
index 9185d56..526e5b7 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/GroupCommand.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/GroupCommand.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.domain;
+package org.apache.fineract.cn.group.api.v1.domain;
 
 public class GroupCommand {
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/GroupDefinition.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/GroupDefinition.java
similarity index 98%
rename from api/src/main/java/io/mifos/group/api/v1/domain/GroupDefinition.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/GroupDefinition.java
index 2083679..9a8d2f1 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/GroupDefinition.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/GroupDefinition.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.domain;
+package org.apache.fineract.cn.group.api.v1.domain;
 
 import org.hibernate.validator.constraints.NotBlank;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/GroupPage.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/GroupPage.java
similarity index 96%
rename from api/src/main/java/io/mifos/group/api/v1/domain/GroupPage.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/GroupPage.java
index 04d3c32..ceae93a 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/GroupPage.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/GroupPage.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.domain;
+package org.apache.fineract.cn.group.api.v1.domain;
 
 import java.util.List;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/Meeting.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/Meeting.java
similarity index 98%
rename from api/src/main/java/io/mifos/group/api/v1/domain/Meeting.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/Meeting.java
index 78c14cf..f7ff2b5 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/Meeting.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/Meeting.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.domain;
+package org.apache.fineract.cn.group.api.v1.domain;
 
 import org.hibernate.validator.constraints.NotBlank;
 import org.hibernate.validator.constraints.NotEmpty;
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/SignOffMeeting.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/SignOffMeeting.java
similarity index 96%
rename from api/src/main/java/io/mifos/group/api/v1/domain/SignOffMeeting.java
rename to api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/SignOffMeeting.java
index 50c2b8f..1ea27e7 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/SignOffMeeting.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/SignOffMeeting.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.api.v1.domain;
+package org.apache.fineract.cn.group.api.v1.domain;
 
 import javax.validation.Valid;
 import java.util.Set;
diff --git a/component-test/src/main/java/io/mifos/group/TestGroup.java b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroup.java
similarity index 93%
rename from component-test/src/main/java/io/mifos/group/TestGroup.java
rename to component-test/src/main/java/org/apache/fineract/cn/group/TestGroup.java
index d918728..19df79c 100644
--- a/component-test/src/main/java/io/mifos/group/TestGroup.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroup.java
@@ -16,20 +16,20 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group;
-
-import io.mifos.group.api.v1.EventConstants;
-import io.mifos.group.api.v1.client.GroupManager;
-import io.mifos.group.api.v1.domain.AssignedEmployeeHolder;
-import io.mifos.group.api.v1.domain.Attendee;
-import io.mifos.group.api.v1.domain.Group;
-import io.mifos.group.api.v1.domain.GroupCommand;
-import io.mifos.group.api.v1.domain.GroupDefinition;
-import io.mifos.group.api.v1.domain.Meeting;
-import io.mifos.group.api.v1.domain.SignOffMeeting;
-import io.mifos.group.service.GroupConfiguration;
-import io.mifos.group.util.GroupDefinitionGenerator;
-import io.mifos.group.util.GroupGenerator;
+package org.apache.fineract.cn.group;
+
+import org.apache.fineract.cn.group.api.v1.EventConstants;
+import org.apache.fineract.cn.group.api.v1.client.GroupManager;
+import org.apache.fineract.cn.group.api.v1.domain.AssignedEmployeeHolder;
+import org.apache.fineract.cn.group.api.v1.domain.Attendee;
+import org.apache.fineract.cn.group.api.v1.domain.Group;
+import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
+import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
+import org.apache.fineract.cn.group.api.v1.domain.Meeting;
+import org.apache.fineract.cn.group.api.v1.domain.SignOffMeeting;
+import org.apache.fineract.cn.group.service.GroupConfiguration;
+import org.apache.fineract.cn.group.util.GroupDefinitionGenerator;
+import org.apache.fineract.cn.group.util.GroupGenerator;
 import java.time.Clock;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
@@ -265,10 +265,10 @@ public class TestGroup {
 
   @Configuration
   @EnableEventRecording
-  @EnableFeignClients(basePackages = {"io.mifos.group.api.v1.client"})
+  @EnableFeignClients(basePackages = {"org.apache.fineract.cn.group.api.v1.client"})
   @RibbonClient(name = APP_NAME)
   @Import({GroupConfiguration.class})
-  @ComponentScan("io.mifos.group.listener")
+  @ComponentScan("org.apache.fineract.cn.group.listener")
   public static class TestConfiguration {
     public TestConfiguration() {
       super();
diff --git a/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroupDefinition.java
similarity index 92%
rename from component-test/src/main/java/io/mifos/group/TestGroupDefinition.java
rename to component-test/src/main/java/org/apache/fineract/cn/group/TestGroupDefinition.java
index f78eb44..4af1087 100644
--- a/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroupDefinition.java
@@ -16,13 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group;
+package org.apache.fineract.cn.group;
 
-import io.mifos.group.api.v1.EventConstants;
-import io.mifos.group.api.v1.client.GroupManager;
-import io.mifos.group.api.v1.domain.GroupDefinition;
-import io.mifos.group.service.GroupConfiguration;
-import io.mifos.group.util.GroupDefinitionGenerator;
+import org.apache.fineract.cn.group.api.v1.EventConstants;
+import org.apache.fineract.cn.group.api.v1.client.GroupManager;
+import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
+import org.apache.fineract.cn.group.service.GroupConfiguration;
+import org.apache.fineract.cn.group.util.GroupDefinitionGenerator;
 import org.apache.fineract.cn.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
 import org.apache.fineract.cn.api.context.AutoUserContext;
 import org.apache.fineract.cn.lang.TenantContextHolder;
@@ -130,10 +130,10 @@ public class TestGroupDefinition {
 
   @Configuration
   @EnableEventRecording
-  @EnableFeignClients(basePackages = {"io.mifos.group.api.v1.client"})
+  @EnableFeignClients(basePackages = {"org.apache.fineract.cn.group.api.v1.client"})
   @RibbonClient(name = APP_NAME)
   @Import({GroupConfiguration.class})
-  @ComponentScan("io.mifos.group.listener")
+  @ComponentScan("org.apache.fineract.cn.group.listener")
   public static class TestConfiguration {
     public TestConfiguration() {
       super();
diff --git a/component-test/src/main/java/io/mifos/group/listener/GroupDefinitionEventListener.java b/component-test/src/main/java/org/apache/fineract/cn/group/listener/GroupDefinitionEventListener.java
similarity index 94%
rename from component-test/src/main/java/io/mifos/group/listener/GroupDefinitionEventListener.java
rename to component-test/src/main/java/org/apache/fineract/cn/group/listener/GroupDefinitionEventListener.java
index 3932eb8..13dad62 100644
--- a/component-test/src/main/java/io/mifos/group/listener/GroupDefinitionEventListener.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/listener/GroupDefinitionEventListener.java
@@ -16,9 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.listener;
+package org.apache.fineract.cn.group.listener;
 
-import io.mifos.group.api.v1.EventConstants;
+import org.apache.fineract.cn.group.api.v1.EventConstants;
 import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
 import org.apache.fineract.cn.test.listener.EventRecorder;
 import org.springframework.beans.factory.annotation.Autowired;
diff --git a/component-test/src/main/java/io/mifos/group/listener/GroupEventListener.java b/component-test/src/main/java/org/apache/fineract/cn/group/listener/GroupEventListener.java
similarity index 96%
rename from component-test/src/main/java/io/mifos/group/listener/GroupEventListener.java
rename to component-test/src/main/java/org/apache/fineract/cn/group/listener/GroupEventListener.java
index 9020138..a453f68 100644
--- a/component-test/src/main/java/io/mifos/group/listener/GroupEventListener.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/listener/GroupEventListener.java
@@ -16,9 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.listener;
+package org.apache.fineract.cn.group.listener;
 
-import io.mifos.group.api.v1.EventConstants;
+import org.apache.fineract.cn.group.api.v1.EventConstants;
 import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
 import org.apache.fineract.cn.test.listener.EventRecorder;
 import org.springframework.beans.factory.annotation.Autowired;
diff --git a/component-test/src/main/java/io/mifos/group/listener/MigrationEventListener.java b/component-test/src/main/java/org/apache/fineract/cn/group/listener/MigrationEventListener.java
similarity index 94%
rename from component-test/src/main/java/io/mifos/group/listener/MigrationEventListener.java
rename to component-test/src/main/java/org/apache/fineract/cn/group/listener/MigrationEventListener.java
index c150fef..027688a 100644
--- a/component-test/src/main/java/io/mifos/group/listener/MigrationEventListener.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/listener/MigrationEventListener.java
@@ -16,9 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.listener;
+package org.apache.fineract.cn.group.listener;
 
-import io.mifos.group.api.v1.EventConstants;
+import org.apache.fineract.cn.group.api.v1.EventConstants;
 import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
 import org.apache.fineract.cn.test.listener.EventRecorder;
 import org.springframework.beans.factory.annotation.Autowired;
diff --git a/component-test/src/main/java/io/mifos/group/util/GroupDefinitionGenerator.java b/component-test/src/main/java/org/apache/fineract/cn/group/util/GroupDefinitionGenerator.java
similarity index 90%
rename from component-test/src/main/java/io/mifos/group/util/GroupDefinitionGenerator.java
rename to component-test/src/main/java/org/apache/fineract/cn/group/util/GroupDefinitionGenerator.java
index 051bd2b..1ecebe8 100644
--- a/component-test/src/main/java/io/mifos/group/util/GroupDefinitionGenerator.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/util/GroupDefinitionGenerator.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.util;
+package org.apache.fineract.cn.group.util;
 
-import io.mifos.group.api.v1.domain.Cycle;
-import io.mifos.group.api.v1.domain.GroupDefinition;
+import org.apache.fineract.cn.group.api.v1.domain.Cycle;
+import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
 import org.apache.commons.lang3.RandomStringUtils;
 
 public class GroupDefinitionGenerator {
diff --git a/component-test/src/main/java/io/mifos/group/util/GroupGenerator.java b/component-test/src/main/java/org/apache/fineract/cn/group/util/GroupGenerator.java
similarity index 94%
rename from component-test/src/main/java/io/mifos/group/util/GroupGenerator.java
rename to component-test/src/main/java/org/apache/fineract/cn/group/util/GroupGenerator.java
index 31ff0e3..4d63436 100644
--- a/component-test/src/main/java/io/mifos/group/util/GroupGenerator.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/util/GroupGenerator.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.util;
+package org.apache.fineract.cn.group.util;
 
-import io.mifos.group.api.v1.domain.Address;
-import io.mifos.group.api.v1.domain.Group;
+import org.apache.fineract.cn.group.api.v1.domain.Address;
+import org.apache.fineract.cn.group.api.v1.domain.Group;
 import org.apache.commons.lang3.RandomStringUtils;
 
 import java.util.Arrays;
diff --git a/service/src/main/java/io/mifos/group/service/GroupApplication.java b/service/src/main/java/org/apache/fineract/cn/group/service/GroupApplication.java
similarity index 95%
rename from service/src/main/java/io/mifos/group/service/GroupApplication.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/GroupApplication.java
index 10ead59..fc17f94 100644
--- a/service/src/main/java/io/mifos/group/service/GroupApplication.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/GroupApplication.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service;
+package org.apache.fineract.cn.group.service;
 
 import org.springframework.boot.SpringApplication;
 
diff --git a/service/src/main/java/io/mifos/group/service/GroupConfiguration.java b/service/src/main/java/org/apache/fineract/cn/group/service/GroupConfiguration.java
similarity index 87%
rename from service/src/main/java/io/mifos/group/service/GroupConfiguration.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/GroupConfiguration.java
index 244716b..ee583e0 100644
--- a/service/src/main/java/io/mifos/group/service/GroupConfiguration.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/GroupConfiguration.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service;
+package org.apache.fineract.cn.group.service;
 
 import org.apache.fineract.cn.anubis.config.EnableAnubis;
 import org.apache.fineract.cn.async.config.EnableAsync;
@@ -48,13 +48,13 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
 @EnableAnubis
 @EnableServiceException
 @ComponentScan({
-    "io.mifos.group.service.rest",
-    "io.mifos.group.service.internal.service",
-    "io.mifos.group.service.internal.repository",
-    "io.mifos.group.service.internal.command.handler"
+    "org.apache.fineract.cn.group.service.rest",
+    "org.apache.fineract.cn.group.service.internal.service",
+    "org.apache.fineract.cn.group.service.internal.repository",
+    "org.apache.fineract.cn.group.service.internal.command.handler"
 })
 @EnableJpaRepositories({
-    "io.mifos.group.service.internal.repository"
+    "org.apache.fineract.cn.group.service.internal.repository"
 })
 public class GroupConfiguration extends WebMvcConfigurerAdapter {
 
diff --git a/service/src/main/java/io/mifos/group/service/ServiceConstants.java b/service/src/main/java/org/apache/fineract/cn/group/service/ServiceConstants.java
similarity index 95%
rename from service/src/main/java/io/mifos/group/service/ServiceConstants.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/ServiceConstants.java
index 3f7f49d..de8f2ff 100644
--- a/service/src/main/java/io/mifos/group/service/ServiceConstants.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/ServiceConstants.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service;
+package org.apache.fineract.cn.group.service;
 
 public interface ServiceConstants {
   String LOGGER_NAME = "group-logger";
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/ActivateGroupCommand.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/ActivateGroupCommand.java
similarity index 90%
rename from service/src/main/java/io/mifos/group/service/internal/command/ActivateGroupCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/command/ActivateGroupCommand.java
index a36da1a..1892d62 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/ActivateGroupCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/ActivateGroupCommand.java
@@ -16,9 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.command;
+package org.apache.fineract.cn.group.service.internal.command;
 
-import io.mifos.group.api.v1.domain.GroupCommand;
+import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
 
 public class ActivateGroupCommand {
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/CloseGroupCommand.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CloseGroupCommand.java
similarity index 90%
rename from service/src/main/java/io/mifos/group/service/internal/command/CloseGroupCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CloseGroupCommand.java
index 496f296..43a6937 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/CloseGroupCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CloseGroupCommand.java
@@ -16,9 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.command;
+package org.apache.fineract.cn.group.service.internal.command;
 
-import io.mifos.group.api.v1.domain.GroupCommand;
+import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
 
 public class CloseGroupCommand {
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupCommand.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CreateGroupCommand.java
similarity index 89%
rename from service/src/main/java/io/mifos/group/service/internal/command/CreateGroupCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CreateGroupCommand.java
index 1f17643..a367a12 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CreateGroupCommand.java
@@ -16,9 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.command;
+package org.apache.fineract.cn.group.service.internal.command;
 
-import io.mifos.group.api.v1.domain.Group;
+import org.apache.fineract.cn.group.api.v1.domain.Group;
 
 public class CreateGroupCommand {
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupDefinitionCommand.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CreateGroupDefinitionCommand.java
similarity index 89%
rename from service/src/main/java/io/mifos/group/service/internal/command/CreateGroupDefinitionCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CreateGroupDefinitionCommand.java
index 47561a8..c034284 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupDefinitionCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CreateGroupDefinitionCommand.java
@@ -16,9 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.command;
+package org.apache.fineract.cn.group.service.internal.command;
 
-import io.mifos.group.api.v1.domain.GroupDefinition;
+import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
 
 public class CreateGroupDefinitionCommand {
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/InitializeServiceCommand.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/InitializeServiceCommand.java
similarity index 93%
rename from service/src/main/java/io/mifos/group/service/internal/command/InitializeServiceCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/command/InitializeServiceCommand.java
index e513bfd..8d65200 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/InitializeServiceCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/InitializeServiceCommand.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.command;
+package org.apache.fineract.cn.group.service.internal.command;
 
 public class InitializeServiceCommand {
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/ReopenGroupCommand.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/ReopenGroupCommand.java
similarity index 90%
rename from service/src/main/java/io/mifos/group/service/internal/command/ReopenGroupCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/command/ReopenGroupCommand.java
index 38a60ca..f21e26a 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/ReopenGroupCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/ReopenGroupCommand.java
@@ -16,9 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.command;
+package org.apache.fineract.cn.group.service.internal.command;
 
-import io.mifos.group.api.v1.domain.GroupCommand;
+import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
 
 public class ReopenGroupCommand {
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/SignOffMeetingCommand.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/SignOffMeetingCommand.java
similarity index 90%
rename from service/src/main/java/io/mifos/group/service/internal/command/SignOffMeetingCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/command/SignOffMeetingCommand.java
index 91cae9c..f67962d 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/SignOffMeetingCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/SignOffMeetingCommand.java
@@ -16,9 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.command;
+package org.apache.fineract.cn.group.service.internal.command;
 
-import io.mifos.group.api.v1.domain.SignOffMeeting;
+import org.apache.fineract.cn.group.api.v1.domain.SignOffMeeting;
 
 public class SignOffMeetingCommand {
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/UpdateAssignedEmployeeCommand.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateAssignedEmployeeCommand.java
similarity index 95%
rename from service/src/main/java/io/mifos/group/service/internal/command/UpdateAssignedEmployeeCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateAssignedEmployeeCommand.java
index 41763ee..f44d86b 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/UpdateAssignedEmployeeCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateAssignedEmployeeCommand.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.command;
+package org.apache.fineract.cn.group.service.internal.command;
 
 public class UpdateAssignedEmployeeCommand {
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/UpdateLeadersCommand.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateLeadersCommand.java
similarity index 95%
rename from service/src/main/java/io/mifos/group/service/internal/command/UpdateLeadersCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateLeadersCommand.java
index add55ed..5a5fc72 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/UpdateLeadersCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateLeadersCommand.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.command;
+package org.apache.fineract.cn.group.service.internal.command;
 
 import java.util.Set;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/UpdateMembersCommand.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateMembersCommand.java
similarity index 95%
rename from service/src/main/java/io/mifos/group/service/internal/command/UpdateMembersCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateMembersCommand.java
index 5b09287..dd4d86e 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/UpdateMembersCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateMembersCommand.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.command;
+package org.apache.fineract.cn.group.service.internal.command;
 
 import java.util.Set;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/handler/GroupAggregate.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/handler/GroupAggregate.java
similarity index 86%
rename from service/src/main/java/io/mifos/group/service/internal/command/handler/GroupAggregate.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/command/handler/GroupAggregate.java
index 5616337..3d99783 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/handler/GroupAggregate.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/handler/GroupAggregate.java
@@ -16,38 +16,38 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.command.handler;
+package org.apache.fineract.cn.group.service.internal.command.handler;
 
-import io.mifos.group.api.v1.EventConstants;
-import io.mifos.group.api.v1.domain.Attendee;
-import io.mifos.group.api.v1.domain.Cycle;
-import io.mifos.group.api.v1.domain.Group;
-import io.mifos.group.api.v1.domain.GroupCommand;
-import io.mifos.group.api.v1.domain.GroupDefinition;
-import io.mifos.group.api.v1.domain.SignOffMeeting;
-import io.mifos.group.service.internal.command.ActivateGroupCommand;
-import io.mifos.group.service.internal.command.CloseGroupCommand;
-import io.mifos.group.service.internal.command.CreateGroupCommand;
-import io.mifos.group.service.internal.command.CreateGroupDefinitionCommand;
-import io.mifos.group.service.internal.command.ReopenGroupCommand;
-import io.mifos.group.service.internal.command.SignOffMeetingCommand;
-import io.mifos.group.service.internal.command.UpdateAssignedEmployeeCommand;
-import io.mifos.group.service.internal.command.UpdateLeadersCommand;
-import io.mifos.group.service.internal.command.UpdateMembersCommand;
-import io.mifos.group.service.internal.mapper.AddressMapper;
-import io.mifos.group.service.internal.mapper.GroupCommandMapper;
-import io.mifos.group.service.internal.repository.AddressEntity;
-import io.mifos.group.service.internal.repository.AddressRepository;
-import io.mifos.group.service.internal.repository.AttendeeEntity;
-import io.mifos.group.service.internal.repository.AttendeeRepository;
-import io.mifos.group.service.internal.repository.GroupCommandEntity;
-import io.mifos.group.service.internal.repository.GroupCommandRepository;
-import io.mifos.group.service.internal.repository.GroupDefinitionEntity;
-import io.mifos.group.service.internal.repository.GroupDefinitionRepository;
-import io.mifos.group.service.internal.repository.GroupEntity;
-import io.mifos.group.service.internal.repository.GroupRepository;
-import io.mifos.group.service.internal.repository.MeetingEntity;
-import io.mifos.group.service.internal.repository.MeetingRepository;
+import org.apache.fineract.cn.group.api.v1.EventConstants;
+import org.apache.fineract.cn.group.api.v1.domain.Attendee;
+import org.apache.fineract.cn.group.api.v1.domain.Cycle;
+import org.apache.fineract.cn.group.api.v1.domain.Group;
+import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
+import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
+import org.apache.fineract.cn.group.api.v1.domain.SignOffMeeting;
+import org.apache.fineract.cn.group.service.internal.command.ActivateGroupCommand;
+import org.apache.fineract.cn.group.service.internal.command.CloseGroupCommand;
+import org.apache.fineract.cn.group.service.internal.command.CreateGroupCommand;
+import org.apache.fineract.cn.group.service.internal.command.CreateGroupDefinitionCommand;
+import org.apache.fineract.cn.group.service.internal.command.ReopenGroupCommand;
+import org.apache.fineract.cn.group.service.internal.command.SignOffMeetingCommand;
+import org.apache.fineract.cn.group.service.internal.command.UpdateAssignedEmployeeCommand;
+import org.apache.fineract.cn.group.service.internal.command.UpdateLeadersCommand;
+import org.apache.fineract.cn.group.service.internal.command.UpdateMembersCommand;
+import org.apache.fineract.cn.group.service.internal.mapper.AddressMapper;
+import org.apache.fineract.cn.group.service.internal.mapper.GroupCommandMapper;
+import org.apache.fineract.cn.group.service.internal.repository.AddressEntity;
+import org.apache.fineract.cn.group.service.internal.repository.AddressRepository;
+import org.apache.fineract.cn.group.service.internal.repository.AttendeeEntity;
+import org.apache.fineract.cn.group.service.internal.repository.AttendeeRepository;
+import org.apache.fineract.cn.group.service.internal.repository.GroupCommandEntity;
+import org.apache.fineract.cn.group.service.internal.repository.GroupCommandRepository;
+import org.apache.fineract.cn.group.service.internal.repository.GroupDefinitionEntity;
+import org.apache.fineract.cn.group.service.internal.repository.GroupDefinitionRepository;
+import org.apache.fineract.cn.group.service.internal.repository.GroupEntity;
+import org.apache.fineract.cn.group.service.internal.repository.GroupRepository;
+import org.apache.fineract.cn.group.service.internal.repository.MeetingEntity;
+import org.apache.fineract.cn.group.service.internal.repository.MeetingRepository;
 import java.time.Clock;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/handler/MigrationAggregate.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/handler/MigrationAggregate.java
similarity index 88%
rename from service/src/main/java/io/mifos/group/service/internal/command/handler/MigrationAggregate.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/command/handler/MigrationAggregate.java
index 64b546f..66fbd9e 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/handler/MigrationAggregate.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/handler/MigrationAggregate.java
@@ -16,11 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.command.handler;
+package org.apache.fineract.cn.group.service.internal.command.handler;
 
-import io.mifos.group.api.v1.EventConstants;
-import io.mifos.group.service.ServiceConstants;
-import io.mifos.group.service.internal.command.InitializeServiceCommand;
+import org.apache.fineract.cn.group.api.v1.EventConstants;
+import org.apache.fineract.cn.group.service.ServiceConstants;
+import org.apache.fineract.cn.group.service.internal.command.InitializeServiceCommand;
 import javax.sql.DataSource;
 import org.apache.fineract.cn.command.annotation.Aggregate;
 import org.apache.fineract.cn.command.annotation.CommandHandler;
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/AddressMapper.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/AddressMapper.java
similarity index 90%
rename from service/src/main/java/io/mifos/group/service/internal/mapper/AddressMapper.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/AddressMapper.java
index c9661e9..aad505e 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/AddressMapper.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/AddressMapper.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.mapper;
+package org.apache.fineract.cn.group.service.internal.mapper;
 
-import io.mifos.group.service.internal.repository.AddressEntity;
-import io.mifos.group.api.v1.domain.Address;
+import org.apache.fineract.cn.group.service.internal.repository.AddressEntity;
+import org.apache.fineract.cn.group.api.v1.domain.Address;
 
 public class AddressMapper {
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/AttendeeMapper.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/AttendeeMapper.java
similarity index 85%
rename from service/src/main/java/io/mifos/group/service/internal/mapper/AttendeeMapper.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/AttendeeMapper.java
index 3ebac1a..94be880 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/AttendeeMapper.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/AttendeeMapper.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.mapper;
+package org.apache.fineract.cn.group.service.internal.mapper;
 
-import io.mifos.group.api.v1.domain.Attendee;
-import io.mifos.group.service.internal.repository.AttendeeEntity;
+import org.apache.fineract.cn.group.api.v1.domain.Attendee;
+import org.apache.fineract.cn.group.service.internal.repository.AttendeeEntity;
 
 public class AttendeeMapper {
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupCommandMapper.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupCommandMapper.java
similarity index 90%
rename from service/src/main/java/io/mifos/group/service/internal/mapper/GroupCommandMapper.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupCommandMapper.java
index ec927c3..90b0027 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupCommandMapper.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupCommandMapper.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.mapper;
+package org.apache.fineract.cn.group.service.internal.mapper;
 
-import io.mifos.group.api.v1.domain.GroupCommand;
-import io.mifos.group.service.internal.repository.GroupCommandEntity;
+import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
+import org.apache.fineract.cn.group.service.internal.repository.GroupCommandEntity;
 import java.time.Clock;
 import java.time.LocalDateTime;
 import org.apache.fineract.cn.api.util.UserContextHolder;
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupDefinitionMapper.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupDefinitionMapper.java
similarity index 88%
rename from service/src/main/java/io/mifos/group/service/internal/mapper/GroupDefinitionMapper.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupDefinitionMapper.java
index 56126bc..2b33d43 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupDefinitionMapper.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupDefinitionMapper.java
@@ -16,11 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.mapper;
+package org.apache.fineract.cn.group.service.internal.mapper;
 
-import io.mifos.group.api.v1.domain.Cycle;
-import io.mifos.group.api.v1.domain.GroupDefinition;
-import io.mifos.group.service.internal.repository.GroupDefinitionEntity;
+import org.apache.fineract.cn.group.api.v1.domain.Cycle;
+import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
+import org.apache.fineract.cn.group.service.internal.repository.GroupDefinitionEntity;
 import org.apache.fineract.cn.lang.DateConverter;
 
 public class GroupDefinitionMapper {
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupMapper.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupMapper.java
similarity index 91%
rename from service/src/main/java/io/mifos/group/service/internal/mapper/GroupMapper.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupMapper.java
index 3e6512c..45c40ef 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupMapper.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupMapper.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.mapper;
+package org.apache.fineract.cn.group.service.internal.mapper;
 
-import io.mifos.group.api.v1.domain.Group;
-import io.mifos.group.service.internal.repository.GroupEntity;
+import org.apache.fineract.cn.group.api.v1.domain.Group;
+import org.apache.fineract.cn.group.service.internal.repository.GroupEntity;
 import org.apache.fineract.cn.lang.DateConverter;
 import org.springframework.util.StringUtils;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/MeetingMapper.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/MeetingMapper.java
similarity index 89%
rename from service/src/main/java/io/mifos/group/service/internal/mapper/MeetingMapper.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/MeetingMapper.java
index 122e882..2d91e1d 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/MeetingMapper.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/MeetingMapper.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.mapper;
+package org.apache.fineract.cn.group.service.internal.mapper;
 
-import io.mifos.group.api.v1.domain.Meeting;
-import io.mifos.group.service.internal.repository.MeetingEntity;
+import org.apache.fineract.cn.group.api.v1.domain.Meeting;
+import org.apache.fineract.cn.group.service.internal.repository.MeetingEntity;
 import org.apache.fineract.cn.lang.DateConverter;
 
 public class MeetingMapper {
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/AddressEntity.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AddressEntity.java
similarity index 97%
rename from service/src/main/java/io/mifos/group/service/internal/repository/AddressEntity.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AddressEntity.java
index 10fb8dd..bbdde39 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/AddressEntity.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AddressEntity.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.repository;
+package org.apache.fineract.cn.group.service.internal.repository;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/AddressRepository.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AddressRepository.java
similarity index 93%
rename from service/src/main/java/io/mifos/group/service/internal/repository/AddressRepository.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AddressRepository.java
index a6fbcff..03146b4 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/AddressRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AddressRepository.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.repository;
+package org.apache.fineract.cn.group.service.internal.repository;
 
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeEntity.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AttendeeEntity.java
similarity index 97%
rename from service/src/main/java/io/mifos/group/service/internal/repository/AttendeeEntity.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AttendeeEntity.java
index d0d525a..fa2d5d5 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeEntity.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AttendeeEntity.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.repository;
+package org.apache.fineract.cn.group.service.internal.repository;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeRepository.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AttendeeRepository.java
similarity index 94%
rename from service/src/main/java/io/mifos/group/service/internal/repository/AttendeeRepository.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AttendeeRepository.java
index 1f590e1..d50fefd 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AttendeeRepository.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.repository;
+package org.apache.fineract.cn.group.service.internal.repository;
 
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandEntity.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupCommandEntity.java
similarity index 97%
rename from service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandEntity.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupCommandEntity.java
index df46f02..7f60768 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandEntity.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupCommandEntity.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.repository;
+package org.apache.fineract.cn.group.service.internal.repository;
 
 import java.time.LocalDateTime;
 import javax.persistence.Column;
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandRepository.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupCommandRepository.java
similarity index 94%
rename from service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandRepository.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupCommandRepository.java
index bfc208f..eef9d7f 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupCommandRepository.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.repository;
+package org.apache.fineract.cn.group.service.internal.repository;
 
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionEntity.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupDefinitionEntity.java
similarity index 98%
rename from service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionEntity.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupDefinitionEntity.java
index 2fb1299..3f755b2 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionEntity.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupDefinitionEntity.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.repository;
+package org.apache.fineract.cn.group.service.internal.repository;
 
 import java.time.LocalDateTime;
 import javax.persistence.Column;
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionRepository.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupDefinitionRepository.java
similarity index 94%
rename from service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionRepository.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupDefinitionRepository.java
index 9d78198..74724ee 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupDefinitionRepository.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.repository;
+package org.apache.fineract.cn.group.service.internal.repository;
 
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupEntity.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupEntity.java
similarity index 98%
rename from service/src/main/java/io/mifos/group/service/internal/repository/GroupEntity.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupEntity.java
index b99529a..7fc37df 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/GroupEntity.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupEntity.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.repository;
+package org.apache.fineract.cn.group.service.internal.repository;
 
 import java.time.LocalDateTime;
 import javax.persistence.Column;
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupRepository.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupRepository.java
similarity index 95%
rename from service/src/main/java/io/mifos/group/service/internal/repository/GroupRepository.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupRepository.java
index d1e3d7e..0186fbf 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/GroupRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupRepository.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.repository;
+package org.apache.fineract.cn.group.service.internal.repository;
 
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/MeetingEntity.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/MeetingEntity.java
similarity index 98%
rename from service/src/main/java/io/mifos/group/service/internal/repository/MeetingEntity.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/MeetingEntity.java
index 72c50b7..86c339f 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/MeetingEntity.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/MeetingEntity.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.repository;
+package org.apache.fineract.cn.group.service.internal.repository;
 
 import java.time.LocalDate;
 import java.time.LocalDateTime;
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/MeetingRepository.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/MeetingRepository.java
similarity index 96%
rename from service/src/main/java/io/mifos/group/service/internal/repository/MeetingRepository.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/MeetingRepository.java
index 4437e6e..e8125fe 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/MeetingRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/MeetingRepository.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.repository;
+package org.apache.fineract.cn.group.service.internal.repository;
 
 import java.time.LocalDate;
 import java.util.List;
diff --git a/service/src/main/java/io/mifos/group/service/internal/service/GroupDefinitionService.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/service/GroupDefinitionService.java
similarity index 84%
rename from service/src/main/java/io/mifos/group/service/internal/service/GroupDefinitionService.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/service/GroupDefinitionService.java
index c691ae8..75e6bac 100644
--- a/service/src/main/java/io/mifos/group/service/internal/service/GroupDefinitionService.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/service/GroupDefinitionService.java
@@ -16,12 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.service;
+package org.apache.fineract.cn.group.service.internal.service;
 
-import io.mifos.group.api.v1.domain.GroupDefinition;
-import io.mifos.group.service.ServiceConstants;
-import io.mifos.group.service.internal.mapper.GroupDefinitionMapper;
-import io.mifos.group.service.internal.repository.GroupDefinitionRepository;
+import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
+import org.apache.fineract.cn.group.service.ServiceConstants;
+import org.apache.fineract.cn.group.service.internal.mapper.GroupDefinitionMapper;
+import org.apache.fineract.cn.group.service.internal.repository.GroupDefinitionRepository;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
diff --git a/service/src/main/java/io/mifos/group/service/internal/service/GroupService.java b/service/src/main/java/org/apache/fineract/cn/group/service/internal/service/GroupService.java
similarity index 79%
rename from service/src/main/java/io/mifos/group/service/internal/service/GroupService.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/internal/service/GroupService.java
index 8f3f680..d842714 100644
--- a/service/src/main/java/io/mifos/group/service/internal/service/GroupService.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/internal/service/GroupService.java
@@ -16,24 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.internal.service;
+package org.apache.fineract.cn.group.service.internal.service;
 
-import io.mifos.group.api.v1.domain.Group;
-import io.mifos.group.api.v1.domain.GroupCommand;
-import io.mifos.group.api.v1.domain.GroupPage;
-import io.mifos.group.api.v1.domain.Meeting;
-import io.mifos.group.service.ServiceConstants;
-import io.mifos.group.service.internal.mapper.AddressMapper;
-import io.mifos.group.service.internal.mapper.AttendeeMapper;
-import io.mifos.group.service.internal.mapper.GroupCommandMapper;
-import io.mifos.group.service.internal.mapper.GroupMapper;
-import io.mifos.group.service.internal.mapper.MeetingMapper;
-import io.mifos.group.service.internal.repository.AttendeeRepository;
-import io.mifos.group.service.internal.repository.GroupCommandRepository;
-import io.mifos.group.service.internal.repository.GroupEntity;
-import io.mifos.group.service.internal.repository.GroupRepository;
-import io.mifos.group.service.internal.repository.MeetingEntity;
-import io.mifos.group.service.internal.repository.MeetingRepository;
+import org.apache.fineract.cn.group.api.v1.domain.Group;
+import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
+import org.apache.fineract.cn.group.api.v1.domain.GroupPage;
+import org.apache.fineract.cn.group.api.v1.domain.Meeting;
+import org.apache.fineract.cn.group.service.ServiceConstants;
+import org.apache.fineract.cn.group.service.internal.mapper.AddressMapper;
+import org.apache.fineract.cn.group.service.internal.mapper.AttendeeMapper;
+import org.apache.fineract.cn.group.service.internal.mapper.GroupCommandMapper;
+import org.apache.fineract.cn.group.service.internal.mapper.GroupMapper;
+import org.apache.fineract.cn.group.service.internal.mapper.MeetingMapper;
+import org.apache.fineract.cn.group.service.internal.repository.AttendeeRepository;
+import org.apache.fineract.cn.group.service.internal.repository.GroupCommandRepository;
+import org.apache.fineract.cn.group.service.internal.repository.GroupEntity;
+import org.apache.fineract.cn.group.service.internal.repository.GroupRepository;
+import org.apache.fineract.cn.group.service.internal.repository.MeetingEntity;
+import org.apache.fineract.cn.group.service.internal.repository.MeetingRepository;
 import java.time.Clock;
 import java.time.LocalDate;
 import java.util.List;
diff --git a/service/src/main/java/io/mifos/group/service/rest/GroupDefinitionRestController.java b/service/src/main/java/org/apache/fineract/cn/group/service/rest/GroupDefinitionRestController.java
similarity index 91%
rename from service/src/main/java/io/mifos/group/service/rest/GroupDefinitionRestController.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/rest/GroupDefinitionRestController.java
index 8cee95f..075427f 100644
--- a/service/src/main/java/io/mifos/group/service/rest/GroupDefinitionRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/rest/GroupDefinitionRestController.java
@@ -16,12 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.rest;
+package org.apache.fineract.cn.group.service.rest;
 
-import io.mifos.group.api.v1.domain.GroupDefinition;
-import io.mifos.group.service.ServiceConstants;
-import io.mifos.group.service.internal.command.CreateGroupDefinitionCommand;
-import io.mifos.group.service.internal.service.GroupDefinitionService;
+import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
+import org.apache.fineract.cn.group.service.ServiceConstants;
+import org.apache.fineract.cn.group.service.internal.command.CreateGroupDefinitionCommand;
+import org.apache.fineract.cn.group.service.internal.service.GroupDefinitionService;
 import java.util.List;
 import javax.validation.Valid;
 import org.apache.fineract.cn.anubis.annotation.AcceptedTokenType;
diff --git a/service/src/main/java/io/mifos/group/service/rest/GroupRestController.java b/service/src/main/java/org/apache/fineract/cn/group/service/rest/GroupRestController.java
similarity index 88%
rename from service/src/main/java/io/mifos/group/service/rest/GroupRestController.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/rest/GroupRestController.java
index 9e25f64..51e66cd 100644
--- a/service/src/main/java/io/mifos/group/service/rest/GroupRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/rest/GroupRestController.java
@@ -16,25 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.rest;
+package org.apache.fineract.cn.group.service.rest;
 
-import io.mifos.group.api.v1.domain.AssignedEmployeeHolder;
-import io.mifos.group.api.v1.domain.Group;
-import io.mifos.group.api.v1.domain.GroupCommand;
-import io.mifos.group.api.v1.domain.GroupPage;
-import io.mifos.group.api.v1.domain.Meeting;
-import io.mifos.group.api.v1.domain.SignOffMeeting;
-import io.mifos.group.service.ServiceConstants;
-import io.mifos.group.service.internal.command.ActivateGroupCommand;
-import io.mifos.group.service.internal.command.CloseGroupCommand;
-import io.mifos.group.service.internal.command.CreateGroupCommand;
-import io.mifos.group.service.internal.command.ReopenGroupCommand;
-import io.mifos.group.service.internal.command.SignOffMeetingCommand;
-import io.mifos.group.service.internal.command.UpdateAssignedEmployeeCommand;
-import io.mifos.group.service.internal.command.UpdateLeadersCommand;
-import io.mifos.group.service.internal.command.UpdateMembersCommand;
-import io.mifos.group.service.internal.service.GroupDefinitionService;
-import io.mifos.group.service.internal.service.GroupService;
+import org.apache.fineract.cn.group.api.v1.domain.AssignedEmployeeHolder;
+import org.apache.fineract.cn.group.api.v1.domain.Group;
+import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
+import org.apache.fineract.cn.group.api.v1.domain.GroupPage;
+import org.apache.fineract.cn.group.api.v1.domain.Meeting;
+import org.apache.fineract.cn.group.api.v1.domain.SignOffMeeting;
+import org.apache.fineract.cn.group.service.ServiceConstants;
+import org.apache.fineract.cn.group.service.internal.command.ActivateGroupCommand;
+import org.apache.fineract.cn.group.service.internal.command.CloseGroupCommand;
+import org.apache.fineract.cn.group.service.internal.command.CreateGroupCommand;
+import org.apache.fineract.cn.group.service.internal.command.ReopenGroupCommand;
+import org.apache.fineract.cn.group.service.internal.command.SignOffMeetingCommand;
+import org.apache.fineract.cn.group.service.internal.command.UpdateAssignedEmployeeCommand;
+import org.apache.fineract.cn.group.service.internal.command.UpdateLeadersCommand;
+import org.apache.fineract.cn.group.service.internal.command.UpdateMembersCommand;
+import org.apache.fineract.cn.group.service.internal.service.GroupDefinitionService;
+import org.apache.fineract.cn.group.service.internal.service.GroupService;
 import java.util.List;
 import java.util.Set;
 import javax.validation.Valid;
diff --git a/service/src/main/java/io/mifos/group/service/rest/MigrationRestController.java b/service/src/main/java/org/apache/fineract/cn/group/service/rest/MigrationRestController.java
similarity index 92%
rename from service/src/main/java/io/mifos/group/service/rest/MigrationRestController.java
rename to service/src/main/java/org/apache/fineract/cn/group/service/rest/MigrationRestController.java
index a1342cc..ebd850e 100644
--- a/service/src/main/java/io/mifos/group/service/rest/MigrationRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/service/rest/MigrationRestController.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.mifos.group.service.rest;
+package org.apache.fineract.cn.group.service.rest;
 
-import io.mifos.group.service.ServiceConstants;
-import io.mifos.group.service.internal.command.InitializeServiceCommand;
+import org.apache.fineract.cn.group.service.ServiceConstants;
+import org.apache.fineract.cn.group.service.internal.command.InitializeServiceCommand;
 import org.apache.fineract.cn.anubis.annotation.AcceptedTokenType;
 import org.apache.fineract.cn.anubis.annotation.Permittable;
 import org.apache.fineract.cn.command.gateway.CommandGateway;


[fineract-cn-group] 21/40: Revert "Document the Group API"

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 4cb416fe55d3be4f3fefcbfb8ba7550f4193a871
Author: Isaac Kamga <u2...@gmail.com>
AuthorDate: Sat Jun 9 15:31:39 2018 +0100

    Revert "Document the Group API"
---
 service/build.gradle                               |  20 +-
 service/src/doc/asciidoc/api-docs.adoc             |  89 ---
 .../curl-request.adoc                              |   4 -
 .../http-request.adoc                              |  10 -
 .../http-response.adoc                             |   5 -
 .../httpie-request.adoc                            |   4 -
 .../should-activate-command/curl-request.adoc      |   4 -
 .../should-activate-command/http-request.adoc      |  10 -
 .../should-activate-command/http-response.adoc     |   5 -
 .../should-activate-command/httpie-request.adoc    |   4 -
 .../should-create-group/curl-request.adoc          |   4 -
 .../should-create-group/http-request.adoc          |  10 -
 .../should-create-group/http-response.adoc         |   5 -
 .../should-create-group/httpie-request.adoc        |   4 -
 .../curl-request.adoc                              |   4 -
 .../http-request.adoc                              |  10 -
 .../http-response.adoc                             |   5 -
 .../httpie-request.adoc                            |   4 -
 .../should-update-leaders/curl-request.adoc        |   4 -
 .../should-update-leaders/http-request.adoc        |  10 -
 .../should-update-leaders/http-response.adoc       |   5 -
 .../should-update-leaders/httpie-request.adoc      |   4 -
 .../should-update-members/curl-request.adoc        |   4 -
 .../should-update-members/http-request.adoc        |  10 -
 .../should-update-members/http-response.adoc       |   5 -
 .../should-update-members/httpie-request.adoc      |   4 -
 service/src/doc/html5/html5/api-docs.html          | 648 ---------------------
 .../org/apache/fineract/cn/group/TestGroup.java    | 335 -----------
 .../fineract/cn/group/TestGroupDefinition.java     | 181 ------
 .../listener/GroupDefinitionEventListener.java     |  50 --
 .../cn/group/listener/GroupEventListener.java      |  70 ---
 .../cn/group/listener/MigrationEventListener.java  |  50 --
 .../cn/group/util/GroupDefinitionGenerator.java    |  44 --
 .../fineract/cn/group/util/GroupGenerator.java     |  62 --
 34 files changed, 1 insertion(+), 1686 deletions(-)

diff --git a/service/build.gradle b/service/build.gradle
index d06cf5d..11b1a51 100644
--- a/service/build.gradle
+++ b/service/build.gradle
@@ -26,7 +26,6 @@ buildscript {
 
     dependencies {
         classpath ("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
-        classpath("org.asciidoctor:asciidoctor-gradle-plugin:1.5.3")
     }
 }
 
@@ -36,7 +35,7 @@ plugins {
 }
 
 apply from: '../shared.gradle'
-apply plugin: 'org.asciidoctor.convert'
+
 apply plugin: 'spring-boot'
 
 springBoot {
@@ -59,23 +58,6 @@ dependencies {
             [group: 'org.apache.fineract.cn', name: 'command', version: versions.frameworkcommand],
             [group: 'org.hibernate', name: 'hibernate-validator', version: versions.validator]
     )
-    testCompile(
-            [group: 'org.apache.fineract.cn.group', name: 'api', version: project.version],
-            [group: 'org.apache.fineract.cn', name: 'api', version: versions.frameworkapi],
-            [group: 'org.apache.fineract.cn', name: 'test', version: versions.frameworktest],
-            [group: 'org.apache.fineract.cn.anubis', name: 'test', version: versions.frameworkanubis],
-            [group: 'org.springframework.restdocs', name: 'spring-restdocs-mockmvc'],
-            [group: 'org.springframework.boot', name: 'spring-boot-starter-test'],
-            [group: 'junit', name: 'junit', version: '4.12']
-    )
-}
-
-asciidoctor {
-    sourceDir 'src/doc/asciidoc/'
-    outputDir 'src/doc/html5'
-    options backend: "html", doctype: "book"
-    attributes "source-highlighter": "highlightjs", \
-                'snippets': file('src/doc/generated-snippets/')
 }
 
 publishToMavenLocal.dependsOn bootRepackage
diff --git a/service/src/doc/asciidoc/api-docs.adoc b/service/src/doc/asciidoc/api-docs.adoc
deleted file mode 100644
index 0c8d64b..0000000
--- a/service/src/doc/asciidoc/api-docs.adoc
+++ /dev/null
@@ -1,89 +0,0 @@
-== Apache Fineract CN Group Management API Documentation ==
-
-== Groups ==
-
-==== Create A Group ====
-
-.curl-request
-include::{snippets}/test-group/should-create-group/curl-request.adoc[]
-
-.http-request
-include::{snippets}/test-group/should-create-group/http-request.adoc[]
-
-.http-response
-include::{snippets}/test-group/should-create-group/http-response.adoc[]
-
-.httpie-request
-include::{snippets}/test-group/should-create-group/httpie-request.adoc[]
-
-==== Activate A Group ====
-
-.curl-request
-include::{snippets}/test-group/should-activate-command/curl-request.adoc[]
-
-.http-request
-include::{snippets}/test-group/should-activate-command/http-request.adoc[]
-
-.http-response
-include::{snippets}/test-group/should-activate-command/http-response.adoc[]
-
-.httpie-request
-include::{snippets}/test-group/should-activate-command/httpie-request.adoc[]
-
-==== Update Assigned Employee ====
-
-.curl-request
-include::{snippets}/test-group/should-update-assigned-employee/curl-request.adoc[]
-
-.http-request
-include::{snippets}/test-group/should-update-assigned-employee/http-request.adoc[]
-
-.http-response
-include::{snippets}/test-group/should-update-assigned-employee/http-response.adoc[]
-
-.httpie-request
-include::{snippets}/test-group/should-update-assigned-employee/httpie-request.adoc[]
-
-==== Update Group Leaders ====
-
-.curl-request
-include::{snippets}/test-group/should-update-leaders/curl-request.adoc[]
-
-.http-request
-include::{snippets}/test-group/should-update-leaders/http-request.adoc[]
-
-.http-response
-include::{snippets}/test-group/should-update-leaders/http-response.adoc[]
-
-.httpie-request
-include::{snippets}/test-group/should-update-leaders/httpie-request.adoc[]
-
-==== Update Group Members ====
-
-.curl-request
-include::{snippets}/test-group/should-update-members/curl-request.adoc[]
-
-.http-request
-include::{snippets}/test-group/should-update-members/http-request.adoc[]
-
-.http-response
-include::{snippets}/test-group/should-update-members/http-response.adoc[]
-
-.httpie-request
-include::{snippets}/test-group/should-update-members/httpie-request.adoc[]
-
-== Group Definitions ==
-
-==== Create A Group Definition ====
-
-.curl-request
-include::{snippets}/test-group-definition/should-create-group-definition/curl-request.adoc[]
-
-.http-request
-include::{snippets}/test-group-definition/should-create-group-definition/http-request.adoc[]
-
-.http-response
-include::{snippets}/test-group-definition/should-create-group-definition/http-response.adoc[]
-
-.httpie-request
-include::{snippets}/test-group-definition/should-create-group-definition/httpie-request.adoc[]
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/curl-request.adoc b/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/curl-request.adoc
deleted file mode 100644
index a6bf5fa..0000000
--- a/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/curl-request.adoc
+++ /dev/null
@@ -1,4 +0,0 @@
-[source,bash]
-----
-$ curl 'http://localhost:8080/group/v1/definitions' -i -X POST -H 'Accept: */*' -H 'Content-Type: application/json' -d 'f56iUIk58phhM1kgYJpSsXjoxrIESX7K'
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/http-request.adoc b/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/http-request.adoc
deleted file mode 100644
index ea1512c..0000000
--- a/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/http-request.adoc
+++ /dev/null
@@ -1,10 +0,0 @@
-[source,http,options="nowrap"]
-----
-POST /group/v1/definitions HTTP/1.1
-Accept: */*
-Content-Type: application/json
-Host: localhost:8080
-Content-Length: 32
-
-f56iUIk58phhM1kgYJpSsXjoxrIESX7K
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/http-response.adoc b/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/http-response.adoc
deleted file mode 100644
index f3b256d..0000000
--- a/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/http-response.adoc
+++ /dev/null
@@ -1,5 +0,0 @@
-[source,http,options="nowrap"]
-----
-HTTP/1.1 404 Not Found
-
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/httpie-request.adoc b/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/httpie-request.adoc
deleted file mode 100644
index f3dda49..0000000
--- a/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/httpie-request.adoc
+++ /dev/null
@@ -1,4 +0,0 @@
-[source,bash]
-----
-$ echo 'f56iUIk58phhM1kgYJpSsXjoxrIESX7K' | http POST 'http://localhost:8080/group/v1/definitions' 'Accept:*/*' 'Content-Type:application/json'
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-activate-command/curl-request.adoc b/service/src/doc/generated-snippets/test-group/should-activate-command/curl-request.adoc
deleted file mode 100644
index f91951f..0000000
--- a/service/src/doc/generated-snippets/test-group/should-activate-command/curl-request.adoc
+++ /dev/null
@@ -1,4 +0,0 @@
-[source,bash]
-----
-$ curl 'http://localhost:8080/group/v1/groups/G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6/commands' -i -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6'
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-activate-command/http-request.adoc b/service/src/doc/generated-snippets/test-group/should-activate-command/http-request.adoc
deleted file mode 100644
index 3a29a86..0000000
--- a/service/src/doc/generated-snippets/test-group/should-activate-command/http-request.adoc
+++ /dev/null
@@ -1,10 +0,0 @@
-[source,http,options="nowrap"]
-----
-POST /group/v1/groups/G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6/commands HTTP/1.1
-Accept: application/json
-Content-Type: application/json
-Host: localhost:8080
-Content-Length: 32
-
-G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-activate-command/http-response.adoc b/service/src/doc/generated-snippets/test-group/should-activate-command/http-response.adoc
deleted file mode 100644
index f3b256d..0000000
--- a/service/src/doc/generated-snippets/test-group/should-activate-command/http-response.adoc
+++ /dev/null
@@ -1,5 +0,0 @@
-[source,http,options="nowrap"]
-----
-HTTP/1.1 404 Not Found
-
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-activate-command/httpie-request.adoc b/service/src/doc/generated-snippets/test-group/should-activate-command/httpie-request.adoc
deleted file mode 100644
index baeda7e..0000000
--- a/service/src/doc/generated-snippets/test-group/should-activate-command/httpie-request.adoc
+++ /dev/null
@@ -1,4 +0,0 @@
-[source,bash]
-----
-$ echo 'G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6' | http POST 'http://localhost:8080/group/v1/groups/G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6/commands' 'Accept:application/json' 'Content-Type:application/json'
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-create-group/curl-request.adoc b/service/src/doc/generated-snippets/test-group/should-create-group/curl-request.adoc
deleted file mode 100644
index 6ed8be5..0000000
--- a/service/src/doc/generated-snippets/test-group/should-create-group/curl-request.adoc
+++ /dev/null
@@ -1,4 +0,0 @@
-[source,bash]
-----
-$ curl 'http://localhost:8080/group/v1/groups' -i -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'K083BUcl4wFgwV5vfyNevzMcU5Skz3d5'
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-create-group/http-request.adoc b/service/src/doc/generated-snippets/test-group/should-create-group/http-request.adoc
deleted file mode 100644
index 6dcda88..0000000
--- a/service/src/doc/generated-snippets/test-group/should-create-group/http-request.adoc
+++ /dev/null
@@ -1,10 +0,0 @@
-[source,http,options="nowrap"]
-----
-POST /group/v1/groups HTTP/1.1
-Accept: application/json
-Content-Type: application/json
-Host: localhost:8080
-Content-Length: 32
-
-K083BUcl4wFgwV5vfyNevzMcU5Skz3d5
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-create-group/http-response.adoc b/service/src/doc/generated-snippets/test-group/should-create-group/http-response.adoc
deleted file mode 100644
index f3b256d..0000000
--- a/service/src/doc/generated-snippets/test-group/should-create-group/http-response.adoc
+++ /dev/null
@@ -1,5 +0,0 @@
-[source,http,options="nowrap"]
-----
-HTTP/1.1 404 Not Found
-
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-create-group/httpie-request.adoc b/service/src/doc/generated-snippets/test-group/should-create-group/httpie-request.adoc
deleted file mode 100644
index 9395e0d..0000000
--- a/service/src/doc/generated-snippets/test-group/should-create-group/httpie-request.adoc
+++ /dev/null
@@ -1,4 +0,0 @@
-[source,bash]
-----
-$ echo 'K083BUcl4wFgwV5vfyNevzMcU5Skz3d5' | http POST 'http://localhost:8080/group/v1/groups' 'Accept:application/json' 'Content-Type:application/json'
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/curl-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/curl-request.adoc
deleted file mode 100644
index a61f6d5..0000000
--- a/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/curl-request.adoc
+++ /dev/null
@@ -1,4 +0,0 @@
-[source,bash]
-----
-$ curl 'http://localhost:8080/group/v1/groups/KsbSd2TGf95VYynRjiZfXiUX75ahKD8v/employee' -i -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'KsbSd2TGf95VYynRjiZfXiUX75ahKD8v'
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/http-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/http-request.adoc
deleted file mode 100644
index 0487bbe..0000000
--- a/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/http-request.adoc
+++ /dev/null
@@ -1,10 +0,0 @@
-[source,http,options="nowrap"]
-----
-PUT /group/v1/groups/KsbSd2TGf95VYynRjiZfXiUX75ahKD8v/employee HTTP/1.1
-Accept: application/json
-Content-Type: application/json
-Host: localhost:8080
-Content-Length: 32
-
-KsbSd2TGf95VYynRjiZfXiUX75ahKD8v
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/http-response.adoc b/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/http-response.adoc
deleted file mode 100644
index f3b256d..0000000
--- a/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/http-response.adoc
+++ /dev/null
@@ -1,5 +0,0 @@
-[source,http,options="nowrap"]
-----
-HTTP/1.1 404 Not Found
-
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/httpie-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/httpie-request.adoc
deleted file mode 100644
index 6a43f7c..0000000
--- a/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/httpie-request.adoc
+++ /dev/null
@@ -1,4 +0,0 @@
-[source,bash]
-----
-$ echo 'KsbSd2TGf95VYynRjiZfXiUX75ahKD8v' | http PUT 'http://localhost:8080/group/v1/groups/KsbSd2TGf95VYynRjiZfXiUX75ahKD8v/employee' 'Accept:application/json' 'Content-Type:application/json'
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-leaders/curl-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-leaders/curl-request.adoc
deleted file mode 100644
index a47e208..0000000
--- a/service/src/doc/generated-snippets/test-group/should-update-leaders/curl-request.adoc
+++ /dev/null
@@ -1,4 +0,0 @@
-[source,bash]
-----
-$ curl 'http://localhost:8080/group/v1/groups/DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera/leaders' -i -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera'
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-leaders/http-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-leaders/http-request.adoc
deleted file mode 100644
index b870cd0..0000000
--- a/service/src/doc/generated-snippets/test-group/should-update-leaders/http-request.adoc
+++ /dev/null
@@ -1,10 +0,0 @@
-[source,http,options="nowrap"]
-----
-PUT /group/v1/groups/DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera/leaders HTTP/1.1
-Accept: application/json
-Content-Type: application/json
-Host: localhost:8080
-Content-Length: 32
-
-DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-leaders/http-response.adoc b/service/src/doc/generated-snippets/test-group/should-update-leaders/http-response.adoc
deleted file mode 100644
index f3b256d..0000000
--- a/service/src/doc/generated-snippets/test-group/should-update-leaders/http-response.adoc
+++ /dev/null
@@ -1,5 +0,0 @@
-[source,http,options="nowrap"]
-----
-HTTP/1.1 404 Not Found
-
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-leaders/httpie-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-leaders/httpie-request.adoc
deleted file mode 100644
index 6bbd4dc..0000000
--- a/service/src/doc/generated-snippets/test-group/should-update-leaders/httpie-request.adoc
+++ /dev/null
@@ -1,4 +0,0 @@
-[source,bash]
-----
-$ echo 'DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera' | http PUT 'http://localhost:8080/group/v1/groups/DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera/leaders' 'Accept:application/json' 'Content-Type:application/json'
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-members/curl-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-members/curl-request.adoc
deleted file mode 100644
index 25101f4..0000000
--- a/service/src/doc/generated-snippets/test-group/should-update-members/curl-request.adoc
+++ /dev/null
@@ -1,4 +0,0 @@
-[source,bash]
-----
-$ curl 'http://localhost:8080/group/v1/groups/t7r2iJxzq957elzLHGdoa7JDedy2h0sQ/members' -i -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -d 't7r2iJxzq957elzLHGdoa7JDedy2h0sQ'
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-members/http-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-members/http-request.adoc
deleted file mode 100644
index 06e9713..0000000
--- a/service/src/doc/generated-snippets/test-group/should-update-members/http-request.adoc
+++ /dev/null
@@ -1,10 +0,0 @@
-[source,http,options="nowrap"]
-----
-PUT /group/v1/groups/t7r2iJxzq957elzLHGdoa7JDedy2h0sQ/members HTTP/1.1
-Accept: application/json
-Content-Type: application/json
-Host: localhost:8080
-Content-Length: 32
-
-t7r2iJxzq957elzLHGdoa7JDedy2h0sQ
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-members/http-response.adoc b/service/src/doc/generated-snippets/test-group/should-update-members/http-response.adoc
deleted file mode 100644
index f3b256d..0000000
--- a/service/src/doc/generated-snippets/test-group/should-update-members/http-response.adoc
+++ /dev/null
@@ -1,5 +0,0 @@
-[source,http,options="nowrap"]
-----
-HTTP/1.1 404 Not Found
-
-----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-members/httpie-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-members/httpie-request.adoc
deleted file mode 100644
index c785bfc..0000000
--- a/service/src/doc/generated-snippets/test-group/should-update-members/httpie-request.adoc
+++ /dev/null
@@ -1,4 +0,0 @@
-[source,bash]
-----
-$ echo 't7r2iJxzq957elzLHGdoa7JDedy2h0sQ' | http PUT 'http://localhost:8080/group/v1/groups/t7r2iJxzq957elzLHGdoa7JDedy2h0sQ/members' 'Accept:application/json' 'Content-Type:application/json'
-----
\ No newline at end of file
diff --git a/service/src/doc/html5/html5/api-docs.html b/service/src/doc/html5/html5/api-docs.html
deleted file mode 100644
index 41b233c..0000000
--- a/service/src/doc/html5/html5/api-docs.html
+++ /dev/null
@@ -1,648 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-<meta charset="UTF-8">
-<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
-<meta name="viewport" content="width=device-width, initial-scale=1.0">
-<meta name="generator" content="Asciidoctor 1.5.3">
-<title>Apache Fineract CN Group Management API Documentation</title>
-<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
-<style>
-/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
-/* Remove comment around @import statement below when using as a custom stylesheet */
-/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
-article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
-audio,canvas,video{display:inline-block}
-audio:not([controls]){display:none;height:0}
-[hidden],template{display:none}
-script{display:none!important}
-html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
-body{margin:0}
-a{background:transparent}
-a:focus{outline:thin dotted}
-a:active,a:hover{outline:0}
-h1{font-size:2em;margin:.67em 0}
-abbr[title]{border-bottom:1px dotted}
-b,strong{font-weight:bold}
-dfn{font-style:italic}
-hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
-mark{background:#ff0;color:#000}
-code,kbd,pre,samp{font-family:monospace;font-size:1em}
-pre{white-space:pre-wrap}
-q{quotes:"\201C" "\201D" "\2018" "\2019"}
-small{font-size:80%}
-sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
-sup{top:-.5em}
-sub{bottom:-.25em}
-img{border:0}
-svg:not(:root){overflow:hidden}
-figure{margin:0}
-fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
-legend{border:0;padding:0}
-button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
-button,input{line-height:normal}
-button,select{text-transform:none}
-button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
-button[disabled],html input[disabled]{cursor:default}
-input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
-input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
-input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}
-button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
-textarea{overflow:auto;vertical-align:top}
-table{border-collapse:collapse;border-spacing:0}
-*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
-html,body{font-size:100%}
-body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto}
-a:hover{cursor:pointer}
-img,object,embed{max-width:100%;height:auto}
-object,embed{height:100%}
-img{-ms-interpolation-mode:bicubic}
-.left{float:left!important}
-.right{float:right!important}
-.text-left{text-align:left!important}
-.text-right{text-align:right!important}
-.text-center{text-align:center!important}
-.text-justify{text-align:justify!important}
-.hide{display:none}
-body{-webkit-font-smoothing:antialiased}
-img,object,svg{display:inline-block;vertical-align:middle}
-textarea{height:auto;min-height:50px}
-select{width:100%}
-.center{margin-left:auto;margin-right:auto}
-.spread{width:100%}
-p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}
-.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
-div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
-a{color:#2156a5;text-decoration:underline;line-height:inherit}
-a:hover,a:focus{color:#1d4b8f}
-a img{border:none}
-p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
-p aside{font-size:.875em;line-height:1.35;font-style:italic}
-h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
-h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
-h1{font-size:2.125em}
-h2{font-size:1.6875em}
-h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
-h4,h5{font-size:1.125em}
-h6{font-size:1em}
-hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
-em,i{font-style:italic;line-height:inherit}
-strong,b{font-weight:bold;line-height:inherit}
-small{font-size:60%;line-height:inherit}
-code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
-ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
-ul,ol,ul.no-bullet,ol.no-bullet{margin-left:1.5em}
-ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
-ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
-ul.square{list-style-type:square}
-ul.circle{list-style-type:circle}
-ul.disc{list-style-type:disc}
-ul.no-bullet{list-style:none}
-ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
-dl dt{margin-bottom:.3125em;font-weight:bold}
-dl dd{margin-bottom:1.25em}
-abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
-abbr{text-transform:none}
-blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
-blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
-blockquote cite:before{content:"\2014 \0020"}
-blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
-blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
-@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
-h1{font-size:2.75em}
-h2{font-size:2.3125em}
-h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
-h4{font-size:1.4375em}}
-table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
-table thead,table tfoot{background:#f7f8f7;font-weight:bold}
-table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
-table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
-table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
-table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
-body{tab-size:4}
-h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
-h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
-.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}
-.clearfix:after,.float-group:after{clear:both}
-*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
-pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
-.keyseq{color:rgba(51,51,51,.8)}
-kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
-.keyseq kbd:first-child{margin-left:0}
-.keyseq kbd:last-child{margin-right:0}
-.menuseq,.menu{color:rgba(0,0,0,.8)}
-b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}
-b.button:before{content:"[";padding:0 3px 0 2px}
-b.button:after{content:"]";padding:0 2px 0 3px}
-p a>code:hover{color:rgba(0,0,0,.9)}
-#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
-#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}
-#header:after,#content:after,#footnotes:after,#footer:after{clear:both}
-#content{margin-top:1.25em}
-#content:before{content:none}
-#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
-#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}
-#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}
-#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
-#header .details span:first-child{margin-left:-.125em}
-#header .details span.email a{color:rgba(0,0,0,.85)}
-#header .details br{display:none}
-#header .details br+span:before{content:"\00a0\2013\00a0"}
-#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
-#header .details br+span#revremark:before{content:"\00a0|\00a0"}
-#header #revnumber{text-transform:capitalize}
-#header #revnumber:after{content:"\00a0"}
-#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
-#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}
-#toc>ul{margin-left:.125em}
-#toc ul.sectlevel0>li>a{font-style:italic}
-#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
-#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
-#toc li{line-height:1.3334;margin-top:.3334em}
-#toc a{text-decoration:none}
-#toc a:active{text-decoration:underline}
-#toctitle{color:#7a2518;font-size:1.2em}
-@media only screen and (min-width:768px){#toctitle{font-size:1.375em}
-body.toc2{padding-left:15em;padding-right:0}
-#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
-#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
-#toc.toc2>ul{font-size:.9em;margin-bottom:0}
-#toc.toc2 ul ul{margin-left:0;padding-left:1em}
-#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
-body.toc2.toc-right{padding-left:0;padding-right:15em}
-body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}
-@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
-#toc.toc2{width:20em}
-#toc.toc2 #toctitle{font-size:1.375em}
-#toc.toc2>ul{font-size:.95em}
-#toc.toc2 ul ul{padding-left:1.25em}
-body.toc2.toc-right{padding-left:0;padding-right:20em}}
-#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
-#content #toc>:first-child{margin-top:0}
-#content #toc>:last-child{margin-bottom:0}
-#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
-#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
-.sect1{padding-bottom:.625em}
-@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}
-.sect1+.sect1{border-top:1px solid #efefed}
-#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
-#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
-#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
-#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
-#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
-.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
-.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
-table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}
-.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}
-table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}
-.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
-.admonitionblock>table td.icon{text-align:center;width:80px}
-.admonitionblock>table td.icon img{max-width:none}
-.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
-.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}
-.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
-.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
-.exampleblock>.content>:first-child{margin-top:0}
-.exampleblock>.content>:last-child{margin-bottom:0}
-.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
-.sidebarblock>:first-child{margin-top:0}
-.sidebarblock>:last-child{margin-bottom:0}
-.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
-.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
-.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
-.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
-.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}
-.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}
-@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
-@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
-.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
-.listingblock pre.highlightjs{padding:0}
-.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
-.listingblock pre.prettyprint{border-width:0}
-.listingblock>.content{position:relative}
-.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
-.listingblock:hover code[data-lang]:before{display:block}
-.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}
-.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}
-table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
-table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
-table.pyhltable td.code{padding-left:.75em;padding-right:0}
-pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}
-pre.pygments .lineno{display:inline-block;margin-right:.25em}
-table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
-.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
-.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
-.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
-.quoteblock blockquote{margin:0;padding:0;border:0}
-.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
-.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
-.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}
-.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}
-.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}
-.quoteblock .quoteblock blockquote:before{display:none}
-.verseblock{margin:0 1em 1.25em 1em}
-.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
-.verseblock pre strong{font-weight:400}
-.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
-.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
-.quoteblock .attribution br,.verseblock .attribution br{display:none}
-.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
-.quoteblock.abstract{margin:0 0 1.25em 0;display:block}
-.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}
-.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}
-table.tableblock{max-width:100%;border-collapse:separate}
-table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}
-table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
-table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0}
-table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0}
-table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0}
-table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0}
-table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0}
-table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0}
-table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0}
-table.frame-all{border-width:1px}
-table.frame-sides{border-width:0 1px}
-table.frame-topbot{border-width:1px 0}
-th.halign-left,td.halign-left{text-align:left}
-th.halign-right,td.halign-right{text-align:right}
-th.halign-center,td.halign-center{text-align:center}
-th.valign-top,td.valign-top{vertical-align:top}
-th.valign-bottom,td.valign-bottom{vertical-align:bottom}
-th.valign-middle,td.valign-middle{vertical-align:middle}
-table thead th,table tfoot th{font-weight:bold}
-tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
-tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
-p.tableblock>code:only-child{background:none;padding:0}
-p.tableblock{font-size:1em}
-td>div.verse{white-space:pre}
-ol{margin-left:1.75em}
-ul li ol{margin-left:1.5em}
-dl dd{margin-left:1.125em}
-dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
-ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
-ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none}
-ul.unstyled,ol.unnumbered,ul.checklist{margin-left:.625em}
-ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1em;font-size:.85em}
-ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px}
-ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}
-ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}
-ul.inline>li>*{display:block}
-.unstyled dl dt{font-weight:400;font-style:normal}
-ol.arabic{list-style-type:decimal}
-ol.decimal{list-style-type:decimal-leading-zero}
-ol.loweralpha{list-style-type:lower-alpha}
-ol.upperalpha{list-style-type:upper-alpha}
-ol.lowerroman{list-style-type:lower-roman}
-ol.upperroman{list-style-type:upper-roman}
-ol.lowergreek{list-style-type:lower-greek}
-.hdlist>table,.colist>table{border:0;background:none}
-.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
-td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
-td.hdlist1{font-weight:bold;padding-bottom:1.25em}
-.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
-.colist>table tr>td:first-of-type{padding:0 .75em;line-height:1}
-.colist>table tr>td:last-of-type{padding:.25em 0}
-.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
-.imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0}
-.imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em}
-.imageblock>.title{margin-bottom:0}
-.imageblock.thumb,.imageblock.th{border-width:6px}
-.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
-.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
-.image.left{margin-right:.625em}
-.image.right{margin-left:.625em}
-a.image{text-decoration:none;display:inline-block}
-a.image object{pointer-events:none}
-sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
-sup.footnote a,sup.footnoteref a{text-decoration:none}
-sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
-#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
-#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}
-#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}
-#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}
-#footnotes .footnote:last-of-type{margin-bottom:0}
-#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
-.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
-.gist .file-data>table td.line-data{width:99%}
-div.unbreakable{page-break-inside:avoid}
-.big{font-size:larger}
-.small{font-size:smaller}
-.underline{text-decoration:underline}
-.overline{text-decoration:overline}
-.line-through{text-decoration:line-through}
-.aqua{color:#00bfbf}
-.aqua-background{background-color:#00fafa}
-.black{color:#000}
-.black-background{background-color:#000}
-.blue{color:#0000bf}
-.blue-background{background-color:#0000fa}
-.fuchsia{color:#bf00bf}
-.fuchsia-background{background-color:#fa00fa}
-.gray{color:#606060}
-.gray-background{background-color:#7d7d7d}
-.green{color:#006000}
-.green-background{background-color:#007d00}
-.lime{color:#00bf00}
-.lime-background{background-color:#00fa00}
-.maroon{color:#600000}
-.maroon-background{background-color:#7d0000}
-.navy{color:#000060}
-.navy-background{background-color:#00007d}
-.olive{color:#606000}
-.olive-background{background-color:#7d7d00}
-.purple{color:#600060}
-.purple-background{background-color:#7d007d}
-.red{color:#bf0000}
-.red-background{background-color:#fa0000}
-.silver{color:#909090}
-.silver-background{background-color:#bcbcbc}
-.teal{color:#006060}
-.teal-background{background-color:#007d7d}
-.white{color:#bfbfbf}
-.white-background{background-color:#fafafa}
-.yellow{color:#bfbf00}
-.yellow-background{background-color:#fafa00}
-span.icon>.fa{cursor:default}
-.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
-.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}
-.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
-.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}
-.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}
-.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}
-.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
-.conum[data-value] *{color:#fff!important}
-.conum[data-value]+b{display:none}
-.conum[data-value]:after{content:attr(data-value)}
-pre .conum[data-value]{position:relative;top:-.125em}
-b.conum *{color:inherit!important}
-.conum:not([data-value]):empty{display:none}
-dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
-h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
-p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
-p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
-p{margin-bottom:1.25rem}
-.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
-.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
-.print-only{display:none!important}
-@media print{@page{margin:1.25cm .75cm}
-*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
-a{color:inherit!important;text-decoration:underline!important}
-a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
-a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
-abbr[title]:after{content:" (" attr(title) ")"}
-pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
-thead{display:table-header-group}
-svg{max-width:100%}
-p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
-h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
-#toc,.sidebarblock,.exampleblock>.content{background:none!important}
-#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}
-.sect1{padding-bottom:0!important}
-.sect1+.sect1{border:0!important}
-#header>h1:first-child{margin-top:1.25rem}
-body.book #header{text-align:center}
-body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}
-body.book #header .details{border:0!important;display:block;padding:0!important}
-body.book #header .details span:first-child{margin-left:0!important}
-body.book #header .details br{display:block}
-body.book #header .details br+span:before{content:none!important}
-body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
-body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
-.listingblock code[data-lang]:before{display:block}
-#footer{background:none!important;padding:0 .9375em}
-#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}
-.hide-on-print{display:none!important}
-.print-only{display:block!important}
-.hide-for-print{display:none!important}
-.show-for-print{display:inherit!important}}
-</style>
-</head>
-<body class="book">
-<div id="header">
-</div>
-<div id="content">
-<div class="sect1">
-<h2 id="_apache_fineract_cn_group_management_api_documentation">Apache Fineract CN Group Management API Documentation</h2>
-<div class="sectionbody">
-
-</div>
-</div>
-<div class="sect1">
-<h2 id="_groups">Groups</h2>
-<div class="sectionbody">
-<div class="sect3">
-<h4 id="_create_a_group">Create A Group</h4>
-<div class="listingblock">
-<div class="title">curl-request</div>
-<div class="content">
-<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/group/v1/groups' -i -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'K083BUcl4wFgwV5vfyNevzMcU5Skz3d5'</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">http-request</div>
-<div class="content">
-<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">POST /group/v1/groups HTTP/1.1
-Accept: application/json
-Content-Type: application/json
-Host: localhost:8080
-Content-Length: 32
-
-K083BUcl4wFgwV5vfyNevzMcU5Skz3d5</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">http-response</div>
-<div class="content">
-<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">httpie-request</div>
-<div class="content">
-<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'K083BUcl4wFgwV5vfyNevzMcU5Skz3d5' | http POST 'http://localhost:8080/group/v1/groups' 'Accept:application/json' 'Content-Type:application/json'</code></pre>
-</div>
-</div>
-</div>
-<div class="sect3">
-<h4 id="_activate_a_group">Activate A Group</h4>
-<div class="listingblock">
-<div class="title">curl-request</div>
-<div class="content">
-<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/group/v1/groups/G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6/commands' -i -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6'</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">http-request</div>
-<div class="content">
-<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">POST /group/v1/groups/G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6/commands HTTP/1.1
-Accept: application/json
-Content-Type: application/json
-Host: localhost:8080
-Content-Length: 32
-
-G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">http-response</div>
-<div class="content">
-<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">httpie-request</div>
-<div class="content">
-<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6' | http POST 'http://localhost:8080/group/v1/groups/G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6/commands' 'Accept:application/json' 'Content-Type:application/json'</code></pre>
-</div>
-</div>
-</div>
-<div class="sect3">
-<h4 id="_update_assigned_employee">Update Assigned Employee</h4>
-<div class="listingblock">
-<div class="title">curl-request</div>
-<div class="content">
-<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/group/v1/groups/KsbSd2TGf95VYynRjiZfXiUX75ahKD8v/employee' -i -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'KsbSd2TGf95VYynRjiZfXiUX75ahKD8v'</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">http-request</div>
-<div class="content">
-<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">PUT /group/v1/groups/KsbSd2TGf95VYynRjiZfXiUX75ahKD8v/employee HTTP/1.1
-Accept: application/json
-Content-Type: application/json
-Host: localhost:8080
-Content-Length: 32
-
-KsbSd2TGf95VYynRjiZfXiUX75ahKD8v</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">http-response</div>
-<div class="content">
-<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">httpie-request</div>
-<div class="content">
-<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'KsbSd2TGf95VYynRjiZfXiUX75ahKD8v' | http PUT 'http://localhost:8080/group/v1/groups/KsbSd2TGf95VYynRjiZfXiUX75ahKD8v/employee' 'Accept:application/json' 'Content-Type:application/json'</code></pre>
-</div>
-</div>
-</div>
-<div class="sect3">
-<h4 id="_update_group_leaders">Update Group Leaders</h4>
-<div class="listingblock">
-<div class="title">curl-request</div>
-<div class="content">
-<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/group/v1/groups/DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera/leaders' -i -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera'</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">http-request</div>
-<div class="content">
-<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">PUT /group/v1/groups/DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera/leaders HTTP/1.1
-Accept: application/json
-Content-Type: application/json
-Host: localhost:8080
-Content-Length: 32
-
-DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">http-response</div>
-<div class="content">
-<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">httpie-request</div>
-<div class="content">
-<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera' | http PUT 'http://localhost:8080/group/v1/groups/DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera/leaders' 'Accept:application/json' 'Content-Type:application/json'</code></pre>
-</div>
-</div>
-</div>
-<div class="sect3">
-<h4 id="_update_group_members">Update Group Members</h4>
-<div class="listingblock">
-<div class="title">curl-request</div>
-<div class="content">
-<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/group/v1/groups/t7r2iJxzq957elzLHGdoa7JDedy2h0sQ/members' -i -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -d 't7r2iJxzq957elzLHGdoa7JDedy2h0sQ'</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">http-request</div>
-<div class="content">
-<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">PUT /group/v1/groups/t7r2iJxzq957elzLHGdoa7JDedy2h0sQ/members HTTP/1.1
-Accept: application/json
-Content-Type: application/json
-Host: localhost:8080
-Content-Length: 32
-
-t7r2iJxzq957elzLHGdoa7JDedy2h0sQ</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">http-response</div>
-<div class="content">
-<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">httpie-request</div>
-<div class="content">
-<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 't7r2iJxzq957elzLHGdoa7JDedy2h0sQ' | http PUT 'http://localhost:8080/group/v1/groups/t7r2iJxzq957elzLHGdoa7JDedy2h0sQ/members' 'Accept:application/json' 'Content-Type:application/json'</code></pre>
-</div>
-</div>
-</div>
-</div>
-</div>
-<div class="sect1">
-<h2 id="_group_definitions">Group Definitions</h2>
-<div class="sectionbody">
-<div class="sect3">
-<h4 id="_create_a_group_definition">Create A Group Definition</h4>
-<div class="listingblock">
-<div class="title">curl-request</div>
-<div class="content">
-<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/group/v1/definitions' -i -X POST -H 'Accept: */*' -H 'Content-Type: application/json' -d 'f56iUIk58phhM1kgYJpSsXjoxrIESX7K'</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">http-request</div>
-<div class="content">
-<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">POST /group/v1/definitions HTTP/1.1
-Accept: */*
-Content-Type: application/json
-Host: localhost:8080
-Content-Length: 32
-
-f56iUIk58phhM1kgYJpSsXjoxrIESX7K</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">http-response</div>
-<div class="content">
-<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
-</div>
-</div>
-<div class="listingblock">
-<div class="title">httpie-request</div>
-<div class="content">
-<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'f56iUIk58phhM1kgYJpSsXjoxrIESX7K' | http POST 'http://localhost:8080/group/v1/definitions' 'Accept:*/*' 'Content-Type:application/json'</code></pre>
-</div>
-</div>
-</div>
-</div>
-</div>
-</div>
-<div id="footer">
-<div id="footer-text">
-Last updated 2018-04-13 05:40:16 +01:00
-</div>
-</div>
-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/styles/github.min.css">
-<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/highlight.min.js"></script>
-<script>hljs.initHighlighting()</script>
-</body>
-</html>
\ No newline at end of file
diff --git a/service/src/test/java/org/apache/fineract/cn/group/TestGroup.java b/service/src/test/java/org/apache/fineract/cn/group/TestGroup.java
deleted file mode 100644
index e4bcaf5..0000000
--- a/service/src/test/java/org/apache/fineract/cn/group/TestGroup.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.fineract.cn.group;
-
-import org.apache.commons.lang3.RandomStringUtils;
-import org.apache.fineract.cn.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
-import org.apache.fineract.cn.api.context.AutoUserContext;
-import org.apache.fineract.cn.group.api.v1.EventConstants;
-import org.apache.fineract.cn.group.api.v1.client.GroupManager;
-import org.apache.fineract.cn.group.api.v1.domain.*;
-import org.apache.fineract.cn.group.util.GroupDefinitionGenerator;
-import org.apache.fineract.cn.group.util.GroupGenerator;
-import org.apache.fineract.cn.test.env.TestEnvironment;
-import org.apache.fineract.cn.test.fixture.TenantDataStoreContextTestRule;
-import org.apache.fineract.cn.test.fixture.cassandra.CassandraInitializer;
-import org.apache.fineract.cn.test.fixture.mariadb.MariaDBInitializer;
-import org.apache.fineract.cn.test.listener.EnableEventRecording;
-import org.apache.fineract.cn.test.listener.EventRecorder;
-import org.junit.*;
-import org.junit.rules.RuleChain;
-import org.junit.rules.TestRule;
-import org.junit.runner.RunWith;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.cloud.netflix.feign.EnableFeignClients;
-import org.springframework.cloud.netflix.ribbon.RibbonClient;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
-import org.springframework.http.MediaType;
-import org.springframework.restdocs.JUnitRestDocumentation;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-import org.springframework.web.context.WebApplicationContext;
-
-import java.time.Clock;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
-import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
-import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
-import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.put;
-import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
-import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
-import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@RunWith(SpringRunner.class)
-@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
-public class TestGroup {
-
-  @Rule
-  public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("src/doc/generated-snippets/test-group");
-
-  @Autowired
-  private WebApplicationContext context;
-
-  private MockMvc mockMvc;
-
-  final String path = "/group/v1";
-
-  @Before
-  public void setUp(){
-
-    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
-            .apply(documentationConfiguration(this.restDocumentation))
-            .alwaysDo(document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())))
-            .build();
-  }
-
-  private static final String APP_NAME = "group-v1";
-  private static final String TEST_USER = "ranefer";
-
-  private final static TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
-  private final static CassandraInitializer cassandraInitializer = new CassandraInitializer();
-  private final static MariaDBInitializer mariaDBInitializer = new MariaDBInitializer();
-  private final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
-
-  @ClassRule
-  public static TestRule orderClassRules = RuleChain
-          .outerRule(testEnvironment)
-          .around(cassandraInitializer)
-          .around(mariaDBInitializer)
-          .around(tenantDataStoreContext);
-
-  @Rule
-  public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
-          = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
-  @Autowired
-  private GroupManager testSubject;
-  @Autowired
-  private EventRecorder eventRecorder;
-
-  private AutoUserContext userContext;
-
-  public TestGroup() {
-    super();
-  }
-
-  @Before
-  public void prepTest() {
-    userContext = this.tenantApplicationSecurityEnvironment.createAutoUserContext(TestGroup.TEST_USER);
-  }
-
-  @After
-  public void cleanTest() {
-    userContext.close();
-  }
-
-  public boolean waitForInitialize() {
-    try {
-      return this.eventRecorder.wait(EventConstants.INITIALIZE, EventConstants.INITIALIZE);
-    } catch (final InterruptedException e) {
-      throw new IllegalStateException(e);
-    }
-  }
-
-  @Test
-  public void shouldCreateGroup() throws Exception {
-    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
-
-    this.testSubject.createGroupDefinition(randomGroupDefinition);
-
-    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
-
-    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
-
-    this.testSubject.createGroup(randomGroup);
-
-    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
-
-    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
-    Assert.assertEquals(randomGroup.getIdentifier(), fetchedGroup.getIdentifier());
-    Assert.assertEquals(randomGroup.getGroupDefinitionIdentifier(), fetchedGroup.getGroupDefinitionIdentifier());
-    Assert.assertEquals(randomGroup.getName(), fetchedGroup.getName());
-    Assert.assertEquals(randomGroup.getOffice(), fetchedGroup.getOffice());
-    Assert.assertEquals(randomGroup.getAssignedEmployee(), fetchedGroup.getAssignedEmployee());
-    Assert.assertEquals(randomGroup.getWeekday(), fetchedGroup.getWeekday());
-    Assert.assertEquals(Group.Status.PENDING.name(), fetchedGroup.getStatus());
-    Assert.assertEquals(randomGroup.getLeaders().size(), fetchedGroup.getLeaders().size());
-    Assert.assertEquals(randomGroup.getMembers().size(), fetchedGroup.getMembers().size());
-    Assert.assertNotNull(fetchedGroup.getCreatedBy());
-    Assert.assertNotNull(fetchedGroup.getCreatedOn());
-    Assert.assertNull(fetchedGroup.getLastModifiedBy());
-    Assert.assertNull(fetchedGroup.getLastModifiedOn());
-    Assert.assertNotNull(fetchedGroup.getAddress());
-
-    this.mockMvc.perform(post(path + "/groups")
-            .accept(MediaType.APPLICATION_JSON_VALUE)
-            .contentType(MediaType.APPLICATION_JSON_VALUE)
-            .content(fetchedGroup.getIdentifier()))
-            .andExpect(status().isNotFound());
-  }
-
-  @Test
-  public void shouldActivateCommand() throws Exception {
-    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
-    this.testSubject.createGroupDefinition(randomGroupDefinition);
-    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
-
-    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
-    this.testSubject.createGroup(randomGroup);
-    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
-
-    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
-    Assert.assertEquals(Group.Status.PENDING.name(), fetchedGroup.getStatus());
-
-    final GroupCommand activate = new GroupCommand();
-    activate.setAction(GroupCommand.Action.ACTIVATE.name());
-    activate.setNote(RandomStringUtils.randomAlphanumeric(256));
-    activate.setCreatedBy(TestGroup.TEST_USER);
-    activate.setCreatedOn(ZonedDateTime.now(Clock.systemUTC()).format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
-
-    this.testSubject.processGroupCommand(randomGroup.getIdentifier(), activate);
-    this.eventRecorder.wait(EventConstants.ACTIVATE_GROUP, randomGroup.getIdentifier());
-
-    final Group activatedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
-    Assert.assertEquals(Group.Status.ACTIVE.name(), activatedGroup.getStatus());
-
-    final List<GroupCommand> groupCommands = this.testSubject.fetchGroupCommands(activatedGroup.getIdentifier());
-    Assert.assertTrue(groupCommands.size() == 1);
-    final GroupCommand groupCommand = groupCommands.get(0);
-    Assert.assertEquals(activate.getAction(), groupCommand.getAction());
-    Assert.assertEquals(activate.getNote(), groupCommand.getNote());
-    Assert.assertEquals(activate.getCreatedBy(), groupCommand.getCreatedBy());
-    Assert.assertNotNull(groupCommand.getCreatedOn());
-
-    final List<Meeting> meetings = this.testSubject.fetchMeetings(activatedGroup.getIdentifier(), Boolean.FALSE);
-    Assert.assertNotNull(meetings);
-    Assert.assertEquals(randomGroupDefinition.getCycle().getNumberOfMeetings(), Integer.valueOf(meetings.size()));
-
-    final Meeting meeting2signOff = meetings.get(0);
-    final SignOffMeeting signOffMeeting = new SignOffMeeting();
-    signOffMeeting.setCycle(meeting2signOff.getCurrentCycle());
-    signOffMeeting.setSequence(meeting2signOff.getMeetingSequence());
-    signOffMeeting.setDuration(120L);
-    signOffMeeting.setAttendees(meeting2signOff.getAttendees()
-            .stream()
-            .map(attendee -> {
-              attendee.setStatus(Attendee.Status.ATTENDED.name());
-              return attendee;
-            })
-            .collect(Collectors.toSet())
-    );
-
-    this.testSubject.closeMeeting(activatedGroup.getIdentifier(), signOffMeeting);
-    this.eventRecorder.wait(EventConstants.PUT_GROUP, activatedGroup.getIdentifier());
-
-    this.mockMvc.perform(post(path + "/groups/" + fetchedGroup.getIdentifier() + "/commands")
-            .accept(MediaType.APPLICATION_JSON_VALUE)
-            .contentType(MediaType.APPLICATION_JSON_VALUE)
-            .content(fetchedGroup.getIdentifier()))
-            .andExpect(status().isNotFound());
-  }
-
-  @Test
-  public void shouldUpdateLeaders() throws Exception {
-    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
-    this.testSubject.createGroupDefinition(randomGroupDefinition);
-    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
-
-    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
-    this.testSubject.createGroup(randomGroup);
-    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
-
-    final int currentLeadersSize = randomGroup.getLeaders().size();
-    randomGroup.getLeaders().add(RandomStringUtils.randomAlphanumeric(32));
-    this.testSubject.updateLeaders(randomGroup.getIdentifier(), randomGroup.getLeaders());
-    this.eventRecorder.wait(EventConstants.PUT_GROUP, randomGroup.getIdentifier());
-
-    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
-    Assert.assertEquals((currentLeadersSize + 1), fetchedGroup.getLeaders().size());
-
-    this.mockMvc.perform(put(path + "/groups/" + fetchedGroup.getIdentifier() + "/leaders" )
-            .accept(MediaType.APPLICATION_JSON_VALUE)
-            .contentType(MediaType.APPLICATION_JSON)
-            .content(fetchedGroup.getIdentifier()))
-            .andExpect(status().is4xxClientError());
-  }
-
-  @Test
-  public void shouldUpdateMembers() throws Exception {
-    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
-    this.testSubject.createGroupDefinition(randomGroupDefinition);
-    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
-
-    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
-    this.testSubject.createGroup(randomGroup);
-    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
-
-    final int currentMembersSize = randomGroup.getMembers().size();
-    randomGroup.getMembers().addAll(Arrays.asList(
-            RandomStringUtils.randomAlphanumeric(32),
-            RandomStringUtils.randomAlphanumeric(32)
-    ));
-    this.testSubject.updateMembers(randomGroup.getIdentifier(), randomGroup.getMembers());
-    this.eventRecorder.wait(EventConstants.PUT_GROUP, randomGroup.getIdentifier());
-
-    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
-    Assert.assertEquals((currentMembersSize + 2), fetchedGroup.getMembers().size());
-
-    this.mockMvc.perform(put(path + "/groups/" + fetchedGroup.getIdentifier() + "/members" )
-            .accept(MediaType.APPLICATION_JSON_VALUE)
-            .contentType(MediaType.APPLICATION_JSON)
-            .content(fetchedGroup.getIdentifier()))
-            .andExpect(status().is4xxClientError());
-  }
-
-  @Test
-  public void shouldUpdateAssignedEmployee() throws Exception {
-    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
-    this.testSubject.createGroupDefinition(randomGroupDefinition);
-    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
-
-    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
-    this.testSubject.createGroup(randomGroup);
-    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
-
-    final AssignedEmployeeHolder anotherEmployee = new AssignedEmployeeHolder();
-    anotherEmployee.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
-
-    this.testSubject.updateAssignedEmployee(randomGroup.getIdentifier(), anotherEmployee);
-    this.eventRecorder.wait(EventConstants.PUT_GROUP, randomGroup.getIdentifier());
-
-    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
-    Assert.assertEquals(anotherEmployee.getIdentifier(), fetchedGroup.getAssignedEmployee());
-
-    this.mockMvc.perform(put(path + "/groups/" + fetchedGroup.getIdentifier() + "/employee")
-            .accept(MediaType.APPLICATION_JSON_VALUE)
-            .contentType(MediaType.APPLICATION_JSON)
-            .content(fetchedGroup.getIdentifier()))
-            .andExpect(status().is4xxClientError());
-  }
-
-  @Configuration
-  @EnableEventRecording
-  @EnableFeignClients(basePackages = {"org.apache.fineract.cn.group.api.v1.client"})
-  @RibbonClient(name = APP_NAME)
-  @Import({GroupConfiguration.class})
-  @ComponentScan("org.apache.fineract.cn.group.listener")
-  public static class TestConfiguration {
-    public TestConfiguration() {
-      super();
-    }
-
-    @Bean()
-    public Logger logger() {
-      return LoggerFactory.getLogger("test-logger");
-    }
-  }
-}
diff --git a/service/src/test/java/org/apache/fineract/cn/group/TestGroupDefinition.java b/service/src/test/java/org/apache/fineract/cn/group/TestGroupDefinition.java
deleted file mode 100644
index 239fb8a..0000000
--- a/service/src/test/java/org/apache/fineract/cn/group/TestGroupDefinition.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.fineract.cn.group;
-
-import org.apache.fineract.cn.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
-import org.apache.fineract.cn.api.context.AutoUserContext;
-import org.apache.fineract.cn.group.api.v1.EventConstants;
-import org.apache.fineract.cn.group.api.v1.client.GroupManager;
-import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
-import org.apache.fineract.cn.group.util.GroupDefinitionGenerator;
-import org.apache.fineract.cn.lang.TenantContextHolder;
-import org.apache.fineract.cn.test.env.TestEnvironment;
-import org.apache.fineract.cn.test.fixture.TenantDataStoreContextTestRule;
-import org.apache.fineract.cn.test.fixture.cassandra.CassandraInitializer;
-import org.apache.fineract.cn.test.fixture.mariadb.MariaDBInitializer;
-import org.apache.fineract.cn.test.listener.EnableEventRecording;
-import org.apache.fineract.cn.test.listener.EventRecorder;
-import org.junit.*;
-import org.junit.rules.RuleChain;
-import org.junit.rules.TestRule;
-import org.junit.runner.RunWith;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.cloud.netflix.feign.EnableFeignClients;
-import org.springframework.cloud.netflix.ribbon.RibbonClient;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
-import org.springframework.http.MediaType;
-import org.springframework.restdocs.JUnitRestDocumentation;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-import org.springframework.web.context.WebApplicationContext;
-
-import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
-import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
-import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
-import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
-import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
-import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@RunWith(SpringRunner.class)
-@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
-public class TestGroupDefinition {
-
-  @Rule
-  public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("src/doc/generated-snippets/test-group-definition");
-
-  @Autowired
-  private WebApplicationContext context;
-
-  private MockMvc mockMvc;
-
-  final String path = "/group/v1";
-
-  @Before
-  public void setUp(){
-
-    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
-            .apply(documentationConfiguration(this.restDocumentation))
-            .alwaysDo(document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())))
-            .build();
-  }
-
-  private static final String APP_NAME = "group-v1";
-  private static final String TEST_USER = "ranefer";
-
-  private final static TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
-  private final static CassandraInitializer cassandraInitializer = new CassandraInitializer();
-  private final static MariaDBInitializer mariaDBInitializer = new MariaDBInitializer();
-  private final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
-
-  @ClassRule
-  public static TestRule orderClassRules = RuleChain
-          .outerRule(testEnvironment)
-          .around(cassandraInitializer)
-          .around(mariaDBInitializer)
-          .around(tenantDataStoreContext);
-
-  @Rule
-  public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
-          = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
-
-  @Autowired
-  private GroupManager testSubject;
-  @Autowired
-  private EventRecorder eventRecorder;
-
-  private AutoUserContext userContext;
-
-  public TestGroupDefinition() {
-    super();
-  }
-
-  @Before
-  public void prepTest() {
-    userContext = this.tenantApplicationSecurityEnvironment.createAutoUserContext(TestGroupDefinition.TEST_USER);
-  }
-
-  @After
-  public void cleanTest() {
-    TenantContextHolder.clear();
-    userContext.close();
-  }
-
-  public boolean waitForInitialize() {
-    try {
-      return this.eventRecorder.wait(EventConstants.INITIALIZE, EventConstants.INITIALIZE);
-    } catch (final InterruptedException e) {
-      throw new IllegalStateException(e);
-    }
-  }
-
-  @Test
-  public void shouldCreateGroupDefinition() throws Exception {
-    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
-    this.testSubject.createGroupDefinition(randomGroupDefinition);
-
-    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
-
-    final GroupDefinition fetchedGroupDefinition = this.testSubject.findGroupDefinition(randomGroupDefinition.getIdentifier());
-
-    Assert.assertEquals(randomGroupDefinition.getIdentifier(), fetchedGroupDefinition.getIdentifier());
-    Assert.assertEquals(randomGroupDefinition.getDescription(), fetchedGroupDefinition.getDescription());
-    Assert.assertEquals(randomGroupDefinition.getMinimalSize(), fetchedGroupDefinition.getMinimalSize());
-    Assert.assertEquals(randomGroupDefinition.getMaximalSize(), fetchedGroupDefinition.getMaximalSize());
-    Assert.assertNotNull(fetchedGroupDefinition.getCycle());
-    Assert.assertEquals(randomGroupDefinition.getCycle().getNumberOfMeetings(), fetchedGroupDefinition.getCycle().getNumberOfMeetings());
-    Assert.assertEquals(randomGroupDefinition.getCycle().getFrequency(), fetchedGroupDefinition.getCycle().getFrequency());
-    Assert.assertEquals(randomGroupDefinition.getCycle().getAdjustment(), fetchedGroupDefinition.getCycle().getAdjustment());
-    Assert.assertNotNull(fetchedGroupDefinition.getCreatedBy());
-    Assert.assertNotNull(fetchedGroupDefinition.getCreateOn());
-    Assert.assertNull(fetchedGroupDefinition.getLastModifiedBy());
-    Assert.assertNull(fetchedGroupDefinition.getLastModifiedOn());
-
-    this.mockMvc.perform(post(path + "/definitions")
-            .accept(MediaType.ALL_VALUE)
-            .contentType(MediaType.APPLICATION_JSON_VALUE)
-            .content(fetchedGroupDefinition.getIdentifier()))
-            .andExpect(status().is4xxClientError());
-
-  }
-
-  @Configuration
-  @EnableEventRecording
-  @EnableFeignClients(basePackages = {"org.apache.fineract.cn.group.api.v1.client"})
-  @RibbonClient(name = APP_NAME)
-  @Import({GroupConfiguration.class})
-  @ComponentScan("org.apache.fineract.cn.group.listener")
-  public static class TestConfiguration {
-    public TestConfiguration() {
-      super();
-    }
-
-    @Bean()
-    public Logger logger() {
-      return LoggerFactory.getLogger("test-logger");
-    }
-  }
-}
diff --git a/service/src/test/java/org/apache/fineract/cn/group/listener/GroupDefinitionEventListener.java b/service/src/test/java/org/apache/fineract/cn/group/listener/GroupDefinitionEventListener.java
deleted file mode 100644
index 13dad62..0000000
--- a/service/src/test/java/org/apache/fineract/cn/group/listener/GroupDefinitionEventListener.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.fineract.cn.group.listener;
-
-import org.apache.fineract.cn.group.api.v1.EventConstants;
-import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
-import org.apache.fineract.cn.test.listener.EventRecorder;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.jms.annotation.JmsListener;
-import org.springframework.messaging.handler.annotation.Header;
-import org.springframework.stereotype.Component;
-
-@SuppressWarnings("unused")
-@Component
-public class GroupDefinitionEventListener {
-
-  private final EventRecorder eventRecorder;
-
-  @Autowired
-  public GroupDefinitionEventListener(final EventRecorder eventRecorder) {
-    super();
-    this.eventRecorder = eventRecorder;
-  }
-
-  @JmsListener(
-      subscription = EventConstants.DESTINATION,
-      destination = EventConstants.DESTINATION,
-      selector = EventConstants.SELECTOR_POST_GROUP_DEFINITION
-  )
-  public void onGroupDefinitionCreated(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
-                                       final String payload) {
-    this.eventRecorder.event(tenant, EventConstants.POST_GROUP_DEFINITION, payload, String.class);
-  }
-}
diff --git a/service/src/test/java/org/apache/fineract/cn/group/listener/GroupEventListener.java b/service/src/test/java/org/apache/fineract/cn/group/listener/GroupEventListener.java
deleted file mode 100644
index a453f68..0000000
--- a/service/src/test/java/org/apache/fineract/cn/group/listener/GroupEventListener.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.fineract.cn.group.listener;
-
-import org.apache.fineract.cn.group.api.v1.EventConstants;
-import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
-import org.apache.fineract.cn.test.listener.EventRecorder;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.jms.annotation.JmsListener;
-import org.springframework.messaging.handler.annotation.Header;
-import org.springframework.stereotype.Component;
-
-@SuppressWarnings("unused")
-@Component
-public class GroupEventListener {
-
-  private final EventRecorder eventRecorder;
-
-  @Autowired
-  public GroupEventListener(final EventRecorder eventRecorder) {
-    super();
-    this.eventRecorder = eventRecorder;
-  }
-
-  @JmsListener(
-      subscription = EventConstants.DESTINATION,
-      destination = EventConstants.DESTINATION,
-      selector = EventConstants.SELECTOR_POST_GROUP
-  )
-  public void onGroupCreated(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
-                             final String payload) {
-    this.eventRecorder.event(tenant, EventConstants.POST_GROUP, payload, String.class);
-  }
-
-  @JmsListener(
-      subscription = EventConstants.DESTINATION,
-      destination = EventConstants.DESTINATION,
-      selector = EventConstants.SELECTOR_ACTIVATE_GROUP
-  )
-  public void onGroupActivated(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
-                             final String payload) {
-    this.eventRecorder.event(tenant, EventConstants.ACTIVATE_GROUP, payload, String.class);
-  }
-
-  @JmsListener(
-      subscription = EventConstants.DESTINATION,
-      destination = EventConstants.DESTINATION,
-      selector = EventConstants.SELECTOR_PUT_GROUP
-  )
-  public void onGroupUpdated(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
-                               final String payload) {
-    this.eventRecorder.event(tenant, EventConstants.PUT_GROUP, payload, String.class);
-  }
-}
diff --git a/service/src/test/java/org/apache/fineract/cn/group/listener/MigrationEventListener.java b/service/src/test/java/org/apache/fineract/cn/group/listener/MigrationEventListener.java
deleted file mode 100644
index 027688a..0000000
--- a/service/src/test/java/org/apache/fineract/cn/group/listener/MigrationEventListener.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.fineract.cn.group.listener;
-
-import org.apache.fineract.cn.group.api.v1.EventConstants;
-import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
-import org.apache.fineract.cn.test.listener.EventRecorder;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.jms.annotation.JmsListener;
-import org.springframework.messaging.handler.annotation.Header;
-import org.springframework.stereotype.Component;
-
-@SuppressWarnings("unused")
-@Component
-public class MigrationEventListener {
-
-  private final EventRecorder eventRecorder;
-
-  @Autowired
-  public MigrationEventListener(final EventRecorder eventRecorder) {
-    super();
-    this.eventRecorder = eventRecorder;
-  }
-
-  @JmsListener(
-      subscription = EventConstants.DESTINATION,
-      destination = EventConstants.DESTINATION,
-      selector = EventConstants.SELECTOR_INITIALIZE
-  )
-  public void onInitialization(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
-                               final String payload) {
-    this.eventRecorder.event(tenant, EventConstants.INITIALIZE, payload, String.class);
-  }
-}
diff --git a/service/src/test/java/org/apache/fineract/cn/group/util/GroupDefinitionGenerator.java b/service/src/test/java/org/apache/fineract/cn/group/util/GroupDefinitionGenerator.java
deleted file mode 100644
index 6d33221..0000000
--- a/service/src/test/java/org/apache/fineract/cn/group/util/GroupDefinitionGenerator.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.fineract.cn.group.util;
-
-import org.apache.commons.lang3.RandomStringUtils;
-import org.apache.fineract.cn.group.api.v1.domain.Cycle;
-import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
-
-public class GroupDefinitionGenerator {
-
-  private GroupDefinitionGenerator() {
-    super();
-  }
-
-  public static GroupDefinition createRandomGroupDefinition() {
-    final GroupDefinition groupDefinition = new GroupDefinition();
-    groupDefinition.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
-    groupDefinition.setDescription(RandomStringUtils.randomAlphabetic(2048));
-    groupDefinition.setMinimalSize(10);
-    groupDefinition.setMaximalSize(30);
-    final Cycle cycle = new Cycle();
-    cycle.setNumberOfMeetings(25);
-    cycle.setFrequency(Cycle.Frequency.WEEKLY.name());
-    cycle.setAdjustment(Cycle.Adjustment.NEXT_BUSINESS_DAY.name());
-    groupDefinition.setCycle(cycle);
-    return groupDefinition;
-  }
-}
diff --git a/service/src/test/java/org/apache/fineract/cn/group/util/GroupGenerator.java b/service/src/test/java/org/apache/fineract/cn/group/util/GroupGenerator.java
deleted file mode 100644
index 112fe07..0000000
--- a/service/src/test/java/org/apache/fineract/cn/group/util/GroupGenerator.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.fineract.cn.group.util;
-
-import org.apache.commons.lang3.RandomStringUtils;
-import org.apache.fineract.cn.group.api.v1.domain.Address;
-import org.apache.fineract.cn.group.api.v1.domain.Group;
-
-import java.util.Arrays;
-import java.util.HashSet;
-
-public class GroupGenerator {
-
-  private GroupGenerator() {
-    super();
-  }
-
-  public static Group createRandomGroup(final String definitionIdentifier) {
-    final Group group = new Group();
-    group.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
-    group.setGroupDefinitionIdentifier(definitionIdentifier);
-    group.setName(RandomStringUtils.randomAlphanumeric(256));
-    group.setOffice(RandomStringUtils.randomAlphanumeric(32));
-    group.setAssignedEmployee(RandomStringUtils.randomAlphanumeric(32));
-    group.setLeaders(new HashSet<>(Arrays.asList(
-        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32)
-    )));
-    group.setMembers(new HashSet<>(Arrays.asList(
-        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
-        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
-        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
-        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
-        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32)
-    )));
-    group.setWeekday(Group.Weekday.WEDNESDAY.getValue());
-    final Address address = new Address();
-    address.setStreet(RandomStringUtils.randomAlphanumeric(256));
-    address.setCity(RandomStringUtils.randomAlphanumeric(256));
-    address.setRegion(RandomStringUtils.randomAlphanumeric(256));
-    address.setPostalCode(RandomStringUtils.randomAlphanumeric(2));
-    address.setCountry(RandomStringUtils.randomAlphanumeric(256));
-    address.setCountryCode(RandomStringUtils.randomAlphanumeric(2));
-    group.setAddress(address);
-    return group;
-  }
-}


[fineract-cn-group] 29/40: changing name from updateGroupDefinition to updateDefinition

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit a9aeb1b9aa1f3ff8f35cf3193cae04050f14c8af
Author: kengneruphine <ru...@gmail.com>
AuthorDate: Fri Jul 6 11:53:37 2018 +0100

    changing name from updateGroupDefinition to updateDefinition
---
 .../apache/fineract/cn/group/rest/GroupDefinitionRestController.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
index 6bd9ecb..f520273 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
@@ -121,7 +121,7 @@ public class GroupDefinitionRestController {
   )
   public
   @ResponseBody
-  ResponseEntity<Void> updateGroupDefinition(@PathVariable("identifier") final String identifier, @RequestBody final GroupDefinition groupDefinition) {
+  ResponseEntity<Void> updateDefinition(@PathVariable("identifier") final String identifier, @RequestBody final GroupDefinition groupDefinition) {
     if (this.groupDefinitionService.groupDefinitionExists(identifier)) {
       this.commandGateway.process(new UpdateGroupDefinitionCommand(identifier, groupDefinition));
     } else {


[fineract-cn-group] 37/40: Merge pull request #9 from Izakey/develop

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 3fa848834ab8e519b3b4d15c6d81b97184a8e264
Merge: acdd064 f252c32
Author: Awasum Yannick <ya...@gmail.com>
AuthorDate: Fri Sep 7 10:39:21 2018 +0100

    Merge pull request #9 from Izakey/develop
    
    Document Group management API for savings and loans in groups

 .gitignore                                         |   3 +
 component-test/build.gradle                        |  15 +-
 .../fineract/cn/group/AbstractGroupTest.java       |  93 +++
 .../fineract/cn/group/GroupApiDocumentation.java   | 717 +++++++++++++++++++++
 .../fineract/cn/group/SuiteTestEnvironment.java    |  45 ++
 .../org/apache/fineract/cn/group/TestGroup.java    | 105 +--
 .../fineract/cn/group/TestGroupDefinition.java     |  79 +--
 .../cn/group/util/GroupDefinitionGenerator.java    |   4 +-
 .../fineract/cn/group/util/GroupGenerator.java     |  32 +-
 9 files changed, 911 insertions(+), 182 deletions(-)


[fineract-cn-group] 14/40: Adjusting to package name changes in upstream repositories.

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit e377bd560aee73e3087f7e0a5e214fece340fec4
Author: Myrle Krantz <my...@apache.org>
AuthorDate: Mon Apr 16 13:07:15 2018 +0200

    Adjusting to package name changes in upstream repositories.
---
 .../io/mifos/group/api/v1/client/GroupManager.java | 13 ++++----
 .../src/main/java/io/mifos/group/TestGroup.java    | 36 ++++++++++++----------
 .../java/io/mifos/group/TestGroupDefinition.java   | 25 +++++++++------
 .../listener/GroupDefinitionEventListener.java     |  4 +--
 .../mifos/group/listener/GroupEventListener.java   |  4 +--
 .../group/listener/MigrationEventListener.java     |  4 +--
 .../io/mifos/group/service/GroupConfiguration.java | 14 ++++-----
 .../internal/command/handler/GroupAggregate.java   | 32 ++++++++++---------
 .../command/handler/MigrationAggregate.java        | 11 +++----
 .../internal/mapper/GroupCommandMapper.java        |  7 ++---
 .../internal/mapper/GroupDefinitionMapper.java     |  4 +--
 .../group/service/internal/mapper/GroupMapper.java |  4 +--
 .../service/internal/mapper/MeetingMapper.java     |  2 +-
 .../internal/repository/GroupCommandEntity.java    |  5 ++-
 .../internal/repository/GroupDefinitionEntity.java |  5 ++-
 .../service/internal/repository/GroupEntity.java   |  5 ++-
 .../service/internal/repository/MeetingEntity.java |  9 +++---
 .../internal/repository/MeetingRepository.java     |  9 +++---
 .../service/internal/service/GroupService.java     | 17 +++++-----
 .../rest/GroupDefinitionRestController.java        | 15 +++++----
 .../group/service/rest/GroupRestController.java    | 25 ++++++++-------
 .../service/rest/MigrationRestController.java      |  6 ++--
 22 files changed, 129 insertions(+), 127 deletions(-)

diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupManager.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupManager.java
index 9b5877e..f393d58 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupManager.java
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupManager.java
@@ -18,16 +18,18 @@
  */
 package io.mifos.group.api.v1.client;
 
-import io.mifos.core.api.annotation.ThrowsException;
-import io.mifos.core.api.annotation.ThrowsExceptions;
-import io.mifos.core.api.util.CustomFeignClientsConfiguration;
 import io.mifos.group.api.v1.domain.AssignedEmployeeHolder;
-import io.mifos.group.api.v1.domain.SignOffMeeting;
 import io.mifos.group.api.v1.domain.Group;
 import io.mifos.group.api.v1.domain.GroupCommand;
 import io.mifos.group.api.v1.domain.GroupDefinition;
 import io.mifos.group.api.v1.domain.GroupPage;
 import io.mifos.group.api.v1.domain.Meeting;
+import io.mifos.group.api.v1.domain.SignOffMeeting;
+import java.util.List;
+import java.util.Set;
+import org.apache.fineract.cn.api.annotation.ThrowsException;
+import org.apache.fineract.cn.api.annotation.ThrowsExceptions;
+import org.apache.fineract.cn.api.util.CustomFeignClientsConfiguration;
 import org.springframework.cloud.netflix.feign.FeignClient;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
@@ -38,9 +40,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 
-import java.util.List;
-import java.util.Set;
-
 @SuppressWarnings("unused")
 @FeignClient(name="group-v1", path="/group/v1", configuration=CustomFeignClientsConfiguration.class)
 public interface GroupManager {
diff --git a/component-test/src/main/java/io/mifos/group/TestGroup.java b/component-test/src/main/java/io/mifos/group/TestGroup.java
index 4e3edf6..d918728 100644
--- a/component-test/src/main/java/io/mifos/group/TestGroup.java
+++ b/component-test/src/main/java/io/mifos/group/TestGroup.java
@@ -18,14 +18,6 @@
  */
 package io.mifos.group;
 
-import io.mifos.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
-import io.mifos.core.api.context.AutoUserContext;
-import io.mifos.core.test.env.TestEnvironment;
-import io.mifos.core.test.fixture.TenantDataStoreContextTestRule;
-import io.mifos.core.test.fixture.cassandra.CassandraInitializer;
-import io.mifos.core.test.fixture.mariadb.MariaDBInitializer;
-import io.mifos.core.test.listener.EnableEventRecording;
-import io.mifos.core.test.listener.EventRecorder;
 import io.mifos.group.api.v1.EventConstants;
 import io.mifos.group.api.v1.client.GroupManager;
 import io.mifos.group.api.v1.domain.AssignedEmployeeHolder;
@@ -38,8 +30,27 @@ import io.mifos.group.api.v1.domain.SignOffMeeting;
 import io.mifos.group.service.GroupConfiguration;
 import io.mifos.group.util.GroupDefinitionGenerator;
 import io.mifos.group.util.GroupGenerator;
+import java.time.Clock;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
 import org.apache.commons.lang3.RandomStringUtils;
-import org.junit.*;
+import org.apache.fineract.cn.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
+import org.apache.fineract.cn.api.context.AutoUserContext;
+import org.apache.fineract.cn.test.env.TestEnvironment;
+import org.apache.fineract.cn.test.fixture.TenantDataStoreContextTestRule;
+import org.apache.fineract.cn.test.fixture.cassandra.CassandraInitializer;
+import org.apache.fineract.cn.test.fixture.mariadb.MariaDBInitializer;
+import org.apache.fineract.cn.test.listener.EnableEventRecording;
+import org.apache.fineract.cn.test.listener.EventRecorder;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
 import org.junit.rules.RuleChain;
 import org.junit.rules.TestRule;
 import org.junit.runner.RunWith;
@@ -55,13 +66,6 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 import org.springframework.test.context.junit4.SpringRunner;
 
-import java.time.Clock;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-
 @RunWith(SpringRunner.class)
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
 public class TestGroup {
diff --git a/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java b/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java
index d59a11f..f78eb44 100644
--- a/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java
+++ b/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java
@@ -18,21 +18,26 @@
  */
 package io.mifos.group;
 
-import io.mifos.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
-import io.mifos.core.api.context.AutoUserContext;
-import io.mifos.core.lang.TenantContextHolder;
-import io.mifos.core.test.env.TestEnvironment;
-import io.mifos.core.test.fixture.TenantDataStoreContextTestRule;
-import io.mifos.core.test.fixture.cassandra.CassandraInitializer;
-import io.mifos.core.test.fixture.mariadb.MariaDBInitializer;
-import io.mifos.core.test.listener.EnableEventRecording;
-import io.mifos.core.test.listener.EventRecorder;
 import io.mifos.group.api.v1.EventConstants;
 import io.mifos.group.api.v1.client.GroupManager;
 import io.mifos.group.api.v1.domain.GroupDefinition;
 import io.mifos.group.service.GroupConfiguration;
 import io.mifos.group.util.GroupDefinitionGenerator;
-import org.junit.*;
+import org.apache.fineract.cn.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
+import org.apache.fineract.cn.api.context.AutoUserContext;
+import org.apache.fineract.cn.lang.TenantContextHolder;
+import org.apache.fineract.cn.test.env.TestEnvironment;
+import org.apache.fineract.cn.test.fixture.TenantDataStoreContextTestRule;
+import org.apache.fineract.cn.test.fixture.cassandra.CassandraInitializer;
+import org.apache.fineract.cn.test.fixture.mariadb.MariaDBInitializer;
+import org.apache.fineract.cn.test.listener.EnableEventRecording;
+import org.apache.fineract.cn.test.listener.EventRecorder;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
 import org.junit.rules.RuleChain;
 import org.junit.rules.TestRule;
 import org.junit.runner.RunWith;
diff --git a/component-test/src/main/java/io/mifos/group/listener/GroupDefinitionEventListener.java b/component-test/src/main/java/io/mifos/group/listener/GroupDefinitionEventListener.java
index be21011..3932eb8 100644
--- a/component-test/src/main/java/io/mifos/group/listener/GroupDefinitionEventListener.java
+++ b/component-test/src/main/java/io/mifos/group/listener/GroupDefinitionEventListener.java
@@ -18,9 +18,9 @@
  */
 package io.mifos.group.listener;
 
-import io.mifos.core.lang.config.TenantHeaderFilter;
-import io.mifos.core.test.listener.EventRecorder;
 import io.mifos.group.api.v1.EventConstants;
+import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
+import org.apache.fineract.cn.test.listener.EventRecorder;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jms.annotation.JmsListener;
 import org.springframework.messaging.handler.annotation.Header;
diff --git a/component-test/src/main/java/io/mifos/group/listener/GroupEventListener.java b/component-test/src/main/java/io/mifos/group/listener/GroupEventListener.java
index 825947c..9020138 100644
--- a/component-test/src/main/java/io/mifos/group/listener/GroupEventListener.java
+++ b/component-test/src/main/java/io/mifos/group/listener/GroupEventListener.java
@@ -18,9 +18,9 @@
  */
 package io.mifos.group.listener;
 
-import io.mifos.core.lang.config.TenantHeaderFilter;
-import io.mifos.core.test.listener.EventRecorder;
 import io.mifos.group.api.v1.EventConstants;
+import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
+import org.apache.fineract.cn.test.listener.EventRecorder;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jms.annotation.JmsListener;
 import org.springframework.messaging.handler.annotation.Header;
diff --git a/component-test/src/main/java/io/mifos/group/listener/MigrationEventListener.java b/component-test/src/main/java/io/mifos/group/listener/MigrationEventListener.java
index 7b90c38..c150fef 100644
--- a/component-test/src/main/java/io/mifos/group/listener/MigrationEventListener.java
+++ b/component-test/src/main/java/io/mifos/group/listener/MigrationEventListener.java
@@ -18,9 +18,9 @@
  */
 package io.mifos.group.listener;
 
-import io.mifos.core.lang.config.TenantHeaderFilter;
-import io.mifos.core.test.listener.EventRecorder;
 import io.mifos.group.api.v1.EventConstants;
+import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
+import org.apache.fineract.cn.test.listener.EventRecorder;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jms.annotation.JmsListener;
 import org.springframework.messaging.handler.annotation.Header;
diff --git a/service/src/main/java/io/mifos/group/service/GroupConfiguration.java b/service/src/main/java/io/mifos/group/service/GroupConfiguration.java
index bb0d3c8..244716b 100644
--- a/service/src/main/java/io/mifos/group/service/GroupConfiguration.java
+++ b/service/src/main/java/io/mifos/group/service/GroupConfiguration.java
@@ -18,13 +18,13 @@
  */
 package io.mifos.group.service;
 
-import io.mifos.anubis.config.EnableAnubis;
-import io.mifos.core.async.config.EnableAsync;
-import io.mifos.core.cassandra.config.EnableCassandra;
-import io.mifos.core.command.config.EnableCommandProcessing;
-import io.mifos.core.lang.config.EnableServiceException;
-import io.mifos.core.lang.config.EnableTenantContext;
-import io.mifos.core.mariadb.config.EnableMariaDB;
+import org.apache.fineract.cn.anubis.config.EnableAnubis;
+import org.apache.fineract.cn.async.config.EnableAsync;
+import org.apache.fineract.cn.cassandra.config.EnableCassandra;
+import org.apache.fineract.cn.command.config.EnableCommandProcessing;
+import org.apache.fineract.cn.lang.config.EnableServiceException;
+import org.apache.fineract.cn.lang.config.EnableTenantContext;
+import org.apache.fineract.cn.mariadb.config.EnableMariaDB;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/handler/GroupAggregate.java b/service/src/main/java/io/mifos/group/service/internal/command/handler/GroupAggregate.java
index 4c3bbae..5616337 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/handler/GroupAggregate.java
+++ b/service/src/main/java/io/mifos/group/service/internal/command/handler/GroupAggregate.java
@@ -18,12 +18,13 @@
  */
 package io.mifos.group.service.internal.command.handler;
 
-import io.mifos.core.api.util.UserContextHolder;
-import io.mifos.core.command.annotation.Aggregate;
-import io.mifos.core.command.annotation.CommandHandler;
-import io.mifos.core.command.annotation.EventEmitter;
-import io.mifos.core.lang.DateConverter;
-import io.mifos.core.lang.ServiceException;
+import io.mifos.group.api.v1.EventConstants;
+import io.mifos.group.api.v1.domain.Attendee;
+import io.mifos.group.api.v1.domain.Cycle;
+import io.mifos.group.api.v1.domain.Group;
+import io.mifos.group.api.v1.domain.GroupCommand;
+import io.mifos.group.api.v1.domain.GroupDefinition;
+import io.mifos.group.api.v1.domain.SignOffMeeting;
 import io.mifos.group.service.internal.command.ActivateGroupCommand;
 import io.mifos.group.service.internal.command.CloseGroupCommand;
 import io.mifos.group.service.internal.command.CreateGroupCommand;
@@ -33,6 +34,8 @@ import io.mifos.group.service.internal.command.SignOffMeetingCommand;
 import io.mifos.group.service.internal.command.UpdateAssignedEmployeeCommand;
 import io.mifos.group.service.internal.command.UpdateLeadersCommand;
 import io.mifos.group.service.internal.command.UpdateMembersCommand;
+import io.mifos.group.service.internal.mapper.AddressMapper;
+import io.mifos.group.service.internal.mapper.GroupCommandMapper;
 import io.mifos.group.service.internal.repository.AddressEntity;
 import io.mifos.group.service.internal.repository.AddressRepository;
 import io.mifos.group.service.internal.repository.AttendeeEntity;
@@ -45,14 +48,6 @@ import io.mifos.group.service.internal.repository.GroupEntity;
 import io.mifos.group.service.internal.repository.GroupRepository;
 import io.mifos.group.service.internal.repository.MeetingEntity;
 import io.mifos.group.service.internal.repository.MeetingRepository;
-import io.mifos.group.api.v1.EventConstants;
-import io.mifos.group.api.v1.domain.*;
-import io.mifos.group.service.internal.mapper.AddressMapper;
-import io.mifos.group.service.internal.mapper.GroupCommandMapper;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.StringUtils;
-
 import java.time.Clock;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
@@ -60,6 +55,15 @@ import java.time.temporal.ChronoField;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
+import org.apache.fineract.cn.api.util.UserContextHolder;
+import org.apache.fineract.cn.command.annotation.Aggregate;
+import org.apache.fineract.cn.command.annotation.CommandHandler;
+import org.apache.fineract.cn.command.annotation.EventEmitter;
+import org.apache.fineract.cn.lang.DateConverter;
+import org.apache.fineract.cn.lang.ServiceException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
 
 @SuppressWarnings("unused")
 @Aggregate
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/handler/MigrationAggregate.java b/service/src/main/java/io/mifos/group/service/internal/command/handler/MigrationAggregate.java
index eed82d2..64b546f 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/handler/MigrationAggregate.java
+++ b/service/src/main/java/io/mifos/group/service/internal/command/handler/MigrationAggregate.java
@@ -18,20 +18,19 @@
  */
 package io.mifos.group.service.internal.command.handler;
 
-import io.mifos.core.command.annotation.Aggregate;
-import io.mifos.core.command.annotation.CommandHandler;
-import io.mifos.core.command.annotation.EventEmitter;
-import io.mifos.core.mariadb.domain.FlywayFactoryBean;
 import io.mifos.group.api.v1.EventConstants;
 import io.mifos.group.service.ServiceConstants;
 import io.mifos.group.service.internal.command.InitializeServiceCommand;
+import javax.sql.DataSource;
+import org.apache.fineract.cn.command.annotation.Aggregate;
+import org.apache.fineract.cn.command.annotation.CommandHandler;
+import org.apache.fineract.cn.command.annotation.EventEmitter;
+import org.apache.fineract.cn.mariadb.domain.FlywayFactoryBean;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.transaction.annotation.Transactional;
 
-import javax.sql.DataSource;
-
 @SuppressWarnings("unused")
 @Aggregate
 public class MigrationAggregate {
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupCommandMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupCommandMapper.java
index bbfbf3a..ec927c3 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupCommandMapper.java
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupCommandMapper.java
@@ -18,13 +18,12 @@
  */
 package io.mifos.group.service.internal.mapper;
 
-import io.mifos.core.api.util.UserContextHolder;
-import io.mifos.core.lang.DateConverter;
-import io.mifos.group.service.internal.repository.GroupCommandEntity;
 import io.mifos.group.api.v1.domain.GroupCommand;
-
+import io.mifos.group.service.internal.repository.GroupCommandEntity;
 import java.time.Clock;
 import java.time.LocalDateTime;
+import org.apache.fineract.cn.api.util.UserContextHolder;
+import org.apache.fineract.cn.lang.DateConverter;
 
 public class GroupCommandMapper {
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupDefinitionMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupDefinitionMapper.java
index 6de8f05..56126bc 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupDefinitionMapper.java
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupDefinitionMapper.java
@@ -18,10 +18,10 @@
  */
 package io.mifos.group.service.internal.mapper;
 
-import io.mifos.core.lang.DateConverter;
-import io.mifos.group.service.internal.repository.GroupDefinitionEntity;
 import io.mifos.group.api.v1.domain.Cycle;
 import io.mifos.group.api.v1.domain.GroupDefinition;
+import io.mifos.group.service.internal.repository.GroupDefinitionEntity;
+import org.apache.fineract.cn.lang.DateConverter;
 
 public class GroupDefinitionMapper {
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupMapper.java
index 764a377..3e6512c 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupMapper.java
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupMapper.java
@@ -18,9 +18,9 @@
  */
 package io.mifos.group.service.internal.mapper;
 
-import io.mifos.core.lang.DateConverter;
-import io.mifos.group.service.internal.repository.GroupEntity;
 import io.mifos.group.api.v1.domain.Group;
+import io.mifos.group.service.internal.repository.GroupEntity;
+import org.apache.fineract.cn.lang.DateConverter;
 import org.springframework.util.StringUtils;
 
 public class GroupMapper {
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/MeetingMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/MeetingMapper.java
index 6851cc3..122e882 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/MeetingMapper.java
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/MeetingMapper.java
@@ -18,9 +18,9 @@
  */
 package io.mifos.group.service.internal.mapper;
 
-import io.mifos.core.lang.DateConverter;
 import io.mifos.group.api.v1.domain.Meeting;
 import io.mifos.group.service.internal.repository.MeetingEntity;
+import org.apache.fineract.cn.lang.DateConverter;
 
 public class MeetingMapper {
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandEntity.java
index e7ae69a..df46f02 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandEntity.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandEntity.java
@@ -18,8 +18,7 @@
  */
 package io.mifos.group.service.internal.repository;
 
-import io.mifos.core.mariadb.util.LocalDateTimeConverter;
-
+import java.time.LocalDateTime;
 import javax.persistence.Column;
 import javax.persistence.Convert;
 import javax.persistence.Entity;
@@ -30,7 +29,7 @@ import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
-import java.time.LocalDateTime;
+import org.apache.fineract.cn.mariadb.util.LocalDateTimeConverter;
 
 @Entity
 @Table(name = "ptah_group_commands")
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionEntity.java
index 876973b..2fb1299 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionEntity.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionEntity.java
@@ -18,8 +18,7 @@
  */
 package io.mifos.group.service.internal.repository;
 
-import io.mifos.core.mariadb.util.LocalDateTimeConverter;
-
+import java.time.LocalDateTime;
 import javax.persistence.Column;
 import javax.persistence.Convert;
 import javax.persistence.Entity;
@@ -27,7 +26,7 @@ import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.Table;
-import java.time.LocalDateTime;
+import org.apache.fineract.cn.mariadb.util.LocalDateTimeConverter;
 
 @Entity
 @Table(name = "ptah_group_definitions")
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/GroupEntity.java
index 6f8fbea..b99529a 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/GroupEntity.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/GroupEntity.java
@@ -18,8 +18,7 @@
  */
 package io.mifos.group.service.internal.repository;
 
-import io.mifos.core.mariadb.util.LocalDateTimeConverter;
-
+import java.time.LocalDateTime;
 import javax.persistence.Column;
 import javax.persistence.Convert;
 import javax.persistence.Entity;
@@ -31,7 +30,7 @@ import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
-import java.time.LocalDateTime;
+import org.apache.fineract.cn.mariadb.util.LocalDateTimeConverter;
 
 @Entity
 @Table(name = "ptah_groups")
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/MeetingEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/MeetingEntity.java
index a6e4b6b..72c50b7 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/MeetingEntity.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/MeetingEntity.java
@@ -18,9 +18,8 @@
  */
 package io.mifos.group.service.internal.repository;
 
-import io.mifos.core.mariadb.util.LocalDateConverter;
-import io.mifos.core.mariadb.util.LocalDateTimeConverter;
-
+import java.time.LocalDate;
+import java.time.LocalDateTime;
 import javax.persistence.Column;
 import javax.persistence.Convert;
 import javax.persistence.Entity;
@@ -31,8 +30,8 @@ import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
+import org.apache.fineract.cn.mariadb.util.LocalDateConverter;
+import org.apache.fineract.cn.mariadb.util.LocalDateTimeConverter;
 
 @Entity
 @Table(name = "ptah_meetings")
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/MeetingRepository.java b/service/src/main/java/io/mifos/group/service/internal/repository/MeetingRepository.java
index 16a2349..4437e6e 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/MeetingRepository.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/MeetingRepository.java
@@ -18,14 +18,13 @@
  */
 package io.mifos.group.service.internal.repository;
 
-import io.mifos.core.mariadb.util.LocalDateConverter;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-import javax.persistence.Convert;
 import java.time.LocalDate;
 import java.util.List;
 import java.util.Optional;
+import javax.persistence.Convert;
+import org.apache.fineract.cn.mariadb.util.LocalDateConverter;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
 
 @Repository
 public interface MeetingRepository extends JpaRepository<MeetingEntity, Long> {
diff --git a/service/src/main/java/io/mifos/group/service/internal/service/GroupService.java b/service/src/main/java/io/mifos/group/service/internal/service/GroupService.java
index 8cfc35e..8f3f680 100644
--- a/service/src/main/java/io/mifos/group/service/internal/service/GroupService.java
+++ b/service/src/main/java/io/mifos/group/service/internal/service/GroupService.java
@@ -18,9 +18,6 @@
  */
 package io.mifos.group.service.internal.service;
 
-import io.mifos.core.lang.ServiceException;
-import io.mifos.group.service.internal.repository.AttendeeRepository;
-import io.mifos.group.service.internal.repository.GroupRepository;
 import io.mifos.group.api.v1.domain.Group;
 import io.mifos.group.api.v1.domain.GroupCommand;
 import io.mifos.group.api.v1.domain.GroupPage;
@@ -31,10 +28,18 @@ import io.mifos.group.service.internal.mapper.AttendeeMapper;
 import io.mifos.group.service.internal.mapper.GroupCommandMapper;
 import io.mifos.group.service.internal.mapper.GroupMapper;
 import io.mifos.group.service.internal.mapper.MeetingMapper;
+import io.mifos.group.service.internal.repository.AttendeeRepository;
 import io.mifos.group.service.internal.repository.GroupCommandRepository;
 import io.mifos.group.service.internal.repository.GroupEntity;
+import io.mifos.group.service.internal.repository.GroupRepository;
 import io.mifos.group.service.internal.repository.MeetingEntity;
 import io.mifos.group.service.internal.repository.MeetingRepository;
+import java.time.Clock;
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import org.apache.fineract.cn.lang.ServiceException;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -42,12 +47,6 @@ import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 
-import java.time.Clock;
-import java.time.LocalDate;
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
 @Service
 public class GroupService {
 
diff --git a/service/src/main/java/io/mifos/group/service/rest/GroupDefinitionRestController.java b/service/src/main/java/io/mifos/group/service/rest/GroupDefinitionRestController.java
index 86588ba..8cee95f 100644
--- a/service/src/main/java/io/mifos/group/service/rest/GroupDefinitionRestController.java
+++ b/service/src/main/java/io/mifos/group/service/rest/GroupDefinitionRestController.java
@@ -18,14 +18,16 @@
  */
 package io.mifos.group.service.rest;
 
-import io.mifos.anubis.annotation.AcceptedTokenType;
-import io.mifos.anubis.annotation.Permittable;
-import io.mifos.core.command.gateway.CommandGateway;
-import io.mifos.core.lang.ServiceException;
+import io.mifos.group.api.v1.domain.GroupDefinition;
 import io.mifos.group.service.ServiceConstants;
 import io.mifos.group.service.internal.command.CreateGroupDefinitionCommand;
 import io.mifos.group.service.internal.service.GroupDefinitionService;
-import io.mifos.group.api.v1.domain.GroupDefinition;
+import java.util.List;
+import javax.validation.Valid;
+import org.apache.fineract.cn.anubis.annotation.AcceptedTokenType;
+import org.apache.fineract.cn.anubis.annotation.Permittable;
+import org.apache.fineract.cn.command.gateway.CommandGateway;
+import org.apache.fineract.cn.lang.ServiceException;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -38,9 +40,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestController;
 
-import javax.validation.Valid;
-import java.util.List;
-
 @RestController
 @RequestMapping("/definitions")
 public class GroupDefinitionRestController {
diff --git a/service/src/main/java/io/mifos/group/service/rest/GroupRestController.java b/service/src/main/java/io/mifos/group/service/rest/GroupRestController.java
index 34a6780..9e25f64 100644
--- a/service/src/main/java/io/mifos/group/service/rest/GroupRestController.java
+++ b/service/src/main/java/io/mifos/group/service/rest/GroupRestController.java
@@ -18,15 +18,6 @@
  */
 package io.mifos.group.service.rest;
 
-import io.mifos.anubis.annotation.AcceptedTokenType;
-import io.mifos.anubis.annotation.Permittable;
-import io.mifos.core.command.gateway.CommandGateway;
-import io.mifos.core.lang.ServiceException;
-import io.mifos.group.service.internal.command.SignOffMeetingCommand;
-import io.mifos.group.service.internal.command.UpdateLeadersCommand;
-import io.mifos.group.service.internal.command.UpdateMembersCommand;
-import io.mifos.group.service.internal.service.GroupDefinitionService;
-import io.mifos.group.service.internal.service.GroupService;
 import io.mifos.group.api.v1.domain.AssignedEmployeeHolder;
 import io.mifos.group.api.v1.domain.Group;
 import io.mifos.group.api.v1.domain.GroupCommand;
@@ -38,7 +29,19 @@ import io.mifos.group.service.internal.command.ActivateGroupCommand;
 import io.mifos.group.service.internal.command.CloseGroupCommand;
 import io.mifos.group.service.internal.command.CreateGroupCommand;
 import io.mifos.group.service.internal.command.ReopenGroupCommand;
+import io.mifos.group.service.internal.command.SignOffMeetingCommand;
 import io.mifos.group.service.internal.command.UpdateAssignedEmployeeCommand;
+import io.mifos.group.service.internal.command.UpdateLeadersCommand;
+import io.mifos.group.service.internal.command.UpdateMembersCommand;
+import io.mifos.group.service.internal.service.GroupDefinitionService;
+import io.mifos.group.service.internal.service.GroupService;
+import java.util.List;
+import java.util.Set;
+import javax.validation.Valid;
+import org.apache.fineract.cn.anubis.annotation.AcceptedTokenType;
+import org.apache.fineract.cn.anubis.annotation.Permittable;
+import org.apache.fineract.cn.command.gateway.CommandGateway;
+import org.apache.fineract.cn.lang.ServiceException;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -55,10 +58,6 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestController;
 
-import javax.validation.Valid;
-import java.util.List;
-import java.util.Set;
-
 @RestController
 @RequestMapping("/groups")
 public class GroupRestController {
diff --git a/service/src/main/java/io/mifos/group/service/rest/MigrationRestController.java b/service/src/main/java/io/mifos/group/service/rest/MigrationRestController.java
index efc4886..a1342cc 100644
--- a/service/src/main/java/io/mifos/group/service/rest/MigrationRestController.java
+++ b/service/src/main/java/io/mifos/group/service/rest/MigrationRestController.java
@@ -18,11 +18,11 @@
  */
 package io.mifos.group.service.rest;
 
-import io.mifos.anubis.annotation.AcceptedTokenType;
-import io.mifos.anubis.annotation.Permittable;
-import io.mifos.core.command.gateway.CommandGateway;
 import io.mifos.group.service.ServiceConstants;
 import io.mifos.group.service.internal.command.InitializeServiceCommand;
+import org.apache.fineract.cn.anubis.annotation.AcceptedTokenType;
+import org.apache.fineract.cn.anubis.annotation.Permittable;
+import org.apache.fineract.cn.command.gateway.CommandGateway;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;


[fineract-cn-group] 04/40: added path configurer to allow dots in url

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit c8f9390c7c34def09776a6765310d8188e7891a2
Author: mgeiss <mg...@mifos.org>
AuthorDate: Wed Apr 26 18:19:48 2017 +0200

    added path configurer to allow dots in url
---
 .../src/main/java/io/mifos/group/service/GroupConfiguration.java | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/service/src/main/java/io/mifos/group/service/GroupConfiguration.java b/service/src/main/java/io/mifos/group/service/GroupConfiguration.java
index 0ecceeb..e7d2300 100644
--- a/service/src/main/java/io/mifos/group/service/GroupConfiguration.java
+++ b/service/src/main/java/io/mifos/group/service/GroupConfiguration.java
@@ -30,6 +30,8 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
 
 @SuppressWarnings("WeakerAccess")
 @Configuration
@@ -51,7 +53,7 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 @EnableJpaRepositories({
     "io.mifos.group.service.internal.repository"
 })
-public class GroupConfiguration {
+public class GroupConfiguration extends WebMvcConfigurerAdapter {
 
   public GroupConfiguration() {
     super();
@@ -61,4 +63,9 @@ public class GroupConfiguration {
   public Logger logger() {
     return LoggerFactory.getLogger(ServiceConstants.LOGGER_NAME);
   }
+
+  @Override
+  public void configurePathMatch(final PathMatchConfigurer configurer) {
+    configurer.setUseSuffixPatternMatch(Boolean.FALSE);
+  }
 }


[fineract-cn-group] 39/40: FINCN-148 build with travis-ci.com and upload artifacts to Artifactory

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 1af5bebf601eba6ee0f65c3ca02e55ff4b03fdc5
Author: Juhan Aasaru <Ju...@nortal.com>
AuthorDate: Thu Apr 25 13:41:56 2019 +0300

    FINCN-148 build with travis-ci.com and upload artifacts to Artifactory
---
 service/build.gradle | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/service/build.gradle b/service/build.gradle
index 11b1a51..4090c17 100644
--- a/service/build.gradle
+++ b/service/build.gradle
@@ -32,6 +32,7 @@ buildscript {
 plugins {
     id "com.github.hierynomus.license" version "0.13.1"
     id("org.nosphere.apache.rat") version "0.3.1"
+    id "com.jfrog.artifactory" version "4.9.5"
 }
 
 apply from: '../shared.gradle'
@@ -68,14 +69,14 @@ publishing {
             from components.java
             groupId project.group
             artifactId project.name
-            version project.version
+            version project.findProperty('externalVersion') ?: project.version
         }
         bootService(MavenPublication) {
             // "boot" jar
             artifact ("$buildDir/libs/$project.name-$version-boot.jar")
             groupId project.group
             artifactId ("$project.name-boot")
-            version project.version
+            version project.findProperty('externalVersion') ?: project.version
         }
     }
 }


[fineract-cn-group] 38/40: FINCN-148 build with travis-ci.com and upload artifacts to Artifactory

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit f6c191145f5c3c4a2cd4e7052d36c9a790adbacd
Author: Juhan Aasaru <Ju...@nortal.com>
AuthorDate: Thu Apr 25 13:26:44 2019 +0300

    FINCN-148 build with travis-ci.com and upload artifacts to Artifactory
---
 .travis.yml                 | 30 +++++++++++++++++++
 README.md                   |  2 +-
 api/build.gradle            |  3 +-
 build.gradle                | 10 ++++++-
 component-test/build.gradle |  6 ++--
 shared.gradle               | 17 +++++++++++
 travis.sh                   | 71 +++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 134 insertions(+), 5 deletions(-)

diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..ee300d9
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,30 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+language: java
+sudo: false
+jdk:
+- openjdk8
+install: true
+script: "./travis.sh"
+env:
+  global:
+    - BUILD_SNAPSHOTS_BRANCH=develop
+    - ARTIFACTORY_URL=https://mifos.jfrog.io/mifos
+    - ARTIFACTORY_USER=travis-ci
+    - secure: "FdXWAAcZACsnm7SHD0IYzWi8EzEg60l8CAX/8Y19LcqQvqA303GvqtUY3+evZeTy8acHLwxoKGuAYkGsc6cY3oP+hkCOoGtqne/B7jpTc9lops7qKRBE7SfFgrCDPuelFCmY1ufa77U/CkrwUlizo14FzqjS7pygIVnqYnH4cql/5xJh5I9IW4QYJPlUcXUyEIZzPFVvco6xRJJ8IpzuiJQvoabbKOYERyh3nVKweqfjYBdIF3oWSEDlzB8joP0aJJd4/ODW5vI20kkJduOyzhFPM0F1f1d0mKdORzdng2aKuEIcDOR/olO1cHkxAlz89iB3/+uU/8WMLJupLbbPzg+o1RoOh4x4UcTrBaibU0jL0lJutd/HkG5OveqVtqdkl+IE/EpiJpqWeOZUsx8VtrFS1drE9vcj80yMnCrEoSn6mx4YJN8t5gSbjT7M4QBuXBLHaDe0g7iiMIePQ08RIvaoUo3Hq [...]
diff --git a/README.md b/README.md
index 09c53cb..6347ed7 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Apache Fineract CN Group Management
+# Apache Fineract CN Group Management [![Build Status](https://api.travis-ci.com/apache/fineract-cn-group.svg?branch=develop)](https://travis-ci.com/apache/fineract-cn-group)
 
 This project provides Group management capabilities.
 
diff --git a/api/build.gradle b/api/build.gradle
index ef2d279..46254a9 100644
--- a/api/build.gradle
+++ b/api/build.gradle
@@ -27,6 +27,7 @@ buildscript {
 plugins {
     id "com.github.hierynomus.license" version "0.13.1"
     id("org.nosphere.apache.rat") version "0.3.1"
+    id "com.jfrog.artifactory" version "4.9.5"
 }
 
 apply from: '../shared.gradle'
@@ -45,7 +46,7 @@ publishing {
             from components.java
             groupId project.group
             artifactId project.name
-            version project.version
+            version project.findProperty('externalVersion') ?: project.version
         }
     }
 }
diff --git a/build.gradle b/build.gradle
index 18918cd..eeb68fb 100644
--- a/build.gradle
+++ b/build.gradle
@@ -39,6 +39,14 @@ task publishToMavenLocal {
     dependsOn publishComponentTestToMavenLocal
 }
 
+task artifactoryPublish {
+    group 'all'
+    dependsOn publishToMavenLocal
+    dependsOn gradle.includedBuild('api').task(':artifactoryPublish')
+    dependsOn gradle.includedBuild('service').task(':artifactoryPublish')
+    dependsOn gradle.includedBuild('component-test').task(':artifactoryPublish')
+}
+
 task prepareForTest {
     group 'all'
     dependsOn publishToMavenLocal
@@ -57,4 +65,4 @@ task rat {
     dependsOn gradle.includedBuild('api').task(':rat')
     dependsOn gradle.includedBuild('service').task(':rat')
     dependsOn gradle.includedBuild('component-test').task(':rat')
-}
\ No newline at end of file
+}
diff --git a/component-test/build.gradle b/component-test/build.gradle
index e4edf5a..9ab28b5 100644
--- a/component-test/build.gradle
+++ b/component-test/build.gradle
@@ -33,6 +33,7 @@ buildscript {
 plugins {
     id "com.github.hierynomus.license" version "0.13.1"
     id("org.nosphere.apache.rat") version "0.3.1"
+    id "com.jfrog.artifactory" version "4.9.5"
 }
 
 apply from: '../shared.gradle'
@@ -60,8 +61,9 @@ asciidoctor {
 }
 publishing {
     publications {
-        mavenJava(MavenPublication) {
+        componentTest(MavenPublication) {
             from components.java
+            version project.findProperty('externalVersion') ?: project.version
         }
     }
-}
\ No newline at end of file
+}
diff --git a/shared.gradle b/shared.gradle
index 91ec124..299ada5 100644
--- a/shared.gradle
+++ b/shared.gradle
@@ -43,6 +43,7 @@ tasks.withType(JavaCompile) {
 repositories {
     jcenter()
     mavenLocal()
+    maven { url 'https://mifos.jfrog.io/mifos/libs-snapshot/' }
 }
 
 dependencyManagement {
@@ -72,6 +73,22 @@ jar {
     from sourceSets.main.allSource
 }
 
+artifactory {
+    contextUrl = System.getenv("ARTIFACTORY_URL")
+    publish {
+        repository {
+            repoKey = project.findProperty('artifactoryRepoKey')
+            username = System.getenv("ARTIFACTORY_USER")
+            password = System.getenv("ARTIFACTORY_PASSWORD")
+        }
+
+        defaults {
+            publications ('api', 'componentTest', 'service', 'bootService')
+        }
+    }
+}
+artifactoryPublish.dependsOn('clean','publishToMavenLocal')
+
 license {
     header rootProject.file('../HEADER')
     strictCheck true
diff --git a/travis.sh b/travis.sh
new file mode 100755
index 0000000..03a75ee
--- /dev/null
+++ b/travis.sh
@@ -0,0 +1,71 @@
+#!/usr/bin/env bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+
+# Documentation: https://cwiki.apache.org/confluence/display/FINERACT/Fineract-CN+Artifactory
+
+#Exit immediately if a command exits with a non-zero status.
+set -e
+EXIT_STATUS=0
+
+# Builds and Publishes a SNAPSHOT
+function build_snapshot() {
+  echo -e "Building and publishing a snapshot out of branch [$TRAVIS_BRANCH]"
+  ./gradlew -PartifactoryRepoKey=libs-snapshot-local -DbuildInfo.build.number=${TRAVIS_COMMIT::7} artifactoryPublish --stacktrace || EXIT_STATUS=$?
+}
+
+# Builds a Pull Request
+function build_pullrequest() {
+  echo -e "Building pull request #$TRAVIS_PULL_REQUEST of branch [$TRAVIS_BRANCH]. Won't publish anything to Artifactory."
+  ./gradlew publishToMavenLocal rat || EXIT_STATUS=$?
+}
+
+# For other branches we need to add branch name as prefix
+function build_otherbranch() {
+  echo -e "Building a snapshot out of branch [$TRAVIS_BRANCH] and publishing it with prefix '${TRAVIS_BRANCH}-SNAPSHOT'"
+  ./gradlew -PartifactoryRepoKey=libs-snapshot-local -DbuildInfo.build.number=${TRAVIS_COMMIT::7} -PexternalVersion=${TRAVIS_BRANCH}-SNAPSHOT artifactoryPublish --stacktrace || EXIT_STATUS=$?
+}
+
+# Builds and Publishes a Tag
+function build_tag() {
+  echo -e "Building tag [$TRAVIS_TAG] and publishing it as a release"
+  ./gradlew -PartifactoryRepoKey=libs-release-local -PexternalVersion=$TRAVIS_TAG artifactoryPublish --stacktrace || EXIT_STATUS=$?
+
+}
+
+echo -e "TRAVIS_BRANCH=$TRAVIS_BRANCH"
+echo -e "TRAVIS_TAG=$TRAVIS_TAG"
+echo -e "TRAVIS_COMMIT=${TRAVIS_COMMIT::7}"
+echo -e "TRAVIS_PULL_REQUEST=$TRAVIS_PULL_REQUEST"
+
+# Build Logic
+if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
+  build_pullrequest
+elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" != "$BUILD_SNAPSHOTS_BRANCH" ] && [ "$TRAVIS_TAG" == "" ]  ; then
+  build_otherbranch
+elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "$BUILD_SNAPSHOTS_BRANCH" ] && [ "$TRAVIS_TAG" == "" ] ; then
+  build_snapshot
+elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" != "" ]; then
+  build_tag
+else
+  echo -e "WARN: Unexpected env variable values => Branch [$TRAVIS_BRANCH], Tag [$TRAVIS_TAG], Pull Request [#$TRAVIS_PULL_REQUEST]"
+  ./gradlew clean build
+fi
+
+exit ${EXIT_STATUS}


[fineract-cn-group] 17/40: Improving directory structure.

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit e8ae29842e0569fbd9b7fe897b95f7f268cf3592
Author: Myrle Krantz <my...@apache.org>
AuthorDate: Mon Apr 16 20:55:38 2018 +0200

    Improving directory structure.
---
 .../org/apache/fineract/cn/group/TestGroup.java    |  1 -
 .../fineract/cn/group/TestGroupDefinition.java     |  1 -
 .../cn/group/{service => }/GroupApplication.java   |  2 +-
 .../cn/group/{service => }/GroupConfiguration.java | 12 +++---
 .../cn/group/{service => }/ServiceConstants.java   |  2 +-
 .../internal/command/ActivateGroupCommand.java     |  2 +-
 .../internal/command/CloseGroupCommand.java        |  2 +-
 .../internal/command/CreateGroupCommand.java       |  2 +-
 .../command/CreateGroupDefinitionCommand.java      |  2 +-
 .../internal/command/InitializeServiceCommand.java |  2 +-
 .../internal/command/ReopenGroupCommand.java       |  2 +-
 .../internal/command/SignOffMeetingCommand.java    |  2 +-
 .../command/UpdateAssignedEmployeeCommand.java     |  2 +-
 .../internal/command/UpdateLeadersCommand.java     |  2 +-
 .../internal/command/UpdateMembersCommand.java     |  2 +-
 .../internal/command/handler/GroupAggregate.java   | 48 +++++++++++-----------
 .../command/handler/MigrationAggregate.java        |  6 +--
 .../internal/mapper/AddressMapper.java             |  4 +-
 .../internal/mapper/AttendeeMapper.java            |  4 +-
 .../internal/mapper/GroupCommandMapper.java        |  4 +-
 .../internal/mapper/GroupDefinitionMapper.java     |  4 +-
 .../{service => }/internal/mapper/GroupMapper.java |  4 +-
 .../internal/mapper/MeetingMapper.java             |  4 +-
 .../internal/repository/AddressEntity.java         |  2 +-
 .../internal/repository/AddressRepository.java     |  2 +-
 .../internal/repository/AttendeeEntity.java        |  2 +-
 .../internal/repository/AttendeeRepository.java    |  2 +-
 .../internal/repository/GroupCommandEntity.java    |  2 +-
 .../repository/GroupCommandRepository.java         |  2 +-
 .../internal/repository/GroupDefinitionEntity.java |  2 +-
 .../repository/GroupDefinitionRepository.java      |  2 +-
 .../internal/repository/GroupEntity.java           |  2 +-
 .../internal/repository/GroupRepository.java       |  2 +-
 .../internal/repository/MeetingEntity.java         |  2 +-
 .../internal/repository/MeetingRepository.java     |  2 +-
 .../internal/service/GroupDefinitionService.java   |  8 ++--
 .../internal/service/GroupService.java             | 26 ++++++------
 .../rest/GroupDefinitionRestController.java        |  8 ++--
 .../{service => }/rest/GroupRestController.java    | 24 +++++------
 .../rest/MigrationRestController.java              |  6 +--
 40 files changed, 105 insertions(+), 107 deletions(-)

diff --git a/component-test/src/main/java/org/apache/fineract/cn/group/TestGroup.java b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroup.java
index 19df79c..1307d66 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/group/TestGroup.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroup.java
@@ -27,7 +27,6 @@ import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
 import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
 import org.apache.fineract.cn.group.api.v1.domain.Meeting;
 import org.apache.fineract.cn.group.api.v1.domain.SignOffMeeting;
-import org.apache.fineract.cn.group.service.GroupConfiguration;
 import org.apache.fineract.cn.group.util.GroupDefinitionGenerator;
 import org.apache.fineract.cn.group.util.GroupGenerator;
 import java.time.Clock;
diff --git a/component-test/src/main/java/org/apache/fineract/cn/group/TestGroupDefinition.java b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroupDefinition.java
index 4af1087..608cf64 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/group/TestGroupDefinition.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/group/TestGroupDefinition.java
@@ -21,7 +21,6 @@ package org.apache.fineract.cn.group;
 import org.apache.fineract.cn.group.api.v1.EventConstants;
 import org.apache.fineract.cn.group.api.v1.client.GroupManager;
 import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
-import org.apache.fineract.cn.group.service.GroupConfiguration;
 import org.apache.fineract.cn.group.util.GroupDefinitionGenerator;
 import org.apache.fineract.cn.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
 import org.apache.fineract.cn.api.context.AutoUserContext;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/GroupApplication.java b/service/src/main/java/org/apache/fineract/cn/group/GroupApplication.java
similarity index 95%
rename from service/src/main/java/org/apache/fineract/cn/group/service/GroupApplication.java
rename to service/src/main/java/org/apache/fineract/cn/group/GroupApplication.java
index fc17f94..117e078 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/GroupApplication.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/GroupApplication.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service;
+package org.apache.fineract.cn.group;
 
 import org.springframework.boot.SpringApplication;
 
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/GroupConfiguration.java b/service/src/main/java/org/apache/fineract/cn/group/GroupConfiguration.java
similarity index 87%
rename from service/src/main/java/org/apache/fineract/cn/group/service/GroupConfiguration.java
rename to service/src/main/java/org/apache/fineract/cn/group/GroupConfiguration.java
index ee583e0..f2f0642 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/GroupConfiguration.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/GroupConfiguration.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service;
+package org.apache.fineract.cn.group;
 
 import org.apache.fineract.cn.anubis.config.EnableAnubis;
 import org.apache.fineract.cn.async.config.EnableAsync;
@@ -48,13 +48,13 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
 @EnableAnubis
 @EnableServiceException
 @ComponentScan({
-    "org.apache.fineract.cn.group.service.rest",
-    "org.apache.fineract.cn.group.service.internal.service",
-    "org.apache.fineract.cn.group.service.internal.repository",
-    "org.apache.fineract.cn.group.service.internal.command.handler"
+    "org.apache.fineract.cn.group.rest",
+    "org.apache.fineract.cn.group.internal.service",
+    "org.apache.fineract.cn.group.internal.repository",
+    "org.apache.fineract.cn.group.internal.command.handler"
 })
 @EnableJpaRepositories({
-    "org.apache.fineract.cn.group.service.internal.repository"
+    "org.apache.fineract.cn.group.internal.repository"
 })
 public class GroupConfiguration extends WebMvcConfigurerAdapter {
 
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/ServiceConstants.java b/service/src/main/java/org/apache/fineract/cn/group/ServiceConstants.java
similarity index 95%
rename from service/src/main/java/org/apache/fineract/cn/group/service/ServiceConstants.java
rename to service/src/main/java/org/apache/fineract/cn/group/ServiceConstants.java
index de8f2ff..1da6c58 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/ServiceConstants.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/ServiceConstants.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service;
+package org.apache.fineract.cn.group;
 
 public interface ServiceConstants {
   String LOGGER_NAME = "group-logger";
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/ActivateGroupCommand.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/ActivateGroupCommand.java
similarity index 95%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/command/ActivateGroupCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/command/ActivateGroupCommand.java
index 1892d62..8d654b7 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/ActivateGroupCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/ActivateGroupCommand.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.command;
+package org.apache.fineract.cn.group.internal.command;
 
 import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
 
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CloseGroupCommand.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/CloseGroupCommand.java
similarity index 95%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CloseGroupCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/command/CloseGroupCommand.java
index 43a6937..54cdab4 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CloseGroupCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/CloseGroupCommand.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.command;
+package org.apache.fineract.cn.group.internal.command;
 
 import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
 
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CreateGroupCommand.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/CreateGroupCommand.java
similarity index 94%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CreateGroupCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/command/CreateGroupCommand.java
index a367a12..f995bca 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CreateGroupCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/CreateGroupCommand.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.command;
+package org.apache.fineract.cn.group.internal.command;
 
 import org.apache.fineract.cn.group.api.v1.domain.Group;
 
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CreateGroupDefinitionCommand.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/CreateGroupDefinitionCommand.java
similarity index 95%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CreateGroupDefinitionCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/command/CreateGroupDefinitionCommand.java
index c034284..98a13b1 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/CreateGroupDefinitionCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/CreateGroupDefinitionCommand.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.command;
+package org.apache.fineract.cn.group.internal.command;
 
 import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
 
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/InitializeServiceCommand.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/InitializeServiceCommand.java
similarity index 93%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/command/InitializeServiceCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/command/InitializeServiceCommand.java
index 8d65200..b67a546 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/InitializeServiceCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/InitializeServiceCommand.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.command;
+package org.apache.fineract.cn.group.internal.command;
 
 public class InitializeServiceCommand {
 
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/ReopenGroupCommand.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/ReopenGroupCommand.java
similarity index 95%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/command/ReopenGroupCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/command/ReopenGroupCommand.java
index f21e26a..a96f239 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/ReopenGroupCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/ReopenGroupCommand.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.command;
+package org.apache.fineract.cn.group.internal.command;
 
 import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
 
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/SignOffMeetingCommand.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/SignOffMeetingCommand.java
similarity index 95%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/command/SignOffMeetingCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/command/SignOffMeetingCommand.java
index f67962d..da1ae48 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/SignOffMeetingCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/SignOffMeetingCommand.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.command;
+package org.apache.fineract.cn.group.internal.command;
 
 import org.apache.fineract.cn.group.api.v1.domain.SignOffMeeting;
 
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateAssignedEmployeeCommand.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateAssignedEmployeeCommand.java
similarity index 95%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateAssignedEmployeeCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateAssignedEmployeeCommand.java
index f44d86b..7168e27 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateAssignedEmployeeCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateAssignedEmployeeCommand.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.command;
+package org.apache.fineract.cn.group.internal.command;
 
 public class UpdateAssignedEmployeeCommand {
 
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateLeadersCommand.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateLeadersCommand.java
similarity index 95%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateLeadersCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateLeadersCommand.java
index 5a5fc72..3e0fcc7 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateLeadersCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateLeadersCommand.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.command;
+package org.apache.fineract.cn.group.internal.command;
 
 import java.util.Set;
 
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateMembersCommand.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateMembersCommand.java
similarity index 95%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateMembersCommand.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateMembersCommand.java
index dd4d86e..ffd5305 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/UpdateMembersCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateMembersCommand.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.command;
+package org.apache.fineract.cn.group.internal.command;
 
 import java.util.Set;
 
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/handler/GroupAggregate.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
similarity index 88%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/command/handler/GroupAggregate.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
index 3d99783..2ddf42f 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/handler/GroupAggregate.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.command.handler;
+package org.apache.fineract.cn.group.internal.command.handler;
 
 import org.apache.fineract.cn.group.api.v1.EventConstants;
 import org.apache.fineract.cn.group.api.v1.domain.Attendee;
@@ -25,29 +25,29 @@ import org.apache.fineract.cn.group.api.v1.domain.Group;
 import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
 import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
 import org.apache.fineract.cn.group.api.v1.domain.SignOffMeeting;
-import org.apache.fineract.cn.group.service.internal.command.ActivateGroupCommand;
-import org.apache.fineract.cn.group.service.internal.command.CloseGroupCommand;
-import org.apache.fineract.cn.group.service.internal.command.CreateGroupCommand;
-import org.apache.fineract.cn.group.service.internal.command.CreateGroupDefinitionCommand;
-import org.apache.fineract.cn.group.service.internal.command.ReopenGroupCommand;
-import org.apache.fineract.cn.group.service.internal.command.SignOffMeetingCommand;
-import org.apache.fineract.cn.group.service.internal.command.UpdateAssignedEmployeeCommand;
-import org.apache.fineract.cn.group.service.internal.command.UpdateLeadersCommand;
-import org.apache.fineract.cn.group.service.internal.command.UpdateMembersCommand;
-import org.apache.fineract.cn.group.service.internal.mapper.AddressMapper;
-import org.apache.fineract.cn.group.service.internal.mapper.GroupCommandMapper;
-import org.apache.fineract.cn.group.service.internal.repository.AddressEntity;
-import org.apache.fineract.cn.group.service.internal.repository.AddressRepository;
-import org.apache.fineract.cn.group.service.internal.repository.AttendeeEntity;
-import org.apache.fineract.cn.group.service.internal.repository.AttendeeRepository;
-import org.apache.fineract.cn.group.service.internal.repository.GroupCommandEntity;
-import org.apache.fineract.cn.group.service.internal.repository.GroupCommandRepository;
-import org.apache.fineract.cn.group.service.internal.repository.GroupDefinitionEntity;
-import org.apache.fineract.cn.group.service.internal.repository.GroupDefinitionRepository;
-import org.apache.fineract.cn.group.service.internal.repository.GroupEntity;
-import org.apache.fineract.cn.group.service.internal.repository.GroupRepository;
-import org.apache.fineract.cn.group.service.internal.repository.MeetingEntity;
-import org.apache.fineract.cn.group.service.internal.repository.MeetingRepository;
+import org.apache.fineract.cn.group.internal.command.ActivateGroupCommand;
+import org.apache.fineract.cn.group.internal.command.CloseGroupCommand;
+import org.apache.fineract.cn.group.internal.command.CreateGroupCommand;
+import org.apache.fineract.cn.group.internal.command.CreateGroupDefinitionCommand;
+import org.apache.fineract.cn.group.internal.command.ReopenGroupCommand;
+import org.apache.fineract.cn.group.internal.command.SignOffMeetingCommand;
+import org.apache.fineract.cn.group.internal.command.UpdateAssignedEmployeeCommand;
+import org.apache.fineract.cn.group.internal.command.UpdateLeadersCommand;
+import org.apache.fineract.cn.group.internal.command.UpdateMembersCommand;
+import org.apache.fineract.cn.group.internal.mapper.AddressMapper;
+import org.apache.fineract.cn.group.internal.mapper.GroupCommandMapper;
+import org.apache.fineract.cn.group.internal.repository.AddressEntity;
+import org.apache.fineract.cn.group.internal.repository.AddressRepository;
+import org.apache.fineract.cn.group.internal.repository.AttendeeEntity;
+import org.apache.fineract.cn.group.internal.repository.AttendeeRepository;
+import org.apache.fineract.cn.group.internal.repository.GroupCommandEntity;
+import org.apache.fineract.cn.group.internal.repository.GroupCommandRepository;
+import org.apache.fineract.cn.group.internal.repository.GroupDefinitionEntity;
+import org.apache.fineract.cn.group.internal.repository.GroupDefinitionRepository;
+import org.apache.fineract.cn.group.internal.repository.GroupEntity;
+import org.apache.fineract.cn.group.internal.repository.GroupRepository;
+import org.apache.fineract.cn.group.internal.repository.MeetingEntity;
+import org.apache.fineract.cn.group.internal.repository.MeetingRepository;
 import java.time.Clock;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/handler/MigrationAggregate.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/MigrationAggregate.java
similarity index 91%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/command/handler/MigrationAggregate.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/MigrationAggregate.java
index 66fbd9e..3ea23ff 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/command/handler/MigrationAggregate.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/MigrationAggregate.java
@@ -16,11 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.command.handler;
+package org.apache.fineract.cn.group.internal.command.handler;
 
 import org.apache.fineract.cn.group.api.v1.EventConstants;
-import org.apache.fineract.cn.group.service.ServiceConstants;
-import org.apache.fineract.cn.group.service.internal.command.InitializeServiceCommand;
+import org.apache.fineract.cn.group.ServiceConstants;
+import org.apache.fineract.cn.group.internal.command.InitializeServiceCommand;
 import javax.sql.DataSource;
 import org.apache.fineract.cn.command.annotation.Aggregate;
 import org.apache.fineract.cn.command.annotation.CommandHandler;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/AddressMapper.java b/service/src/main/java/org/apache/fineract/cn/group/internal/mapper/AddressMapper.java
similarity index 92%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/AddressMapper.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/mapper/AddressMapper.java
index aad505e..995189f 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/AddressMapper.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/mapper/AddressMapper.java
@@ -16,9 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.mapper;
+package org.apache.fineract.cn.group.internal.mapper;
 
-import org.apache.fineract.cn.group.service.internal.repository.AddressEntity;
+import org.apache.fineract.cn.group.internal.repository.AddressEntity;
 import org.apache.fineract.cn.group.api.v1.domain.Address;
 
 public class AddressMapper {
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/AttendeeMapper.java b/service/src/main/java/org/apache/fineract/cn/group/internal/mapper/AttendeeMapper.java
similarity index 89%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/AttendeeMapper.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/mapper/AttendeeMapper.java
index 94be880..cee9d56 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/AttendeeMapper.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/mapper/AttendeeMapper.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.mapper;
+package org.apache.fineract.cn.group.internal.mapper;
 
 import org.apache.fineract.cn.group.api.v1.domain.Attendee;
-import org.apache.fineract.cn.group.service.internal.repository.AttendeeEntity;
+import org.apache.fineract.cn.group.internal.repository.AttendeeEntity;
 
 public class AttendeeMapper {
 
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupCommandMapper.java b/service/src/main/java/org/apache/fineract/cn/group/internal/mapper/GroupCommandMapper.java
similarity index 93%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupCommandMapper.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/mapper/GroupCommandMapper.java
index 90b0027..301a0a0 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupCommandMapper.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/mapper/GroupCommandMapper.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.mapper;
+package org.apache.fineract.cn.group.internal.mapper;
 
 import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
-import org.apache.fineract.cn.group.service.internal.repository.GroupCommandEntity;
+import org.apache.fineract.cn.group.internal.repository.GroupCommandEntity;
 import java.time.Clock;
 import java.time.LocalDateTime;
 import org.apache.fineract.cn.api.util.UserContextHolder;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupDefinitionMapper.java b/service/src/main/java/org/apache/fineract/cn/group/internal/mapper/GroupDefinitionMapper.java
similarity index 93%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupDefinitionMapper.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/mapper/GroupDefinitionMapper.java
index 2b33d43..38b4a7e 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupDefinitionMapper.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/mapper/GroupDefinitionMapper.java
@@ -16,11 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.mapper;
+package org.apache.fineract.cn.group.internal.mapper;
 
 import org.apache.fineract.cn.group.api.v1.domain.Cycle;
 import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
-import org.apache.fineract.cn.group.service.internal.repository.GroupDefinitionEntity;
+import org.apache.fineract.cn.group.internal.repository.GroupDefinitionEntity;
 import org.apache.fineract.cn.lang.DateConverter;
 
 public class GroupDefinitionMapper {
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupMapper.java b/service/src/main/java/org/apache/fineract/cn/group/internal/mapper/GroupMapper.java
similarity index 93%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupMapper.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/mapper/GroupMapper.java
index 45c40ef..6195222 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/GroupMapper.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/mapper/GroupMapper.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.mapper;
+package org.apache.fineract.cn.group.internal.mapper;
 
 import org.apache.fineract.cn.group.api.v1.domain.Group;
-import org.apache.fineract.cn.group.service.internal.repository.GroupEntity;
+import org.apache.fineract.cn.group.internal.repository.GroupEntity;
 import org.apache.fineract.cn.lang.DateConverter;
 import org.springframework.util.StringUtils;
 
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/MeetingMapper.java b/service/src/main/java/org/apache/fineract/cn/group/internal/mapper/MeetingMapper.java
similarity index 92%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/MeetingMapper.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/mapper/MeetingMapper.java
index 2d91e1d..1073155 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/mapper/MeetingMapper.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/mapper/MeetingMapper.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.mapper;
+package org.apache.fineract.cn.group.internal.mapper;
 
 import org.apache.fineract.cn.group.api.v1.domain.Meeting;
-import org.apache.fineract.cn.group.service.internal.repository.MeetingEntity;
+import org.apache.fineract.cn.group.internal.repository.MeetingEntity;
 import org.apache.fineract.cn.lang.DateConverter;
 
 public class MeetingMapper {
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AddressEntity.java b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/AddressEntity.java
similarity index 97%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AddressEntity.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/repository/AddressEntity.java
index bbdde39..7474499 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AddressEntity.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/AddressEntity.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.repository;
+package org.apache.fineract.cn.group.internal.repository;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AddressRepository.java b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/AddressRepository.java
similarity index 93%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AddressRepository.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/repository/AddressRepository.java
index 03146b4..535ffae 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AddressRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/AddressRepository.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.repository;
+package org.apache.fineract.cn.group.internal.repository;
 
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AttendeeEntity.java b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/AttendeeEntity.java
similarity index 97%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AttendeeEntity.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/repository/AttendeeEntity.java
index fa2d5d5..6252f47 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AttendeeEntity.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/AttendeeEntity.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.repository;
+package org.apache.fineract.cn.group.internal.repository;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AttendeeRepository.java b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/AttendeeRepository.java
similarity index 94%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AttendeeRepository.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/repository/AttendeeRepository.java
index d50fefd..8b16819 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/AttendeeRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/AttendeeRepository.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.repository;
+package org.apache.fineract.cn.group.internal.repository;
 
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupCommandEntity.java b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupCommandEntity.java
similarity index 97%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupCommandEntity.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupCommandEntity.java
index 7f60768..67c8286 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupCommandEntity.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupCommandEntity.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.repository;
+package org.apache.fineract.cn.group.internal.repository;
 
 import java.time.LocalDateTime;
 import javax.persistence.Column;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupCommandRepository.java b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupCommandRepository.java
similarity index 94%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupCommandRepository.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupCommandRepository.java
index eef9d7f..f729204 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupCommandRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupCommandRepository.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.repository;
+package org.apache.fineract.cn.group.internal.repository;
 
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupDefinitionEntity.java b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupDefinitionEntity.java
similarity index 98%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupDefinitionEntity.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupDefinitionEntity.java
index 3f755b2..5b4c856 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupDefinitionEntity.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupDefinitionEntity.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.repository;
+package org.apache.fineract.cn.group.internal.repository;
 
 import java.time.LocalDateTime;
 import javax.persistence.Column;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupDefinitionRepository.java b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupDefinitionRepository.java
similarity index 94%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupDefinitionRepository.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupDefinitionRepository.java
index 74724ee..5bb130b 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupDefinitionRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupDefinitionRepository.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.repository;
+package org.apache.fineract.cn.group.internal.repository;
 
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupEntity.java b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupEntity.java
similarity index 98%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupEntity.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupEntity.java
index 7fc37df..10e8a57 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupEntity.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupEntity.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.repository;
+package org.apache.fineract.cn.group.internal.repository;
 
 import java.time.LocalDateTime;
 import javax.persistence.Column;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupRepository.java b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupRepository.java
similarity index 95%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupRepository.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupRepository.java
index 0186fbf..d1cf609 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/GroupRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupRepository.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.repository;
+package org.apache.fineract.cn.group.internal.repository;
 
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/MeetingEntity.java b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/MeetingEntity.java
similarity index 98%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/MeetingEntity.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/repository/MeetingEntity.java
index 86c339f..dc9fef9 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/MeetingEntity.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/MeetingEntity.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.repository;
+package org.apache.fineract.cn.group.internal.repository;
 
 import java.time.LocalDate;
 import java.time.LocalDateTime;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/MeetingRepository.java b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/MeetingRepository.java
similarity index 96%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/MeetingRepository.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/repository/MeetingRepository.java
index e8125fe..c094de0 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/repository/MeetingRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/MeetingRepository.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.repository;
+package org.apache.fineract.cn.group.internal.repository;
 
 import java.time.LocalDate;
 import java.util.List;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/service/GroupDefinitionService.java b/service/src/main/java/org/apache/fineract/cn/group/internal/service/GroupDefinitionService.java
similarity index 87%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/service/GroupDefinitionService.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/service/GroupDefinitionService.java
index 75e6bac..6d34e81 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/service/GroupDefinitionService.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/service/GroupDefinitionService.java
@@ -16,12 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.service;
+package org.apache.fineract.cn.group.internal.service;
 
 import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
-import org.apache.fineract.cn.group.service.ServiceConstants;
-import org.apache.fineract.cn.group.service.internal.mapper.GroupDefinitionMapper;
-import org.apache.fineract.cn.group.service.internal.repository.GroupDefinitionRepository;
+import org.apache.fineract.cn.group.ServiceConstants;
+import org.apache.fineract.cn.group.internal.mapper.GroupDefinitionMapper;
+import org.apache.fineract.cn.group.internal.repository.GroupDefinitionRepository;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/internal/service/GroupService.java b/service/src/main/java/org/apache/fineract/cn/group/internal/service/GroupService.java
similarity index 83%
rename from service/src/main/java/org/apache/fineract/cn/group/service/internal/service/GroupService.java
rename to service/src/main/java/org/apache/fineract/cn/group/internal/service/GroupService.java
index d842714..2b7909c 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/internal/service/GroupService.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/service/GroupService.java
@@ -16,24 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.internal.service;
+package org.apache.fineract.cn.group.internal.service;
 
 import org.apache.fineract.cn.group.api.v1.domain.Group;
 import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
 import org.apache.fineract.cn.group.api.v1.domain.GroupPage;
 import org.apache.fineract.cn.group.api.v1.domain.Meeting;
-import org.apache.fineract.cn.group.service.ServiceConstants;
-import org.apache.fineract.cn.group.service.internal.mapper.AddressMapper;
-import org.apache.fineract.cn.group.service.internal.mapper.AttendeeMapper;
-import org.apache.fineract.cn.group.service.internal.mapper.GroupCommandMapper;
-import org.apache.fineract.cn.group.service.internal.mapper.GroupMapper;
-import org.apache.fineract.cn.group.service.internal.mapper.MeetingMapper;
-import org.apache.fineract.cn.group.service.internal.repository.AttendeeRepository;
-import org.apache.fineract.cn.group.service.internal.repository.GroupCommandRepository;
-import org.apache.fineract.cn.group.service.internal.repository.GroupEntity;
-import org.apache.fineract.cn.group.service.internal.repository.GroupRepository;
-import org.apache.fineract.cn.group.service.internal.repository.MeetingEntity;
-import org.apache.fineract.cn.group.service.internal.repository.MeetingRepository;
+import org.apache.fineract.cn.group.ServiceConstants;
+import org.apache.fineract.cn.group.internal.mapper.AddressMapper;
+import org.apache.fineract.cn.group.internal.mapper.AttendeeMapper;
+import org.apache.fineract.cn.group.internal.mapper.GroupCommandMapper;
+import org.apache.fineract.cn.group.internal.mapper.GroupMapper;
+import org.apache.fineract.cn.group.internal.mapper.MeetingMapper;
+import org.apache.fineract.cn.group.internal.repository.AttendeeRepository;
+import org.apache.fineract.cn.group.internal.repository.GroupCommandRepository;
+import org.apache.fineract.cn.group.internal.repository.GroupEntity;
+import org.apache.fineract.cn.group.internal.repository.GroupRepository;
+import org.apache.fineract.cn.group.internal.repository.MeetingEntity;
+import org.apache.fineract.cn.group.internal.repository.MeetingRepository;
 import java.time.Clock;
 import java.time.LocalDate;
 import java.util.List;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/rest/GroupDefinitionRestController.java b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
similarity index 93%
rename from service/src/main/java/org/apache/fineract/cn/group/service/rest/GroupDefinitionRestController.java
rename to service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
index 075427f..a526450 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/rest/GroupDefinitionRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
@@ -16,12 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.rest;
+package org.apache.fineract.cn.group.rest;
 
 import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
-import org.apache.fineract.cn.group.service.ServiceConstants;
-import org.apache.fineract.cn.group.service.internal.command.CreateGroupDefinitionCommand;
-import org.apache.fineract.cn.group.service.internal.service.GroupDefinitionService;
+import org.apache.fineract.cn.group.ServiceConstants;
+import org.apache.fineract.cn.group.internal.command.CreateGroupDefinitionCommand;
+import org.apache.fineract.cn.group.internal.service.GroupDefinitionService;
 import java.util.List;
 import javax.validation.Valid;
 import org.apache.fineract.cn.anubis.annotation.AcceptedTokenType;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/rest/GroupRestController.java b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupRestController.java
similarity index 91%
rename from service/src/main/java/org/apache/fineract/cn/group/service/rest/GroupRestController.java
rename to service/src/main/java/org/apache/fineract/cn/group/rest/GroupRestController.java
index 51e66cd..c9edae9 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/rest/GroupRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupRestController.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.rest;
+package org.apache.fineract.cn.group.rest;
 
 import org.apache.fineract.cn.group.api.v1.domain.AssignedEmployeeHolder;
 import org.apache.fineract.cn.group.api.v1.domain.Group;
@@ -24,17 +24,17 @@ import org.apache.fineract.cn.group.api.v1.domain.GroupCommand;
 import org.apache.fineract.cn.group.api.v1.domain.GroupPage;
 import org.apache.fineract.cn.group.api.v1.domain.Meeting;
 import org.apache.fineract.cn.group.api.v1.domain.SignOffMeeting;
-import org.apache.fineract.cn.group.service.ServiceConstants;
-import org.apache.fineract.cn.group.service.internal.command.ActivateGroupCommand;
-import org.apache.fineract.cn.group.service.internal.command.CloseGroupCommand;
-import org.apache.fineract.cn.group.service.internal.command.CreateGroupCommand;
-import org.apache.fineract.cn.group.service.internal.command.ReopenGroupCommand;
-import org.apache.fineract.cn.group.service.internal.command.SignOffMeetingCommand;
-import org.apache.fineract.cn.group.service.internal.command.UpdateAssignedEmployeeCommand;
-import org.apache.fineract.cn.group.service.internal.command.UpdateLeadersCommand;
-import org.apache.fineract.cn.group.service.internal.command.UpdateMembersCommand;
-import org.apache.fineract.cn.group.service.internal.service.GroupDefinitionService;
-import org.apache.fineract.cn.group.service.internal.service.GroupService;
+import org.apache.fineract.cn.group.ServiceConstants;
+import org.apache.fineract.cn.group.internal.command.ActivateGroupCommand;
+import org.apache.fineract.cn.group.internal.command.CloseGroupCommand;
+import org.apache.fineract.cn.group.internal.command.CreateGroupCommand;
+import org.apache.fineract.cn.group.internal.command.ReopenGroupCommand;
+import org.apache.fineract.cn.group.internal.command.SignOffMeetingCommand;
+import org.apache.fineract.cn.group.internal.command.UpdateAssignedEmployeeCommand;
+import org.apache.fineract.cn.group.internal.command.UpdateLeadersCommand;
+import org.apache.fineract.cn.group.internal.command.UpdateMembersCommand;
+import org.apache.fineract.cn.group.internal.service.GroupDefinitionService;
+import org.apache.fineract.cn.group.internal.service.GroupService;
 import java.util.List;
 import java.util.Set;
 import javax.validation.Valid;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/service/rest/MigrationRestController.java b/service/src/main/java/org/apache/fineract/cn/group/rest/MigrationRestController.java
similarity index 92%
rename from service/src/main/java/org/apache/fineract/cn/group/service/rest/MigrationRestController.java
rename to service/src/main/java/org/apache/fineract/cn/group/rest/MigrationRestController.java
index ebd850e..9bc8f92 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/service/rest/MigrationRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/rest/MigrationRestController.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.group.service.rest;
+package org.apache.fineract.cn.group.rest;
 
-import org.apache.fineract.cn.group.service.ServiceConstants;
-import org.apache.fineract.cn.group.service.internal.command.InitializeServiceCommand;
+import org.apache.fineract.cn.group.ServiceConstants;
+import org.apache.fineract.cn.group.internal.command.InitializeServiceCommand;
 import org.apache.fineract.cn.anubis.annotation.AcceptedTokenType;
 import org.apache.fineract.cn.anubis.annotation.Permittable;
 import org.apache.fineract.cn.command.gateway.CommandGateway;


[fineract-cn-group] 10/40: Removed unused year and name variables

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit cc472fc6fbe93d9862aaf4ee987f7bee773bc31d
Author: Isaac Kamga <u2...@gmail.com>
AuthorDate: Mon Mar 5 21:19:16 2018 +0100

    Removed unused year and name variables
---
 shared.gradle | 2 --
 1 file changed, 2 deletions(-)

diff --git a/shared.gradle b/shared.gradle
index 967c06f..06e2e4b 100644
--- a/shared.gradle
+++ b/shared.gradle
@@ -65,6 +65,4 @@ license {
         yaml = 'SCRIPT_STYLE'
         uxf = 'XML_STYLE'
     }
-    ext.year = Calendar.getInstance().get(Calendar.YEAR)
-    ext.name = 'The Apache Software Foundation'
 }


[fineract-cn-group] 12/40: Adding rat checks.

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit b166c811c58e36d51d3e566ba7ad450a0b67cbe2
Author: Myrle Krantz <my...@apache.org>
AuthorDate: Mon Apr 9 18:39:05 2018 +0200

    Adding rat checks.
---
 api/build.gradle               | 18 ++++++++++++++++++
 api/settings.gradle            | 17 +++++++++++++++++
 build.gradle                   | 24 ++++++++++++++++++++++++
 component-test/build.gradle    | 18 ++++++++++++++++++
 component-test/settings.gradle | 17 +++++++++++++++++
 service/build.gradle           | 18 ++++++++++++++++++
 service/settings.gradle        | 17 +++++++++++++++++
 settings.gradle                | 17 +++++++++++++++++
 shared.gradle                  | 30 ++++++++++++++++++++++++++++++
 9 files changed, 176 insertions(+)

diff --git a/api/build.gradle b/api/build.gradle
index dcc39a6..ef2d279 100644
--- a/api/build.gradle
+++ b/api/build.gradle
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 buildscript {
     repositories {
         jcenter()
@@ -9,6 +26,7 @@ buildscript {
 
 plugins {
     id "com.github.hierynomus.license" version "0.13.1"
+    id("org.nosphere.apache.rat") version "0.3.1"
 }
 
 apply from: '../shared.gradle'
diff --git a/api/settings.gradle b/api/settings.gradle
index 5cd7dd3..5798b26 100644
--- a/api/settings.gradle
+++ b/api/settings.gradle
@@ -1 +1,18 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 rootProject.name = 'api'
diff --git a/build.gradle b/build.gradle
index b82a3b2..18918cd 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 group 'org.apache.fineract.cn'
 
 task publishApiToMavenLocal {
@@ -34,3 +51,10 @@ task licenseFormat {
     dependsOn gradle.includedBuild('service').task(':licenseFormat')
     dependsOn gradle.includedBuild('component-test').task(':licenseFormat')
 }
+
+task rat {
+    group 'all'
+    dependsOn gradle.includedBuild('api').task(':rat')
+    dependsOn gradle.includedBuild('service').task(':rat')
+    dependsOn gradle.includedBuild('component-test').task(':rat')
+}
\ No newline at end of file
diff --git a/component-test/build.gradle b/component-test/build.gradle
index 5ca391b..a3a8ccb 100644
--- a/component-test/build.gradle
+++ b/component-test/build.gradle
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 buildscript {
     ext {
         springBootVersion = '1.4.1.RELEASE'
@@ -14,6 +31,7 @@ buildscript {
 
 plugins {
     id "com.github.hierynomus.license" version "0.13.1"
+    id("org.nosphere.apache.rat") version "0.3.1"
 }
 
 apply from: '../shared.gradle'
diff --git a/component-test/settings.gradle b/component-test/settings.gradle
index b2e36e3..dc9351a 100644
--- a/component-test/settings.gradle
+++ b/component-test/settings.gradle
@@ -1 +1,18 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 rootProject.name = 'component-test'
diff --git a/service/build.gradle b/service/build.gradle
index 2d36413..11b1a51 100644
--- a/service/build.gradle
+++ b/service/build.gradle
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 buildscript {
     ext {
         springBootVersion = '1.4.1.RELEASE'
@@ -14,6 +31,7 @@ buildscript {
 
 plugins {
     id "com.github.hierynomus.license" version "0.13.1"
+    id("org.nosphere.apache.rat") version "0.3.1"
 }
 
 apply from: '../shared.gradle'
diff --git a/service/settings.gradle b/service/settings.gradle
index 1ed471d..7c968c8 100644
--- a/service/settings.gradle
+++ b/service/settings.gradle
@@ -1 +1,18 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 rootProject.name = 'service'
diff --git a/settings.gradle b/settings.gradle
index c82a6db..386113a 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 rootProject.name = 'group'
 
 includeBuild 'api'
diff --git a/shared.gradle b/shared.gradle
index 06e2e4b..91ec124 100644
--- a/shared.gradle
+++ b/shared.gradle
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 group 'org.apache.fineract.cn.group'
 version '0.1.0-BUILD-SNAPSHOT'
 
@@ -66,3 +83,16 @@ license {
         uxf = 'XML_STYLE'
     }
 }
+
+rat {
+    // List of exclude directives, defaults to ['**/.gradle/**']
+    excludes = [
+            "**/.idea/**",
+            "**/.gradle/**",
+            "**/gradle/**",
+            "**/build/**",
+            "gradlew",
+            "gradlew.bat",
+            "README.md"
+    ]
+}


[fineract-cn-group] 16/40: Removing last references to mifos.

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit c9c06e0dbb635b42bf46cf5df40c975ee255547d
Author: Myrle Krantz <my...@apache.org>
AuthorDate: Mon Apr 16 13:13:43 2018 +0200

    Removing last references to mifos.
---
 README.md | 2 --
 1 file changed, 2 deletions(-)

diff --git a/README.md b/README.md
index ac2600e..09c53cb 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,5 @@
 # Apache Fineract CN Group Management
 
-[![Join the chat at https://gitter.im/mifos-initiative/mifos.io](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mifos-initiative/mifos.io?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
 This project provides Group management capabilities.
 
 ## Versioning


[fineract-cn-group] 35/40: Merge pull request #7 from kengneruphine/develop

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit acdd06484bf0b9ea2cf5003d96fe03521dc438d7
Merge: c9f6fb4 4b1b30b
Author: Awasum Yannick <ya...@gmail.com>
AuthorDate: Thu Sep 6 16:43:50 2018 +0100

    Merge pull request #7 from kengneruphine/develop
    
    Changes added to the Group Microservice [GSoC period]

 .gitignore                                         |  2 +
 .../fineract/cn/group/api/v1/EventConstants.java   |  2 +
 .../cn/group/api/v1/PermittableGroupIds.java       | 13 ++--
 .../cn/group/api/v1/client/GroupManager.java       | 35 +++++++--
 .../cn/group/api/v1/domain/GroupCommand.java       |  2 +-
 .../org/apache/fineract/cn/group/TestGroup.java    | 23 ++++++
 .../fineract/cn/group/TestGroupDefinition.java     | 31 +++++++-
 .../listener/GroupDefinitionEventListener.java     | 11 +++
 .../UpdateGroupCommand.java}                       | 21 +++--
 .../UpdateGroupDefinitionCommand.java}             | 20 +++--
 .../internal/command/handler/GroupAggregate.java   | 91 +++++++++++++++++++++-
 .../repository/GroupDefinitionRepository.java      |  5 +-
 .../internal/service/GroupDefinitionService.java   |  4 +
 .../group/rest/GroupDefinitionRestController.java  | 52 ++++++++++---
 .../cn/group/rest/GroupRestController.java         | 45 +++++++++--
 service/src/main/resources/bootstrap.yml           |  2 +-
 16 files changed, 309 insertions(+), 50 deletions(-)


[fineract-cn-group] 25/40: Implementing PUT request on Group definition

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit f2297c2ed23a99c2a8740967bbeba0f0881c6762
Author: kengneruphine <ru...@gmail.com>
AuthorDate: Sun Jun 24 15:59:05 2018 +0100

    Implementing PUT request on Group definition
---
 .../cn/group/api/v1/client/GroupManager.java       | 12 +++++++
 .../command/UpdateGroupDefinitionCommand.java      | 41 ++++++++++++++++++++++
 .../group/rest/GroupDefinitionRestController.java  | 19 ++++++++++
 3 files changed, 72 insertions(+)

diff --git a/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupManager.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupManager.java
index e146987..dac2955 100644
--- a/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupManager.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupManager.java
@@ -76,6 +76,18 @@ public interface GroupManager {
   List<GroupDefinition> fetchGroupDefinitions();
 
   @RequestMapping(
+          value = "/definitions/{identifier}",
+          method = RequestMethod.PUT,
+          produces = MediaType.APPLICATION_JSON_VALUE,
+          consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ThrowsExceptions({
+          @ThrowsException(status = HttpStatus.NOT_FOUND, exception = GroupDefinitionNotFound.class),
+          @ThrowsException(status = HttpStatus.BAD_REQUEST, exception = GroupDefinitionValidation.class)
+  })
+  void updateGroupDefinition(@PathVariable("identifier") final String identifier, @RequestBody final GroupDefinition groupDefinition);
+
+  @RequestMapping(
       value = "/groups",
       method = RequestMethod.POST,
       produces = MediaType.APPLICATION_JSON_VALUE,
diff --git a/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateGroupDefinitionCommand.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateGroupDefinitionCommand.java
new file mode 100644
index 0000000..cb9c481
--- /dev/null
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateGroupDefinitionCommand.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.fineract.cn.group.internal.command;
+
+import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
+
+public class UpdateGroupDefinitionCommand {
+
+    private final String identifier;
+    private final GroupDefinition groupDefinition;
+
+    public UpdateGroupDefinitionCommand(final String identifier, final GroupDefinition groupDefinition) {
+        super();
+        this.identifier = identifier;
+        this.groupDefinition = groupDefinition;
+    }
+
+    public String identifier() {
+        return this.identifier;
+    }
+
+    public GroupDefinition groupDefinition() {
+        return this.groupDefinition;
+    }
+}
diff --git a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
index 8874e76..6bd9ecb 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
@@ -22,6 +22,7 @@ import org.apache.fineract.cn.group.api.v1.PermittableGroupIds;
 import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
 import org.apache.fineract.cn.group.ServiceConstants;
 import org.apache.fineract.cn.group.internal.command.CreateGroupDefinitionCommand;
+import org.apache.fineract.cn.group.internal.command.UpdateGroupDefinitionCommand;
 import org.apache.fineract.cn.group.internal.service.GroupDefinitionService;
 import java.util.List;
 import javax.validation.Valid;
@@ -110,4 +111,22 @@ public class GroupDefinitionRestController {
         .map(ResponseEntity::ok)
         .orElseThrow(() -> ServiceException.notFound("Group definition {0} not found.", identifier));
   }
+
+  @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEFINITION)
+  @RequestMapping(
+          value = "/definitions/{identifier}",
+          method = RequestMethod.PUT,
+          produces = MediaType.APPLICATION_JSON_VALUE,
+          consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  public
+  @ResponseBody
+  ResponseEntity<Void> updateGroupDefinition(@PathVariable("identifier") final String identifier, @RequestBody final GroupDefinition groupDefinition) {
+    if (this.groupDefinitionService.groupDefinitionExists(identifier)) {
+      this.commandGateway.process(new UpdateGroupDefinitionCommand(identifier, groupDefinition));
+    } else {
+      throw ServiceException.notFound("Group Definition {0} not found.", identifier);
+    }
+    return ResponseEntity.accepted().build();
+  }
 }


[fineract-cn-group] 11/40: Merge pull request #2 from Izakey/develop

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit b376a148c178a457d8a3cdc6b3a59a7838aa7249
Merge: 2f2dc58 cc472fc
Author: Myrle Krantz <my...@apache.org>
AuthorDate: Fri Mar 16 11:50:25 2018 +0100

    Merge pull request #2 from Izakey/develop
    
    Updated copyright information on group

 HEADER                                             | 25 ++++++++++++----------
 NOTICE.txt                                         |  5 +++++
 README.md                                          |  2 +-
 .../java/io/mifos/group/api/v1/EventConstants.java | 25 ++++++++++++----------
 .../group/api/v1/client/GroupAlreadyExists.java    | 25 ++++++++++++----------
 .../v1/client/GroupDefinitionAlreadyExists.java    | 25 ++++++++++++----------
 .../api/v1/client/GroupDefinitionNotFound.java     | 25 ++++++++++++----------
 .../api/v1/client/GroupDefinitionValidation.java   | 25 ++++++++++++----------
 .../io/mifos/group/api/v1/client/GroupManager.java | 25 ++++++++++++----------
 .../api/v1/client/GroupNotFoundException.java      | 25 ++++++++++++----------
 .../api/v1/client/GroupValidationException.java    | 25 ++++++++++++----------
 .../java/io/mifos/group/api/v1/domain/Address.java | 25 ++++++++++++----------
 .../api/v1/domain/AssignedEmployeeHolder.java      | 25 ++++++++++++----------
 .../io/mifos/group/api/v1/domain/Attendee.java     | 25 ++++++++++++----------
 .../java/io/mifos/group/api/v1/domain/Cycle.java   | 25 ++++++++++++----------
 .../java/io/mifos/group/api/v1/domain/Group.java   | 25 ++++++++++++----------
 .../io/mifos/group/api/v1/domain/GroupCommand.java | 25 ++++++++++++----------
 .../mifos/group/api/v1/domain/GroupDefinition.java | 25 ++++++++++++----------
 .../io/mifos/group/api/v1/domain/GroupPage.java    | 25 ++++++++++++----------
 .../java/io/mifos/group/api/v1/domain/Meeting.java | 25 ++++++++++++----------
 .../mifos/group/api/v1/domain/SignOffMeeting.java  | 25 ++++++++++++----------
 .../src/main/java/io/mifos/group/TestGroup.java    | 25 ++++++++++++----------
 .../java/io/mifos/group/TestGroupDefinition.java   | 25 ++++++++++++----------
 .../listener/GroupDefinitionEventListener.java     | 25 ++++++++++++----------
 .../mifos/group/listener/GroupEventListener.java   | 25 ++++++++++++----------
 .../group/listener/MigrationEventListener.java     | 25 ++++++++++++----------
 .../mifos/group/util/GroupDefinitionGenerator.java | 25 ++++++++++++----------
 .../java/io/mifos/group/util/GroupGenerator.java   | 25 ++++++++++++----------
 component-test/src/main/resources/logback.xml      | 25 ++++++++++++----------
 .../io/mifos/group/service/GroupApplication.java   | 25 ++++++++++++----------
 .../io/mifos/group/service/GroupConfiguration.java | 25 ++++++++++++----------
 .../io/mifos/group/service/ServiceConstants.java   | 25 ++++++++++++----------
 .../internal/command/ActivateGroupCommand.java     | 25 ++++++++++++----------
 .../internal/command/CloseGroupCommand.java        | 25 ++++++++++++----------
 .../internal/command/CreateGroupCommand.java       | 25 ++++++++++++----------
 .../command/CreateGroupDefinitionCommand.java      | 25 ++++++++++++----------
 .../internal/command/InitializeServiceCommand.java | 25 ++++++++++++----------
 .../internal/command/ReopenGroupCommand.java       | 25 ++++++++++++----------
 .../internal/command/SignOffMeetingCommand.java    | 25 ++++++++++++----------
 .../command/UpdateAssignedEmployeeCommand.java     | 25 ++++++++++++----------
 .../internal/command/UpdateLeadersCommand.java     | 25 ++++++++++++----------
 .../internal/command/UpdateMembersCommand.java     | 25 ++++++++++++----------
 .../internal/command/handler/GroupAggregate.java   | 25 ++++++++++++----------
 .../command/handler/MigrationAggregate.java        | 25 ++++++++++++----------
 .../service/internal/mapper/AddressMapper.java     | 25 ++++++++++++----------
 .../service/internal/mapper/AttendeeMapper.java    | 25 ++++++++++++----------
 .../internal/mapper/GroupCommandMapper.java        | 25 ++++++++++++----------
 .../internal/mapper/GroupDefinitionMapper.java     | 25 ++++++++++++----------
 .../group/service/internal/mapper/GroupMapper.java | 25 ++++++++++++----------
 .../service/internal/mapper/MeetingMapper.java     | 25 ++++++++++++----------
 .../service/internal/repository/AddressEntity.java | 25 ++++++++++++----------
 .../internal/repository/AddressRepository.java     | 25 ++++++++++++----------
 .../internal/repository/AttendeeEntity.java        | 25 ++++++++++++----------
 .../internal/repository/AttendeeRepository.java    | 25 ++++++++++++----------
 .../internal/repository/GroupCommandEntity.java    | 25 ++++++++++++----------
 .../repository/GroupCommandRepository.java         | 25 ++++++++++++----------
 .../internal/repository/GroupDefinitionEntity.java | 25 ++++++++++++----------
 .../repository/GroupDefinitionRepository.java      | 25 ++++++++++++----------
 .../service/internal/repository/GroupEntity.java   | 25 ++++++++++++----------
 .../internal/repository/GroupRepository.java       | 25 ++++++++++++----------
 .../service/internal/repository/MeetingEntity.java | 25 ++++++++++++----------
 .../internal/repository/MeetingRepository.java     | 25 ++++++++++++----------
 .../internal/service/GroupDefinitionService.java   | 25 ++++++++++++----------
 .../service/internal/service/GroupService.java     | 25 ++++++++++++----------
 .../rest/GroupDefinitionRestController.java        | 25 ++++++++++++----------
 .../group/service/rest/GroupRestController.java    | 25 ++++++++++++----------
 .../service/rest/MigrationRestController.java      | 25 ++++++++++++----------
 service/src/main/resources/application.yml         | 19 ++++++++++++++++
 service/src/main/resources/bootstrap.yml           | 25 ++++++++++++----------
 .../db/migrations/mariadb/V1__initial_setup.sql    | 25 ++++++++++++----------
 shared.gradle                                      |  2 --
 71 files changed, 963 insertions(+), 740 deletions(-)


[fineract-cn-group] 08/40: Merge pull request #1 from myrle-krantz/develop

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 2f2dc588f8416796d2b9f5c26fba103abedb83a5
Merge: c759a24 b09e22e
Author: Myrle Krantz <my...@apache.org>
AuthorDate: Mon Feb 26 18:31:20 2018 +0100

    Merge pull request #1 from myrle-krantz/develop
    
     updating artifact ids to apache fineract from mifos io

 api/build.gradle            |  2 +-
 build.gradle                |  2 +-
 component-test/build.gradle | 10 +++++-----
 gradlew                     |  0
 service/build.gradle        | 14 +++++++-------
 shared.gradle               |  2 +-
 6 files changed, 15 insertions(+), 15 deletions(-)


[fineract-cn-group] 23/40: adding permittableGroupIds and modifiying the bootstrap.yml file

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 3ce19f90332adf1a18f1bd16cd096cea8f00f59b
Author: kengneruphine <ru...@gmail.com>
AuthorDate: Mon Jun 18 16:24:33 2018 +0100

    adding permittableGroupIds and modifiying the bootstrap.yml file
---
 .../cn/group/api/v1/PermittableGroupIds.java       | 27 ++++++++++++++++++++++
 .../group/rest/GroupDefinitionRestController.java  |  7 +++---
 .../cn/group/rest/GroupRestController.java         | 14 ++++++++---
 service/src/main/resources/bootstrap.yml           |  2 +-
 4 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/api/src/main/java/org/apache/fineract/cn/group/api/v1/PermittableGroupIds.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/PermittableGroupIds.java
new file mode 100644
index 0000000..48738c8
--- /dev/null
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/PermittableGroupIds.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.fineract.cn.group.api.v1;
+
+public interface PermittableGroupIds {
+
+    String GROUP = "group__v1__group";
+    String DEFINITION = "group__v1__definition";
+}
\ No newline at end of file
diff --git a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
index a526450..1250560 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.cn.group.rest;
 
+import org.apache.fineract.cn.group.api.v1.PermittableGroupIds;
 import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
 import org.apache.fineract.cn.group.ServiceConstants;
 import org.apache.fineract.cn.group.internal.command.CreateGroupDefinitionCommand;
@@ -58,7 +59,7 @@ public class GroupDefinitionRestController {
     this.groupDefinitionService = groupDefinitionService;
   }
 
-  @Permittable(AcceptedTokenType.TENANT)
+  @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEFINITION)
   @RequestMapping(
       method = RequestMethod.POST,
       consumes = MediaType.APPLICATION_JSON_VALUE,
@@ -76,7 +77,7 @@ public class GroupDefinitionRestController {
     return ResponseEntity.accepted().build();
   }
 
-  @Permittable(AcceptedTokenType.TENANT)
+  @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEFINITION)
   @RequestMapping(
       method = RequestMethod.GET,
       consumes = MediaType.ALL_VALUE,
@@ -88,7 +89,7 @@ public class GroupDefinitionRestController {
     return ResponseEntity.ok(this.groupDefinitionService.fetchAllGroupDefinitions());
   }
 
-  @Permittable(AcceptedTokenType.TENANT)
+  @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEFINITION)
   @RequestMapping(
       value = "/{identifier}",
       method = RequestMethod.GET,
diff --git a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupRestController.java b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupRestController.java
index c9edae9..ee0e55e 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupRestController.java
@@ -25,6 +25,7 @@ import org.apache.fineract.cn.group.api.v1.domain.GroupPage;
 import org.apache.fineract.cn.group.api.v1.domain.Meeting;
 import org.apache.fineract.cn.group.api.v1.domain.SignOffMeeting;
 import org.apache.fineract.cn.group.ServiceConstants;
+import org.apache.fineract.cn.group.api.v1.PermittableGroupIds;
 import org.apache.fineract.cn.group.internal.command.ActivateGroupCommand;
 import org.apache.fineract.cn.group.internal.command.CloseGroupCommand;
 import org.apache.fineract.cn.group.internal.command.CreateGroupCommand;
@@ -80,7 +81,7 @@ public class GroupRestController {
     this.groupDefinitionService = groupDefinitionService;
   }
 
-  @Permittable(AcceptedTokenType.TENANT)
+  @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.GROUP)
   @RequestMapping(
       method = RequestMethod.POST,
       consumes = MediaType.APPLICATION_JSON_VALUE,
@@ -102,7 +103,7 @@ public class GroupRestController {
     return ResponseEntity.accepted().build();
   }
 
-  @Permittable(AcceptedTokenType.TENANT)
+  @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.GROUP)
   @RequestMapping(
       method = RequestMethod.GET,
       consumes = MediaType.ALL_VALUE,
@@ -121,7 +122,7 @@ public class GroupRestController {
     );
   }
 
-  @Permittable(AcceptedTokenType.TENANT)
+  @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.GROUP)
   @RequestMapping(
       value = "/{identifier}",
       method = RequestMethod.GET,
@@ -136,6 +137,7 @@ public class GroupRestController {
         .orElseThrow(() -> ServiceException.notFound("Group {0} not found.", identifier));
   }
 
+  @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.GROUP)
   @RequestMapping(
       value = "/{identifier}/commands",
       method = RequestMethod.POST,
@@ -163,6 +165,7 @@ public class GroupRestController {
     return ResponseEntity.accepted().build();
   }
 
+  @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.GROUP)
   @RequestMapping(
       value = "/{identifier}/commands",
       method = RequestMethod.GET,
@@ -175,6 +178,7 @@ public class GroupRestController {
     return ResponseEntity.ok(this.groupService.findCommandsByIdentifier(identifier));
   }
 
+  @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.GROUP)
   @RequestMapping(
       value = "/{identifier}/leaders",
       method = RequestMethod.PUT,
@@ -193,6 +197,7 @@ public class GroupRestController {
     return ResponseEntity.accepted().build();
   }
 
+  @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.GROUP)
   @RequestMapping(
       value = "/{identifier}/members",
       method = RequestMethod.PUT,
@@ -211,6 +216,7 @@ public class GroupRestController {
     return ResponseEntity.accepted().build();
   }
 
+  @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.GROUP)
   @RequestMapping(
       value = "/{identifier}/employee",
       method = RequestMethod.PUT,
@@ -230,6 +236,7 @@ public class GroupRestController {
     return ResponseEntity.accepted().build();
   }
 
+  @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.GROUP)
   @RequestMapping(
       value = "/{identifier}/meetings",
       method = RequestMethod.GET,
@@ -245,6 +252,7 @@ public class GroupRestController {
     return ResponseEntity.ok(this.groupService.findMeetings(groupIdentifier, upcoming));
   }
 
+  @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.GROUP)
   @RequestMapping(
       value = "/{identifier}/meetings",
       method = RequestMethod.PUT,
diff --git a/service/src/main/resources/bootstrap.yml b/service/src/main/resources/bootstrap.yml
index 93851b3..79e4528 100644
--- a/service/src/main/resources/bootstrap.yml
+++ b/service/src/main/resources/bootstrap.yml
@@ -19,4 +19,4 @@
 
 spring:
     application:
-        name: group-api
+        name: group-v1


[fineract-cn-group] 32/40: modified endpoint for updateGroupDefinition

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit c96cd337b8de383effceb2e134c08a1742ba11fc
Author: kengneruphine <ru...@gmail.com>
AuthorDate: Wed Aug 8 16:20:01 2018 +0100

    modified endpoint for updateGroupDefinition
---
 .../apache/fineract/cn/group/rest/GroupDefinitionRestController.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
index d878938..5e6b92b 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
@@ -114,7 +114,7 @@ public class GroupDefinitionRestController {
 
   @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEFINITION)
   @RequestMapping(
-          value = "/definitions/{identifier}",
+          value = "/{identifier}",
           method = RequestMethod.PUT,
           produces = MediaType.APPLICATION_JSON_VALUE,
           consumes = MediaType.APPLICATION_JSON_VALUE


[fineract-cn-group] 07/40: fixing executability of gradlew under linux

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit b09e22e4dd9b9c848ebc79ccc2aadcf4e2dc0e9e
Author: Myrle Krantz <my...@apache.org>
AuthorDate: Mon Feb 26 17:57:26 2018 +0100

    fixing executability of gradlew under linux
---
 gradlew | 0
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/gradlew b/gradlew
old mode 100644
new mode 100755


[fineract-cn-group] 22/40: Merge pull request #6 from apache/revert-5-develop

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit c9f6fb4d54670e4eddd2039af76ff9fe552f50f0
Merge: 30c2f64 4cb416f
Author: Isaac Kamga <u2...@gmail.com>
AuthorDate: Sat Jun 9 15:32:05 2018 +0100

    Merge pull request #6 from apache/revert-5-develop
    
    Revert "Document the Group API"

 service/build.gradle                               |  20 +-
 service/src/doc/asciidoc/api-docs.adoc             |  89 ---
 .../curl-request.adoc                              |   4 -
 .../http-request.adoc                              |  10 -
 .../http-response.adoc                             |   5 -
 .../httpie-request.adoc                            |   4 -
 .../should-activate-command/curl-request.adoc      |   4 -
 .../should-activate-command/http-request.adoc      |  10 -
 .../should-activate-command/http-response.adoc     |   5 -
 .../should-activate-command/httpie-request.adoc    |   4 -
 .../should-create-group/curl-request.adoc          |   4 -
 .../should-create-group/http-request.adoc          |  10 -
 .../should-create-group/http-response.adoc         |   5 -
 .../should-create-group/httpie-request.adoc        |   4 -
 .../curl-request.adoc                              |   4 -
 .../http-request.adoc                              |  10 -
 .../http-response.adoc                             |   5 -
 .../httpie-request.adoc                            |   4 -
 .../should-update-leaders/curl-request.adoc        |   4 -
 .../should-update-leaders/http-request.adoc        |  10 -
 .../should-update-leaders/http-response.adoc       |   5 -
 .../should-update-leaders/httpie-request.adoc      |   4 -
 .../should-update-members/curl-request.adoc        |   4 -
 .../should-update-members/http-request.adoc        |  10 -
 .../should-update-members/http-response.adoc       |   5 -
 .../should-update-members/httpie-request.adoc      |   4 -
 service/src/doc/html5/html5/api-docs.html          | 648 ---------------------
 .../org/apache/fineract/cn/group/TestGroup.java    | 335 -----------
 .../fineract/cn/group/TestGroupDefinition.java     | 181 ------
 .../listener/GroupDefinitionEventListener.java     |  50 --
 .../cn/group/listener/GroupEventListener.java      |  70 ---
 .../cn/group/listener/MigrationEventListener.java  |  50 --
 .../cn/group/util/GroupDefinitionGenerator.java    |  44 --
 .../fineract/cn/group/util/GroupGenerator.java     |  62 --
 34 files changed, 1 insertion(+), 1686 deletions(-)


[fineract-cn-group] 09/40: Updated copyright information on group

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit b89ea5a301d262cfcfadab0f6d8180330153614e
Author: Isaac Kamga <u2...@gmail.com>
AuthorDate: Fri Mar 2 22:11:34 2018 +0100

    Updated copyright information on group
---
 HEADER                                             | 25 ++++++++++++----------
 NOTICE.txt                                         |  5 +++++
 README.md                                          |  2 +-
 .../java/io/mifos/group/api/v1/EventConstants.java | 25 ++++++++++++----------
 .../group/api/v1/client/GroupAlreadyExists.java    | 25 ++++++++++++----------
 .../v1/client/GroupDefinitionAlreadyExists.java    | 25 ++++++++++++----------
 .../api/v1/client/GroupDefinitionNotFound.java     | 25 ++++++++++++----------
 .../api/v1/client/GroupDefinitionValidation.java   | 25 ++++++++++++----------
 .../io/mifos/group/api/v1/client/GroupManager.java | 25 ++++++++++++----------
 .../api/v1/client/GroupNotFoundException.java      | 25 ++++++++++++----------
 .../api/v1/client/GroupValidationException.java    | 25 ++++++++++++----------
 .../java/io/mifos/group/api/v1/domain/Address.java | 25 ++++++++++++----------
 .../api/v1/domain/AssignedEmployeeHolder.java      | 25 ++++++++++++----------
 .../io/mifos/group/api/v1/domain/Attendee.java     | 25 ++++++++++++----------
 .../java/io/mifos/group/api/v1/domain/Cycle.java   | 25 ++++++++++++----------
 .../java/io/mifos/group/api/v1/domain/Group.java   | 25 ++++++++++++----------
 .../io/mifos/group/api/v1/domain/GroupCommand.java | 25 ++++++++++++----------
 .../mifos/group/api/v1/domain/GroupDefinition.java | 25 ++++++++++++----------
 .../io/mifos/group/api/v1/domain/GroupPage.java    | 25 ++++++++++++----------
 .../java/io/mifos/group/api/v1/domain/Meeting.java | 25 ++++++++++++----------
 .../mifos/group/api/v1/domain/SignOffMeeting.java  | 25 ++++++++++++----------
 .../src/main/java/io/mifos/group/TestGroup.java    | 25 ++++++++++++----------
 .../java/io/mifos/group/TestGroupDefinition.java   | 25 ++++++++++++----------
 .../listener/GroupDefinitionEventListener.java     | 25 ++++++++++++----------
 .../mifos/group/listener/GroupEventListener.java   | 25 ++++++++++++----------
 .../group/listener/MigrationEventListener.java     | 25 ++++++++++++----------
 .../mifos/group/util/GroupDefinitionGenerator.java | 25 ++++++++++++----------
 .../java/io/mifos/group/util/GroupGenerator.java   | 25 ++++++++++++----------
 component-test/src/main/resources/logback.xml      | 25 ++++++++++++----------
 .../io/mifos/group/service/GroupApplication.java   | 25 ++++++++++++----------
 .../io/mifos/group/service/GroupConfiguration.java | 25 ++++++++++++----------
 .../io/mifos/group/service/ServiceConstants.java   | 25 ++++++++++++----------
 .../internal/command/ActivateGroupCommand.java     | 25 ++++++++++++----------
 .../internal/command/CloseGroupCommand.java        | 25 ++++++++++++----------
 .../internal/command/CreateGroupCommand.java       | 25 ++++++++++++----------
 .../command/CreateGroupDefinitionCommand.java      | 25 ++++++++++++----------
 .../internal/command/InitializeServiceCommand.java | 25 ++++++++++++----------
 .../internal/command/ReopenGroupCommand.java       | 25 ++++++++++++----------
 .../internal/command/SignOffMeetingCommand.java    | 25 ++++++++++++----------
 .../command/UpdateAssignedEmployeeCommand.java     | 25 ++++++++++++----------
 .../internal/command/UpdateLeadersCommand.java     | 25 ++++++++++++----------
 .../internal/command/UpdateMembersCommand.java     | 25 ++++++++++++----------
 .../internal/command/handler/GroupAggregate.java   | 25 ++++++++++++----------
 .../command/handler/MigrationAggregate.java        | 25 ++++++++++++----------
 .../service/internal/mapper/AddressMapper.java     | 25 ++++++++++++----------
 .../service/internal/mapper/AttendeeMapper.java    | 25 ++++++++++++----------
 .../internal/mapper/GroupCommandMapper.java        | 25 ++++++++++++----------
 .../internal/mapper/GroupDefinitionMapper.java     | 25 ++++++++++++----------
 .../group/service/internal/mapper/GroupMapper.java | 25 ++++++++++++----------
 .../service/internal/mapper/MeetingMapper.java     | 25 ++++++++++++----------
 .../service/internal/repository/AddressEntity.java | 25 ++++++++++++----------
 .../internal/repository/AddressRepository.java     | 25 ++++++++++++----------
 .../internal/repository/AttendeeEntity.java        | 25 ++++++++++++----------
 .../internal/repository/AttendeeRepository.java    | 25 ++++++++++++----------
 .../internal/repository/GroupCommandEntity.java    | 25 ++++++++++++----------
 .../repository/GroupCommandRepository.java         | 25 ++++++++++++----------
 .../internal/repository/GroupDefinitionEntity.java | 25 ++++++++++++----------
 .../repository/GroupDefinitionRepository.java      | 25 ++++++++++++----------
 .../service/internal/repository/GroupEntity.java   | 25 ++++++++++++----------
 .../internal/repository/GroupRepository.java       | 25 ++++++++++++----------
 .../service/internal/repository/MeetingEntity.java | 25 ++++++++++++----------
 .../internal/repository/MeetingRepository.java     | 25 ++++++++++++----------
 .../internal/service/GroupDefinitionService.java   | 25 ++++++++++++----------
 .../service/internal/service/GroupService.java     | 25 ++++++++++++----------
 .../rest/GroupDefinitionRestController.java        | 25 ++++++++++++----------
 .../group/service/rest/GroupRestController.java    | 25 ++++++++++++----------
 .../service/rest/MigrationRestController.java      | 25 ++++++++++++----------
 service/src/main/resources/application.yml         | 19 ++++++++++++++++
 service/src/main/resources/bootstrap.yml           | 25 ++++++++++++----------
 .../db/migrations/mariadb/V1__initial_setup.sql    | 25 ++++++++++++----------
 shared.gradle                                      |  2 +-
 71 files changed, 964 insertions(+), 739 deletions(-)

diff --git a/HEADER b/HEADER
index 4b2eadf..90705e0 100644
--- a/HEADER
+++ b/HEADER
@@ -1,13 +1,16 @@
-Copyright ${year} ${name}.
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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
 
-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
 
-   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.
\ No newline at end of file
+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.
\ No newline at end of file
diff --git a/NOTICE.txt b/NOTICE.txt
new file mode 100644
index 0000000..5f2a7ce
--- /dev/null
+++ b/NOTICE.txt
@@ -0,0 +1,5 @@
+Apache Fineract CN Group
+Copyright [2017-2018] The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/README.md b/README.md
index bec5de8..ac2600e 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Mifos I/O Group Management
+# Apache Fineract CN Group Management
 
 [![Join the chat at https://gitter.im/mifos-initiative/mifos.io](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mifos-initiative/mifos.io?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/EventConstants.java b/api/src/main/java/io/mifos/group/api/v1/EventConstants.java
index f18fe33..7a33567 100644
--- a/api/src/main/java/io/mifos/group/api/v1/EventConstants.java
+++ b/api/src/main/java/io/mifos/group/api/v1/EventConstants.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupAlreadyExists.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupAlreadyExists.java
index 35fd6e2..fdf09d2 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupAlreadyExists.java
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupAlreadyExists.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.client;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionAlreadyExists.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionAlreadyExists.java
index 261411a..e0f31f9 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionAlreadyExists.java
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionAlreadyExists.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.client;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionNotFound.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionNotFound.java
index 99e2676..7b1c260 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionNotFound.java
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionNotFound.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.client;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionValidation.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionValidation.java
index 75be3a1..aa83065 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionValidation.java
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionValidation.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.client;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupManager.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupManager.java
index 63f2075..9b5877e 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupManager.java
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupManager.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.client;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupNotFoundException.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupNotFoundException.java
index 629c5e6..ee0999a 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupNotFoundException.java
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupNotFoundException.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.client;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupValidationException.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupValidationException.java
index 2a3bd0b..caa61f0 100644
--- a/api/src/main/java/io/mifos/group/api/v1/client/GroupValidationException.java
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupValidationException.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.client;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/Address.java b/api/src/main/java/io/mifos/group/api/v1/domain/Address.java
index 902b255..16c76f0 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/Address.java
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/Address.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.domain;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/AssignedEmployeeHolder.java b/api/src/main/java/io/mifos/group/api/v1/domain/AssignedEmployeeHolder.java
index e2ce5d8..6871e5a 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/AssignedEmployeeHolder.java
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/AssignedEmployeeHolder.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.domain;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/Attendee.java b/api/src/main/java/io/mifos/group/api/v1/domain/Attendee.java
index 147be78..e48a45f 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/Attendee.java
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/Attendee.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.domain;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/Cycle.java b/api/src/main/java/io/mifos/group/api/v1/domain/Cycle.java
index 261c651..05a1c78 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/Cycle.java
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/Cycle.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.domain;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/Group.java b/api/src/main/java/io/mifos/group/api/v1/domain/Group.java
index c38d955..d51751d 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/Group.java
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/Group.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.domain;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/GroupCommand.java b/api/src/main/java/io/mifos/group/api/v1/domain/GroupCommand.java
index 1941d47..9185d56 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/GroupCommand.java
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/GroupCommand.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.domain;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/GroupDefinition.java b/api/src/main/java/io/mifos/group/api/v1/domain/GroupDefinition.java
index 70f7726..2083679 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/GroupDefinition.java
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/GroupDefinition.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.domain;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/GroupPage.java b/api/src/main/java/io/mifos/group/api/v1/domain/GroupPage.java
index 7ddd739..04d3c32 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/GroupPage.java
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/GroupPage.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.domain;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/Meeting.java b/api/src/main/java/io/mifos/group/api/v1/domain/Meeting.java
index 7770ac3..78c14cf 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/Meeting.java
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/Meeting.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.domain;
 
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/SignOffMeeting.java b/api/src/main/java/io/mifos/group/api/v1/domain/SignOffMeeting.java
index a8e71f7..50c2b8f 100644
--- a/api/src/main/java/io/mifos/group/api/v1/domain/SignOffMeeting.java
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/SignOffMeeting.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.api.v1.domain;
 
diff --git a/component-test/src/main/java/io/mifos/group/TestGroup.java b/component-test/src/main/java/io/mifos/group/TestGroup.java
index caa15ed..4e3edf6 100644
--- a/component-test/src/main/java/io/mifos/group/TestGroup.java
+++ b/component-test/src/main/java/io/mifos/group/TestGroup.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group;
 
diff --git a/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java b/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java
index 18b7203..d59a11f 100644
--- a/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java
+++ b/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group;
 
diff --git a/component-test/src/main/java/io/mifos/group/listener/GroupDefinitionEventListener.java b/component-test/src/main/java/io/mifos/group/listener/GroupDefinitionEventListener.java
index a64b355..be21011 100644
--- a/component-test/src/main/java/io/mifos/group/listener/GroupDefinitionEventListener.java
+++ b/component-test/src/main/java/io/mifos/group/listener/GroupDefinitionEventListener.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.listener;
 
diff --git a/component-test/src/main/java/io/mifos/group/listener/GroupEventListener.java b/component-test/src/main/java/io/mifos/group/listener/GroupEventListener.java
index 32446b3..825947c 100644
--- a/component-test/src/main/java/io/mifos/group/listener/GroupEventListener.java
+++ b/component-test/src/main/java/io/mifos/group/listener/GroupEventListener.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.listener;
 
diff --git a/component-test/src/main/java/io/mifos/group/listener/MigrationEventListener.java b/component-test/src/main/java/io/mifos/group/listener/MigrationEventListener.java
index df7c8fb..7b90c38 100644
--- a/component-test/src/main/java/io/mifos/group/listener/MigrationEventListener.java
+++ b/component-test/src/main/java/io/mifos/group/listener/MigrationEventListener.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.listener;
 
diff --git a/component-test/src/main/java/io/mifos/group/util/GroupDefinitionGenerator.java b/component-test/src/main/java/io/mifos/group/util/GroupDefinitionGenerator.java
index 7024152..051bd2b 100644
--- a/component-test/src/main/java/io/mifos/group/util/GroupDefinitionGenerator.java
+++ b/component-test/src/main/java/io/mifos/group/util/GroupDefinitionGenerator.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.util;
 
diff --git a/component-test/src/main/java/io/mifos/group/util/GroupGenerator.java b/component-test/src/main/java/io/mifos/group/util/GroupGenerator.java
index d00bde4..31ff0e3 100644
--- a/component-test/src/main/java/io/mifos/group/util/GroupGenerator.java
+++ b/component-test/src/main/java/io/mifos/group/util/GroupGenerator.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2017 The Mifos Initiative
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.util;
 
diff --git a/component-test/src/main/resources/logback.xml b/component-test/src/main/resources/logback.xml
index e0b1e5e..0f6e5b6 100644
--- a/component-test/src/main/resources/logback.xml
+++ b/component-test/src/main/resources/logback.xml
@@ -1,18 +1,21 @@
 <!--
 
-    Copyright 2017 The Mifos Initiative
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you 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
 
-    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
 
-       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.
+    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.
 
 -->
 <configuration>
diff --git a/service/src/main/java/io/mifos/group/service/GroupApplication.java b/service/src/main/java/io/mifos/group/service/GroupApplication.java
index 1dac37d..10ead59 100644
--- a/service/src/main/java/io/mifos/group/service/GroupApplication.java
+++ b/service/src/main/java/io/mifos/group/service/GroupApplication.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service;
 
diff --git a/service/src/main/java/io/mifos/group/service/GroupConfiguration.java b/service/src/main/java/io/mifos/group/service/GroupConfiguration.java
index e7d2300..bb0d3c8 100644
--- a/service/src/main/java/io/mifos/group/service/GroupConfiguration.java
+++ b/service/src/main/java/io/mifos/group/service/GroupConfiguration.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service;
 
diff --git a/service/src/main/java/io/mifos/group/service/ServiceConstants.java b/service/src/main/java/io/mifos/group/service/ServiceConstants.java
index 07ae9a0..3f7f49d 100644
--- a/service/src/main/java/io/mifos/group/service/ServiceConstants.java
+++ b/service/src/main/java/io/mifos/group/service/ServiceConstants.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/ActivateGroupCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/ActivateGroupCommand.java
index 6e03951..a36da1a 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/ActivateGroupCommand.java
+++ b/service/src/main/java/io/mifos/group/service/internal/command/ActivateGroupCommand.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.command;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/CloseGroupCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/CloseGroupCommand.java
index e599458..496f296 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/CloseGroupCommand.java
+++ b/service/src/main/java/io/mifos/group/service/internal/command/CloseGroupCommand.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.command;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupCommand.java
index 88515db..1f17643 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupCommand.java
+++ b/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupCommand.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.command;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupDefinitionCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupDefinitionCommand.java
index 5c85f8d..47561a8 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupDefinitionCommand.java
+++ b/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupDefinitionCommand.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.command;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/InitializeServiceCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/InitializeServiceCommand.java
index a5e28da..e513bfd 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/InitializeServiceCommand.java
+++ b/service/src/main/java/io/mifos/group/service/internal/command/InitializeServiceCommand.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.command;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/ReopenGroupCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/ReopenGroupCommand.java
index 0e83570..38a60ca 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/ReopenGroupCommand.java
+++ b/service/src/main/java/io/mifos/group/service/internal/command/ReopenGroupCommand.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.command;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/SignOffMeetingCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/SignOffMeetingCommand.java
index 0144b32..91cae9c 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/SignOffMeetingCommand.java
+++ b/service/src/main/java/io/mifos/group/service/internal/command/SignOffMeetingCommand.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.command;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/UpdateAssignedEmployeeCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/UpdateAssignedEmployeeCommand.java
index e664ac1..41763ee 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/UpdateAssignedEmployeeCommand.java
+++ b/service/src/main/java/io/mifos/group/service/internal/command/UpdateAssignedEmployeeCommand.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.command;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/UpdateLeadersCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/UpdateLeadersCommand.java
index 7167aeb..add55ed 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/UpdateLeadersCommand.java
+++ b/service/src/main/java/io/mifos/group/service/internal/command/UpdateLeadersCommand.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.command;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/UpdateMembersCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/UpdateMembersCommand.java
index 935257a..5b09287 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/UpdateMembersCommand.java
+++ b/service/src/main/java/io/mifos/group/service/internal/command/UpdateMembersCommand.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.command;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/handler/GroupAggregate.java b/service/src/main/java/io/mifos/group/service/internal/command/handler/GroupAggregate.java
index 49074ce..4c3bbae 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/handler/GroupAggregate.java
+++ b/service/src/main/java/io/mifos/group/service/internal/command/handler/GroupAggregate.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.command.handler;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/handler/MigrationAggregate.java b/service/src/main/java/io/mifos/group/service/internal/command/handler/MigrationAggregate.java
index 3d93d3b..eed82d2 100644
--- a/service/src/main/java/io/mifos/group/service/internal/command/handler/MigrationAggregate.java
+++ b/service/src/main/java/io/mifos/group/service/internal/command/handler/MigrationAggregate.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.command.handler;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/AddressMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/AddressMapper.java
index 7ff897a..c9661e9 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/AddressMapper.java
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/AddressMapper.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.mapper;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/AttendeeMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/AttendeeMapper.java
index 58cc7bb..3ebac1a 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/AttendeeMapper.java
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/AttendeeMapper.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.mapper;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupCommandMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupCommandMapper.java
index c1bbca0..bbfbf3a 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupCommandMapper.java
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupCommandMapper.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.mapper;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupDefinitionMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupDefinitionMapper.java
index 88cf2c4..6de8f05 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupDefinitionMapper.java
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupDefinitionMapper.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.mapper;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupMapper.java
index a345c2a..764a377 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupMapper.java
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupMapper.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.mapper;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/MeetingMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/MeetingMapper.java
index 9e67548..6851cc3 100644
--- a/service/src/main/java/io/mifos/group/service/internal/mapper/MeetingMapper.java
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/MeetingMapper.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.mapper;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/AddressEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/AddressEntity.java
index f456da2..10fb8dd 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/AddressEntity.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/AddressEntity.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.repository;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/AddressRepository.java b/service/src/main/java/io/mifos/group/service/internal/repository/AddressRepository.java
index b3dfdfb..a6fbcff 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/AddressRepository.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/AddressRepository.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.repository;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeEntity.java
index f0b37db..d0d525a 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeEntity.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeEntity.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.repository;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeRepository.java b/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeRepository.java
index b718aa6..1f590e1 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeRepository.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeRepository.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.repository;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandEntity.java
index 332c02e..e7ae69a 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandEntity.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandEntity.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.repository;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandRepository.java b/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandRepository.java
index 9313514..bfc208f 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandRepository.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandRepository.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.repository;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionEntity.java
index 926e832..876973b 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionEntity.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionEntity.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.repository;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionRepository.java b/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionRepository.java
index e274b95..9d78198 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionRepository.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionRepository.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.repository;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/GroupEntity.java
index da5a423..6f8fbea 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/GroupEntity.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/GroupEntity.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.repository;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupRepository.java b/service/src/main/java/io/mifos/group/service/internal/repository/GroupRepository.java
index 7398865..d1e3d7e 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/GroupRepository.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/GroupRepository.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.repository;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/MeetingEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/MeetingEntity.java
index 2733c5a..a6e4b6b 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/MeetingEntity.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/MeetingEntity.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.repository;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/MeetingRepository.java b/service/src/main/java/io/mifos/group/service/internal/repository/MeetingRepository.java
index 6875ba7..16a2349 100644
--- a/service/src/main/java/io/mifos/group/service/internal/repository/MeetingRepository.java
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/MeetingRepository.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.repository;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/service/GroupDefinitionService.java b/service/src/main/java/io/mifos/group/service/internal/service/GroupDefinitionService.java
index 2bc03cb..c691ae8 100644
--- a/service/src/main/java/io/mifos/group/service/internal/service/GroupDefinitionService.java
+++ b/service/src/main/java/io/mifos/group/service/internal/service/GroupDefinitionService.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.service;
 
diff --git a/service/src/main/java/io/mifos/group/service/internal/service/GroupService.java b/service/src/main/java/io/mifos/group/service/internal/service/GroupService.java
index 76ce37e..8cfc35e 100644
--- a/service/src/main/java/io/mifos/group/service/internal/service/GroupService.java
+++ b/service/src/main/java/io/mifos/group/service/internal/service/GroupService.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.internal.service;
 
diff --git a/service/src/main/java/io/mifos/group/service/rest/GroupDefinitionRestController.java b/service/src/main/java/io/mifos/group/service/rest/GroupDefinitionRestController.java
index 7b78586..86588ba 100644
--- a/service/src/main/java/io/mifos/group/service/rest/GroupDefinitionRestController.java
+++ b/service/src/main/java/io/mifos/group/service/rest/GroupDefinitionRestController.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.rest;
 
diff --git a/service/src/main/java/io/mifos/group/service/rest/GroupRestController.java b/service/src/main/java/io/mifos/group/service/rest/GroupRestController.java
index 7aad78b..34a6780 100644
--- a/service/src/main/java/io/mifos/group/service/rest/GroupRestController.java
+++ b/service/src/main/java/io/mifos/group/service/rest/GroupRestController.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.rest;
 
diff --git a/service/src/main/java/io/mifos/group/service/rest/MigrationRestController.java b/service/src/main/java/io/mifos/group/service/rest/MigrationRestController.java
index e656b2a..efc4886 100644
--- a/service/src/main/java/io/mifos/group/service/rest/MigrationRestController.java
+++ b/service/src/main/java/io/mifos/group/service/rest/MigrationRestController.java
@@ -1,17 +1,20 @@
 /*
- * Copyright 2016 The Mifos Initiative.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *    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.
+ * 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 io.mifos.group.service.rest;
 
diff --git a/service/src/main/resources/application.yml b/service/src/main/resources/application.yml
index fbbfa68..f9b2ce0 100644
--- a/service/src/main/resources/application.yml
+++ b/service/src/main/resources/application.yml
@@ -1,3 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+
 
 #
 # Copyright 2016 The Mifos Initiative.
diff --git a/service/src/main/resources/bootstrap.yml b/service/src/main/resources/bootstrap.yml
index 93080e3..93851b3 100644
--- a/service/src/main/resources/bootstrap.yml
+++ b/service/src/main/resources/bootstrap.yml
@@ -1,17 +1,20 @@
 #
-# Copyright 2016 The Mifos Initiative.
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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
 #
-# 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
 #
-#    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.
+# 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.
 #
 
 spring:
diff --git a/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql b/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
index ab45c4b..4460330 100644
--- a/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
+++ b/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
@@ -1,17 +1,20 @@
 --
--- Copyright 2016 The Mifos Initiative.
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you 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
 --
--- 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
 --
---    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.
+-- 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.
 --
 
 CREATE TABLE ptah_addresses (
diff --git a/shared.gradle b/shared.gradle
index 32403fd..967c06f 100644
--- a/shared.gradle
+++ b/shared.gradle
@@ -66,5 +66,5 @@ license {
         uxf = 'XML_STYLE'
     }
     ext.year = Calendar.getInstance().get(Calendar.YEAR)
-    ext.name = 'The Mifos Initiative'
+    ext.name = 'The Apache Software Foundation'
 }


[fineract-cn-group] 01/40: Initial Commit

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit fe3968e6f7198ce8670b93a1fe9e8d528e7326ba
Author: Markus Geiss <mg...@mifos.org>
AuthorDate: Thu Mar 16 14:48:55 2017 +0100

    Initial Commit
---
 .gitignore                                         |  16 +
 HEADER                                             |  13 +
 LICENSE                                            | 201 +++++++++++++
 README.md                                          |  25 ++
 api/build.gradle                                   |  33 ++
 api/settings.gradle                                |   1 +
 .../java/io/mifos/group/api/v1/EventConstants.java |  45 +++
 .../group/api/v1/client/GroupAlreadyExists.java    |  19 ++
 .../io/mifos/group/api/v1/client/GroupClient.java  | 174 +++++++++++
 .../v1/client/GroupDefinitionAlreadyExists.java    |  19 ++
 .../api/v1/client/GroupDefinitionNotFound.java     |  19 ++
 .../api/v1/client/GroupDefinitionValidation.java   |  19 ++
 .../api/v1/client/GroupNotFoundException.java      |  19 ++
 .../api/v1/client/GroupValidationException.java    |  19 ++
 .../java/io/mifos/group/api/v1/domain/Address.java |  83 ++++++
 .../api/v1/domain/AssignedEmployeeHolder.java      |  33 ++
 .../io/mifos/group/api/v1/domain/Attendee.java     |  54 ++++
 .../java/io/mifos/group/api/v1/domain/Cycle.java   |  67 +++++
 .../java/io/mifos/group/api/v1/domain/Group.java   | 202 +++++++++++++
 .../io/mifos/group/api/v1/domain/GroupCommand.java |  66 ++++
 .../mifos/group/api/v1/domain/GroupDefinition.java | 116 +++++++
 .../io/mifos/group/api/v1/domain/GroupPage.java    |  53 ++++
 .../java/io/mifos/group/api/v1/domain/Meeting.java | 127 ++++++++
 .../mifos/group/api/v1/domain/SignOffMeeting.java  |  64 ++++
 build.gradle                                       |  29 ++
 component-test/build.gradle                        |  38 +++
 component-test/settings.gradle                     |   1 +
 .../src/main/java/io/mifos/group/TestGroup.java    | 275 +++++++++++++++++
 .../java/io/mifos/group/TestGroupDefinition.java   | 139 +++++++++
 .../listener/GroupDefinitionEventListener.java     |  47 +++
 .../mifos/group/listener/GroupEventListener.java   |  67 +++++
 .../group/listener/MigrationEventListener.java     |  47 +++
 .../mifos/group/util/GroupDefinitionGenerator.java |  41 +++
 .../java/io/mifos/group/util/GroupGenerator.java   |  59 ++++
 component-test/src/main/resources/logback.xml      |  28 ++
 gradle/wrapper/gradle-wrapper.jar                  | Bin 0 -> 54212 bytes
 gradle/wrapper/gradle-wrapper.properties           |   6 +
 gradlew                                            | 172 +++++++++++
 gradlew.bat                                        |  84 ++++++
 service/build.gradle                               |  63 ++++
 service/settings.gradle                            |   1 +
 .../io/mifos/group/service/GroupApplication.java   |  29 ++
 .../io/mifos/group/service/GroupConfiguration.java |  64 ++++
 .../io/mifos/group/service/ServiceConstants.java   |  20 ++
 .../internal/command/ActivateGroupCommand.java     |  38 +++
 .../internal/command/CloseGroupCommand.java        |  38 +++
 .../internal/command/CreateGroupCommand.java       |  32 ++
 .../command/CreateGroupDefinitionCommand.java      |  32 ++
 .../internal/command/InitializeServiceCommand.java |  23 ++
 .../internal/command/ReopenGroupCommand.java       |  38 +++
 .../internal/command/SignOffMeetingCommand.java    |  38 +++
 .../command/UpdateAssignedEmployeeCommand.java     |  36 +++
 .../internal/command/UpdateLeadersCommand.java     |  38 +++
 .../internal/command/UpdateMembersCommand.java     |  38 +++
 .../internal/command/handler/GroupAggregate.java   | 332 +++++++++++++++++++++
 .../command/handler/MigrationAggregate.java        |  58 ++++
 .../service/internal/mapper/AddressMapper.java     |  48 +++
 .../service/internal/mapper/AttendeeMapper.java    |  33 ++
 .../internal/mapper/GroupCommandMapper.java        |  49 +++
 .../internal/mapper/GroupDefinitionMapper.java     |  51 ++++
 .../group/service/internal/mapper/GroupMapper.java |  48 +++
 .../service/internal/mapper/MeetingMapper.java     |  43 +++
 .../service/internal/repository/AddressEntity.java | 105 +++++++
 .../internal/repository/AddressRepository.java     |  23 ++
 .../internal/repository/AttendeeEntity.java        |  79 +++++
 .../internal/repository/AttendeeRepository.java    |  27 ++
 .../internal/repository/GroupCommandEntity.java    | 104 +++++++
 .../repository/GroupCommandRepository.java         |  27 ++
 .../internal/repository/GroupDefinitionEntity.java | 161 ++++++++++
 .../repository/GroupDefinitionRepository.java      |  27 ++
 .../service/internal/repository/GroupEntity.java   | 207 +++++++++++++
 .../internal/repository/GroupRepository.java       |  31 ++
 .../service/internal/repository/MeetingEntity.java | 138 +++++++++
 .../internal/repository/MeetingRepository.java     |  39 +++
 .../internal/service/GroupDefinitionService.java   |  55 ++++
 .../service/internal/service/GroupService.java     | 134 +++++++++
 .../rest/GroupDefinitionRestController.java        | 104 +++++++
 .../group/service/rest/GroupRestController.java    | 269 +++++++++++++++++
 .../service/rest/MigrationRestController.java      |  60 ++++
 service/src/main/resources/application.yml         |  67 +++++
 service/src/main/resources/bootstrap.yml           |  19 ++
 .../db/migrations/mariadb/V1__initial_setup.sql    | 100 +++++++
 settings.gradle                                    |   5 +
 shared.gradle                                      |  64 ++++
 84 files changed, 5555 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..95274b9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,16 @@
+.gradle
+.idea
+**/build/
+**/target/
+
+# Ignore Gradle GUI config
+gradle-app.setting
+
+# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
+!gradle-wrapper.jar
+
+*.iml
+
+*.log
+
+*.toDelete
\ No newline at end of file
diff --git a/HEADER b/HEADER
new file mode 100644
index 0000000..76f9222
--- /dev/null
+++ b/HEADER
@@ -0,0 +1,13 @@
+Copyright ${year} ${name}
+
+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.
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..8dada3e
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   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.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..bec5de8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,25 @@
+# Mifos I/O Group Management
+
+[![Join the chat at https://gitter.im/mifos-initiative/mifos.io](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mifos-initiative/mifos.io?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+This project provides Group management capabilities.
+
+## Versioning
+The version numbers follow the [Semantic Versioning](http://semver.org/) scheme.
+
+In addition to MAJOR.MINOR.PATCH the following postfixes are used to indicate the development state.
+
+* BUILD-SNAPSHOT - A release currently in development. 
+* M - A _milestone_ release include specific sets of functions and are released as soon as the functionality is complete.
+* RC - A _release candidate_ is a version with potential to be a final product, considered _code complete_.
+* RELEASE - _General availability_ indicates that this release is the best available version and is recommended for all usage.
+
+The versioning layout is {MAJOR}.{MINOR}.{PATCH}-{INDICATOR}[.{PATCH}]. Only milestones and release candidates can  have patch versions. Some examples:
+
+1.2.3.BUILD-SNAPSHOT  
+1.3.5.M.1  
+1.5.7.RC.2  
+2.0.0.RELEASE
+
+## License
+See [LICENSE](LICENSE) file.
diff --git a/api/build.gradle b/api/build.gradle
new file mode 100644
index 0000000..5dc9656
--- /dev/null
+++ b/api/build.gradle
@@ -0,0 +1,33 @@
+buildscript {
+    repositories {
+        jcenter()
+    }
+
+    dependencies {
+        classpath 'io.spring.gradle:dependency-management-plugin:0.6.0.RELEASE' }
+}
+
+plugins {
+    id "com.github.hierynomus.license" version "0.13.1"
+}
+
+apply from: '../shared.gradle'
+
+dependencies {
+    compile(
+            [group: 'org.springframework.cloud', name: 'spring-cloud-starter-feign'],
+            [group: 'io.mifos.core', name: 'api', version: versions.frameworkapi],
+            [group: 'org.hibernate', name: 'hibernate-validator', version: versions.validator]
+    )
+}
+
+publishing {
+    publications {
+        api(MavenPublication) {
+            from components.java
+            groupId project.group
+            artifactId project.name
+            version project.version
+        }
+    }
+}
diff --git a/api/settings.gradle b/api/settings.gradle
new file mode 100644
index 0000000..5cd7dd3
--- /dev/null
+++ b/api/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'api'
diff --git a/api/src/main/java/io/mifos/group/api/v1/EventConstants.java b/api/src/main/java/io/mifos/group/api/v1/EventConstants.java
new file mode 100644
index 0000000..f18fe33
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/EventConstants.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1;
+
+@SuppressWarnings("unused")
+public interface EventConstants {
+
+  String DESTINATION = "group-v1";
+  String SELECTOR_NAME = "action";
+
+  String INITIALIZE = "initialize";
+  String SELECTOR_INITIALIZE = SELECTOR_NAME + " = '" + INITIALIZE + "'";
+
+  String POST_GROUP_DEFINITION = "post-group-definition";
+  String SELECTOR_POST_GROUP_DEFINITION = SELECTOR_NAME + " = '" + POST_GROUP_DEFINITION + "'";
+
+  String POST_GROUP = "post-group";
+  String SELECTOR_POST_GROUP = SELECTOR_NAME + " = '" + POST_GROUP + "'";
+  String PUT_GROUP = "put-group";
+  String SELECTOR_PUT_GROUP = SELECTOR_NAME + " = '" + PUT_GROUP + "'";
+  String ACTIVATE_GROUP = "activate-group";
+  String SELECTOR_ACTIVATE_GROUP = SELECTOR_NAME + " = '" + ACTIVATE_GROUP + "'";
+  String CLOSE_GROUP = "close-group";
+  String SELECTOR_CLOSE_GROUP = SELECTOR_NAME + " = '" + CLOSE_GROUP + "'";
+  String REOPEN_GROUP = "reopen-group";
+  String SELECTOR_REOPEN_GROUP = SELECTOR_NAME + " = '" + REOPEN_GROUP + "'";
+
+  String POST_MEETING = "post-meeting";
+  String SELECTOR_POST_MEETING = SELECTOR_NAME + " = '" + POST_MEETING + "'";
+  String PUT_MEETING = "put-meeting";
+  String SELECTOR_PUT_MEETING = SELECTOR_NAME + " = '" + PUT_MEETING + "'";
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupAlreadyExists.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupAlreadyExists.java
new file mode 100644
index 0000000..35fd6e2
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupAlreadyExists.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.client;
+
+public class GroupAlreadyExists extends RuntimeException {
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupClient.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupClient.java
new file mode 100644
index 0000000..f1e44b9
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupClient.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.client;
+
+import io.mifos.core.api.annotation.ThrowsException;
+import io.mifos.core.api.annotation.ThrowsExceptions;
+import io.mifos.core.api.util.CustomFeignClientsConfiguration;
+import io.mifos.group.api.v1.domain.AssignedEmployeeHolder;
+import io.mifos.group.api.v1.domain.SignOffMeeting;
+import io.mifos.group.api.v1.domain.Group;
+import io.mifos.group.api.v1.domain.GroupCommand;
+import io.mifos.group.api.v1.domain.GroupDefinition;
+import io.mifos.group.api.v1.domain.GroupPage;
+import io.mifos.group.api.v1.domain.Meeting;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.List;
+import java.util.Set;
+
+@SuppressWarnings("unused")
+@FeignClient(name="group-v1", path="/group/v1", configuration=CustomFeignClientsConfiguration.class)
+public interface GroupClient {
+
+  @RequestMapping(
+      value = "/definitions",
+      method = RequestMethod.POST,
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ThrowsExceptions({
+      @ThrowsException(status = HttpStatus.CONFLICT, exception = GroupDefinitionAlreadyExists.class),
+      @ThrowsException(status = HttpStatus.BAD_REQUEST, exception = GroupDefinitionValidation.class)
+  })
+  void createGroupDefinition(@RequestBody final GroupDefinition groupDefinition);
+
+  @RequestMapping(
+      value = "/definitions/{identifier}",
+      method = RequestMethod.GET,
+      produces = MediaType.ALL_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ResponseBody
+  @ThrowsException(status = HttpStatus.NOT_FOUND, exception = GroupDefinitionNotFound.class)
+  GroupDefinition findGroupDefinition(@PathVariable("identifier") final String identifier);
+
+  @RequestMapping(
+      value = "/definitions",
+      method = RequestMethod.GET,
+      produces = MediaType.ALL_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ResponseBody
+  List<GroupDefinition> fetchGroupDefinitions();
+
+  @RequestMapping(
+      value = "/groups",
+      method = RequestMethod.POST,
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ThrowsExceptions({
+      @ThrowsException(status = HttpStatus.CONFLICT, exception = GroupAlreadyExists.class),
+      @ThrowsException(status = HttpStatus.BAD_REQUEST, exception = GroupValidationException.class)
+  })
+  void createGroup(@RequestBody final Group group);
+
+  @RequestMapping(
+      value = "/groups",
+      method = RequestMethod.GET,
+      produces = MediaType.ALL_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  GroupPage fetchGroups(@RequestParam("employee") final String employee,
+                        @RequestParam("page") final Integer page,
+                        @RequestParam("size") final Integer size,
+                        @RequestParam("sortColumn") final String sortColumn,
+                        @RequestParam("sortDirection") final String sortDirection);
+
+  @RequestMapping(
+      value = "/groups/{identifier}",
+      method = RequestMethod.GET,
+      produces = MediaType.ALL_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ThrowsException(status = HttpStatus.NOT_FOUND, exception = GroupNotFoundException.class)
+  Group findGroup(@PathVariable("identifier") final String identifier);
+
+  @RequestMapping(
+      value = "/groups/{identifier}/leaders",
+      method = RequestMethod.PUT,
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ThrowsException(status = HttpStatus.NOT_FOUND, exception = GroupNotFoundException.class)
+  void updateLeaders(@PathVariable("identifier") final String identifier, final Set<String> customerIdentifiers);
+
+  @RequestMapping(
+      value = "/groups/{identifier}/members",
+      method = RequestMethod.PUT,
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ThrowsException(status = HttpStatus.NOT_FOUND, exception = GroupNotFoundException.class)
+  void updateMembers(@PathVariable("identifier") final String identifier, final Set<String> customerIdentifiers);
+
+  @RequestMapping(
+      value = "/groups/{identifier}/employee",
+      method = RequestMethod.PUT,
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ThrowsException(status = HttpStatus.NOT_FOUND, exception = GroupNotFoundException.class)
+  void updateAssignedEmployee(@PathVariable("identifier") final String identifier,
+                              final AssignedEmployeeHolder assignedEmployeeHolder);
+
+  @RequestMapping(
+      value = "/groups/{identifier}/commands",
+      method = RequestMethod.POST,
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ThrowsException(status = HttpStatus.NOT_FOUND, exception = GroupNotFoundException.class)
+  void processGroupCommand(@PathVariable("identifier") final String identifier, final GroupCommand groupCommand);
+
+  @RequestMapping(
+      value = "/groups/{identifier}/commands",
+      method = RequestMethod.GET,
+      produces = MediaType.ALL_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ThrowsException(status = HttpStatus.NOT_FOUND, exception = GroupNotFoundException.class)
+  List<GroupCommand> fetchGroupCommands(@PathVariable("identifier") final String identifier);
+
+  @RequestMapping(
+      value = "/groups/{identifier}/meetings",
+      method = RequestMethod.GET,
+      produces = MediaType.ALL_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ThrowsException(status = HttpStatus.NOT_FOUND, exception = GroupNotFoundException.class)
+  List<Meeting> fetchMeetings(
+      @PathVariable("identifier") final String groupIdentifier,
+      @RequestParam("upcoming") final Boolean upcoming);
+
+  @RequestMapping(
+      value = "/groups/{identifier}/meetings",
+      method = RequestMethod.PUT,
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ThrowsException(status = HttpStatus.NOT_FOUND, exception = GroupNotFoundException.class)
+  void closeMeeting(@PathVariable("identifier") final String groupIdentifier, final SignOffMeeting signOffMeeting);
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionAlreadyExists.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionAlreadyExists.java
new file mode 100644
index 0000000..261411a
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionAlreadyExists.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.client;
+
+public class GroupDefinitionAlreadyExists extends RuntimeException {
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionNotFound.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionNotFound.java
new file mode 100644
index 0000000..99e2676
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionNotFound.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.client;
+
+public class GroupDefinitionNotFound extends RuntimeException {
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionValidation.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionValidation.java
new file mode 100644
index 0000000..75be3a1
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupDefinitionValidation.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.client;
+
+public class GroupDefinitionValidation extends RuntimeException {
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupNotFoundException.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupNotFoundException.java
new file mode 100644
index 0000000..629c5e6
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupNotFoundException.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.client;
+
+public class GroupNotFoundException extends RuntimeException {
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/client/GroupValidationException.java b/api/src/main/java/io/mifos/group/api/v1/client/GroupValidationException.java
new file mode 100644
index 0000000..2a3bd0b
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/client/GroupValidationException.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.client;
+
+public class GroupValidationException extends RuntimeException {
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/Address.java b/api/src/main/java/io/mifos/group/api/v1/domain/Address.java
new file mode 100644
index 0000000..902b255
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/Address.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.domain;
+
+import org.hibernate.validator.constraints.NotBlank;
+
+public class Address {
+
+  @NotBlank
+  private String street;
+  @NotBlank
+  private String city;
+  private String region;
+  private String postalCode;
+  @NotBlank
+  private String countryCode;
+  private String country;
+
+  public Address() {
+    super();
+  }
+
+  public String getStreet() {
+    return this.street;
+  }
+
+  public void setStreet(final String street) {
+    this.street = street;
+  }
+
+  public String getCity() {
+    return this.city;
+  }
+
+  public void setCity(final String city) {
+    this.city = city;
+  }
+
+  public String getRegion() {
+    return this.region;
+  }
+
+  public void setRegion(final String region) {
+    this.region = region;
+  }
+
+  public String getPostalCode() {
+    return this.postalCode;
+  }
+
+  public void setPostalCode(final String postalCode) {
+    this.postalCode = postalCode;
+  }
+
+  public String getCountryCode() {
+    return this.countryCode;
+  }
+
+  public void setCountryCode(final String countryCode) {
+    this.countryCode = countryCode;
+  }
+
+  public String getCountry() {
+    return this.country;
+  }
+
+  public void setCountry(final String country) {
+    this.country = country;
+  }
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/AssignedEmployeeHolder.java b/api/src/main/java/io/mifos/group/api/v1/domain/AssignedEmployeeHolder.java
new file mode 100644
index 0000000..e2ce5d8
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/AssignedEmployeeHolder.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.domain;
+
+public class AssignedEmployeeHolder {
+
+  private String identifier;
+
+  public AssignedEmployeeHolder() {
+    super();
+  }
+
+  public String getIdentifier() {
+    return this.identifier;
+  }
+
+  public void setIdentifier(final String identifier) {
+    this.identifier = identifier;
+  }
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/Attendee.java b/api/src/main/java/io/mifos/group/api/v1/domain/Attendee.java
new file mode 100644
index 0000000..147be78
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/Attendee.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.domain;
+
+import org.hibernate.validator.constraints.NotBlank;
+
+import javax.validation.constraints.NotNull;
+
+public class Attendee {
+
+  @NotBlank
+  private String customerIdentifier;
+  @NotNull
+  private Status status;
+
+  public Attendee() {
+    super();
+  }
+
+  public String getCustomerIdentifier() {
+    return this.customerIdentifier;
+  }
+
+  public void setCustomerIdentifier(final String customerIdentifier) {
+    this.customerIdentifier = customerIdentifier;
+  }
+
+  public String getStatus() {
+    return this.status.name();
+  }
+
+  public void setStatus(final String status) {
+    this.status = Status.valueOf(status);
+  }
+
+  public enum Status {
+    EXPECTED,
+    ATTENDED,
+    MISSED
+  }
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/Cycle.java b/api/src/main/java/io/mifos/group/api/v1/domain/Cycle.java
new file mode 100644
index 0000000..261c651
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/Cycle.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.domain;
+
+import javax.validation.constraints.NotNull;
+
+public class Cycle {
+
+  @NotNull
+  private Integer numberOfMeetings;
+  @NotNull
+  private Frequency frequency;
+  private Adjustment adjustment;
+
+  public Cycle() {
+    super();
+  }
+
+  public Integer getNumberOfMeetings() {
+    return this.numberOfMeetings;
+  }
+
+  public void setNumberOfMeetings(final Integer numberOfMeetings) {
+    this.numberOfMeetings = numberOfMeetings;
+  }
+
+  public String getFrequency() {
+    return this.frequency.name();
+  }
+
+  public void setFrequency(final String frequency) {
+    this.frequency = Frequency.valueOf(frequency);
+  }
+
+  public String getAdjustment() {
+    return this.adjustment.name();
+  }
+
+  public void setAdjustment(final String adjustment) {
+    this.adjustment = Adjustment.valueOf(adjustment);
+  }
+
+  public enum Frequency {
+    DAILY,
+    WEEKLY,
+    FORTNIGHTLY,
+    MONTHLY
+  }
+
+  public enum Adjustment {
+    NEXT_BUSINESS_DAY,
+    SKIP
+  }
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/Group.java b/api/src/main/java/io/mifos/group/api/v1/domain/Group.java
new file mode 100644
index 0000000..c38d955
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/Group.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.domain;
+
+import org.hibernate.validator.constraints.NotBlank;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.util.Objects;
+import java.util.Set;
+
+public class Group {
+
+  @NotBlank
+  private String identifier;
+  @NotBlank
+  private String groupDefinitionIdentifier;
+  @NotBlank
+  private String name;
+  @Size(max = 15)
+  private Set<String> leaders;
+  @Size(min = 1, max = 60)
+  private Set<String> members;
+  @NotBlank
+  private String office;
+  @NotBlank
+  private String assignedEmployee;
+  @NotNull
+  private Integer weekday;
+  private Status status;
+  @Valid
+  private Address address;
+  private String createdOn;
+  private String createdBy;
+  private String lastModifiedOn;
+  private String lastModifiedBy;
+
+  public Group() {
+    super();
+  }
+
+  public String getGroupDefinitionIdentifier() {
+    return this.groupDefinitionIdentifier;
+  }
+
+  public void setGroupDefinitionIdentifier(final String groupDefinitionIdentifier) {
+    this.groupDefinitionIdentifier = groupDefinitionIdentifier;
+  }
+
+  public String getIdentifier() {
+    return this.identifier;
+  }
+
+  public void setIdentifier(final String identifier) {
+    this.identifier = identifier;
+  }
+
+  public String getName() {
+    return this.name;
+  }
+
+  public void setName(final String name) {
+    this.name = name;
+  }
+
+  public Set<String> getLeaders() {
+    return this.leaders;
+  }
+
+  public void setLeaders(final Set<String> leaders) {
+    this.leaders = leaders;
+  }
+
+  public Set<String> getMembers() {
+    return this.members;
+  }
+
+  public void setMembers(final Set<String> members) {
+    this.members = members;
+  }
+
+  public String getOffice() {
+    return this.office;
+  }
+
+  public void setOffice(final String office) {
+    this.office = office;
+  }
+
+  public String getAssignedEmployee() {
+    return this.assignedEmployee;
+  }
+
+  public void setAssignedEmployee(final String assignedEmployee) {
+    this.assignedEmployee = assignedEmployee;
+  }
+
+  public String getStatus() {
+    return this.status.name();
+  }
+
+  public void setStatus(final String status) {
+    this.status = Status.valueOf(status);
+  }
+
+  public Integer getWeekday() {
+    return this.weekday;
+  }
+
+  public void setWeekday(final Integer weekday) {
+    this.weekday = weekday;
+  }
+
+  public Address getAddress() {
+    return this.address;
+  }
+
+  public void setAddress(final Address address) {
+    this.address = address;
+  }
+
+  public String getCreatedOn() {
+    return this.createdOn;
+  }
+
+  public void setCreatedOn(final String createdOn) {
+    this.createdOn = createdOn;
+  }
+
+  public String getCreatedBy() {
+    return this.createdBy;
+  }
+
+  public void setCreatedBy(final String createdBy) {
+    this.createdBy = createdBy;
+  }
+
+  public String getLastModifiedOn() {
+    return this.lastModifiedOn;
+  }
+
+  public void setLastModifiedOn(final String lastModifiedOn) {
+    this.lastModifiedOn = lastModifiedOn;
+  }
+
+  public String getLastModifiedBy() {
+    return this.lastModifiedBy;
+  }
+
+  public void setLastModifiedBy(final String lastModifiedBy) {
+    this.lastModifiedBy = lastModifiedBy;
+  }
+
+  public enum Weekday {
+    MONDAY(1),
+    TUESDAY(2),
+    WEDNESDAY(3),
+    THURSDAY(4),
+    FRIDAY(5),
+    SATURDAY(6),
+    SUNDAY(7);
+
+    private Integer value;
+
+    Weekday(final Integer value) {
+      this.value = value;
+    }
+
+    public static Weekday from(final Integer dayOfWeek) {
+      for (Weekday weekday : Weekday.values()) {
+        if (Objects.equals(weekday.value, dayOfWeek)) {
+          return weekday;
+        }
+      }
+      throw new IllegalArgumentException("Unknown day of week '" + dayOfWeek + "'.");
+    }
+
+    public Integer getValue() {
+      return this.value;
+    }
+  }
+
+  public enum Status {
+    PENDING,
+    ACTIVE,
+    CLOSED
+  }
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/GroupCommand.java b/api/src/main/java/io/mifos/group/api/v1/domain/GroupCommand.java
new file mode 100644
index 0000000..1941d47
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/GroupCommand.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.domain;
+
+public class GroupCommand {
+
+  private Action action;
+  private String note;
+  private String createdBy;
+  private String createdOn;
+
+  public GroupCommand() {
+    super();
+  }
+
+  public String getAction() {
+    return this.action.name();
+  }
+
+  public void setAction(final String action) {
+    this.action = Action.valueOf(action);
+  }
+
+  public String getNote() {
+    return this.note;
+  }
+
+  public void setNote(final String note) {
+    this.note = note;
+  }
+
+  public String getCreatedBy() {
+    return this.createdBy;
+  }
+
+  public void setCreatedBy(final String createdBy) {
+    this.createdBy = createdBy;
+  }
+
+  public String getCreatedOn() {
+    return this.createdOn;
+  }
+
+  public void setCreatedOn(final String createdOn) {
+    this.createdOn = createdOn;
+  }
+
+  public enum Action {
+    ACTIVATE,
+    CLOSE,
+    REOPEN
+  }
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/GroupDefinition.java b/api/src/main/java/io/mifos/group/api/v1/domain/GroupDefinition.java
new file mode 100644
index 0000000..70f7726
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/GroupDefinition.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.domain;
+
+import org.hibernate.validator.constraints.NotBlank;
+
+import javax.validation.Valid;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+
+public class GroupDefinition {
+
+  @NotBlank
+  private String identifier;
+  private String description;
+  @NotNull
+  @Min(1L)
+  private Integer minimalSize;
+  @Min(2L)
+  private Integer maximalSize;
+  @Valid
+  private Cycle cycle;
+  private String createOn;
+  private String createdBy;
+  private String lastModifiedOn;
+  private String lastModifiedBy;
+
+  public GroupDefinition() {
+    super();
+  }
+
+  public String getIdentifier() {
+    return this.identifier;
+  }
+
+  public void setIdentifier(final String identifier) {
+    this.identifier = identifier;
+  }
+
+  public String getDescription() {
+    return this.description;
+  }
+
+  public void setDescription(final String description) {
+    this.description = description;
+  }
+
+  public Integer getMinimalSize() {
+    return this.minimalSize;
+  }
+
+  public void setMinimalSize(final Integer minimalSize) {
+    this.minimalSize = minimalSize;
+  }
+
+  public Integer getMaximalSize() {
+    return this.maximalSize;
+  }
+
+  public void setMaximalSize(final Integer maximalSize) {
+    this.maximalSize = maximalSize;
+  }
+
+  public Cycle getCycle() {
+    return this.cycle;
+  }
+
+  public void setCycle(final Cycle cycle) {
+    this.cycle = cycle;
+  }
+
+  public String getCreateOn() {
+    return this.createOn;
+  }
+
+  public void setCreateOn(final String createOn) {
+    this.createOn = createOn;
+  }
+
+  public String getCreatedBy() {
+    return this.createdBy;
+  }
+
+  public void setCreatedBy(final String createdBy) {
+    this.createdBy = createdBy;
+  }
+
+  public String getLastModifiedOn() {
+    return this.lastModifiedOn;
+  }
+
+  public void setLastModifiedOn(final String lastModifiedOn) {
+    this.lastModifiedOn = lastModifiedOn;
+  }
+
+  public String getLastModifiedBy() {
+    return this.lastModifiedBy;
+  }
+
+  public void setLastModifiedBy(final String lastModifiedBy) {
+    this.lastModifiedBy = lastModifiedBy;
+  }
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/GroupPage.java b/api/src/main/java/io/mifos/group/api/v1/domain/GroupPage.java
new file mode 100644
index 0000000..7ddd739
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/GroupPage.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.domain;
+
+import java.util.List;
+
+public class GroupPage {
+
+  private List<Group> groups;
+  private Integer totalPages;
+  private Long totalElements;
+
+  public GroupPage() {
+    super();
+  }
+
+  public List<Group> getGroups() {
+    return this.groups;
+  }
+
+  public void setGroups(final List<Group> groups) {
+    this.groups = groups;
+  }
+
+  public Integer getTotalPages() {
+    return this.totalPages;
+  }
+
+  public void setTotalPages(final Integer totalPages) {
+    this.totalPages = totalPages;
+  }
+
+  public Long getTotalElements() {
+    return this.totalElements;
+  }
+
+  public void setTotalElements(final Long totalElements) {
+    this.totalElements = totalElements;
+  }
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/Meeting.java b/api/src/main/java/io/mifos/group/api/v1/domain/Meeting.java
new file mode 100644
index 0000000..7770ac3
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/Meeting.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.domain;
+
+import org.hibernate.validator.constraints.NotBlank;
+import org.hibernate.validator.constraints.NotEmpty;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.util.Set;
+
+public class Meeting {
+
+  @NotBlank
+  private Integer meetingSequence;
+  @NotBlank
+  private String groupIdentifier;
+  @NotNull
+  private Integer currentCycle;
+  @NotEmpty
+  @Valid
+  private Set<Attendee> attendees;
+  private String scheduledFor;
+  @Valid
+  private Address location;
+  private String heldOn;
+  private Long duration;
+  private String createdOn;
+  private String createdBy;
+
+  public Meeting() {
+    super();
+  }
+
+  public Integer getMeetingSequence() {
+    return this.meetingSequence;
+  }
+
+  public void setMeetingSequence(final Integer meetingSequence) {
+    this.meetingSequence = meetingSequence;
+  }
+
+  public String getGroupIdentifier() {
+    return this.groupIdentifier;
+  }
+
+  public void setGroupIdentifier(final String groupIdentifier) {
+    this.groupIdentifier = groupIdentifier;
+  }
+
+  public Integer getCurrentCycle() {
+    return this.currentCycle;
+  }
+
+  public void setCurrentCycle(final Integer currentCycle) {
+    this.currentCycle = currentCycle;
+  }
+
+  public Set<Attendee> getAttendees() {
+    return this.attendees;
+  }
+
+  public void setAttendees(final Set<Attendee> attendees) {
+    this.attendees = attendees;
+  }
+
+  public String getScheduledFor() {
+    return this.scheduledFor;
+  }
+
+  public void setScheduledFor(final String scheduledFor) {
+    this.scheduledFor = scheduledFor;
+  }
+
+  public Address getLocation() {
+    return this.location;
+  }
+
+  public void setLocation(final Address location) {
+    this.location = location;
+  }
+
+  public String getHeldOn() {
+    return this.heldOn;
+  }
+
+  public void setHeldOn(final String heldOn) {
+    this.heldOn = heldOn;
+  }
+
+  public Long getDuration() {
+    return this.duration;
+  }
+
+  public void setDuration(final Long duration) {
+    this.duration = duration;
+  }
+
+  public String getCreatedOn() {
+    return this.createdOn;
+  }
+
+  public void setCreatedOn(final String createdOn) {
+    this.createdOn = createdOn;
+  }
+
+  public String getCreatedBy() {
+    return this.createdBy;
+  }
+
+  public void setCreatedBy(final String createdBy) {
+    this.createdBy = createdBy;
+  }
+}
diff --git a/api/src/main/java/io/mifos/group/api/v1/domain/SignOffMeeting.java b/api/src/main/java/io/mifos/group/api/v1/domain/SignOffMeeting.java
new file mode 100644
index 0000000..a8e71f7
--- /dev/null
+++ b/api/src/main/java/io/mifos/group/api/v1/domain/SignOffMeeting.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.api.v1.domain;
+
+import javax.validation.Valid;
+import java.util.Set;
+
+public class SignOffMeeting {
+
+  @Valid
+  private Integer cycle;
+  private Integer sequence;
+  private Set<Attendee> attendees;
+  private Long duration;
+
+  public SignOffMeeting() {
+    super();
+  }
+
+  public Integer getCycle() {
+    return this.cycle;
+  }
+
+  public void setCycle(final Integer cycle) {
+    this.cycle = cycle;
+  }
+
+  public Integer getSequence() {
+    return this.sequence;
+  }
+
+  public void setSequence(final Integer sequence) {
+    this.sequence = sequence;
+  }
+
+  public Set<Attendee> getAttendees() {
+    return this.attendees;
+  }
+
+  public void setAttendees(final Set<Attendee> attendees) {
+    this.attendees = attendees;
+  }
+
+  public Long getDuration() {
+    return this.duration;
+  }
+
+  public void setDuration(final Long duration) {
+    this.duration = duration;
+  }
+}
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..b8c09e6
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,29 @@
+group 'io.mifos'
+
+task publishApiToMavenLocal {
+    dependsOn gradle.includedBuild('api').task(':publishToMavenLocal')
+}
+
+task publishServiceToMavenLocal {
+    mustRunAfter publishApiToMavenLocal
+    dependsOn gradle.includedBuild('service').task(':publishToMavenLocal')
+}
+
+task publishComponentTestToMavenLocal {
+    mustRunAfter publishApiToMavenLocal
+    mustRunAfter publishServiceToMavenLocal
+    dependsOn gradle.includedBuild('component-test').task(':publishToMavenLocal')
+}
+
+task publishToMavenLocal {
+    group 'all'
+    dependsOn publishApiToMavenLocal
+    dependsOn publishServiceToMavenLocal
+    dependsOn publishComponentTestToMavenLocal
+}
+
+task prepareForTest {
+    group 'all'
+    dependsOn publishToMavenLocal
+    dependsOn gradle.includedBuild('component-test').task(':build')
+}
diff --git a/component-test/build.gradle b/component-test/build.gradle
new file mode 100644
index 0000000..b9a16bc
--- /dev/null
+++ b/component-test/build.gradle
@@ -0,0 +1,38 @@
+buildscript {
+    ext {
+        springBootVersion = '1.4.1.RELEASE'
+    }
+
+    repositories {
+        jcenter()
+    }
+
+    dependencies {
+        classpath ("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
+    }
+}
+
+plugins {
+    id "com.github.hierynomus.license" version "0.13.1"
+}
+
+apply from: '../shared.gradle'
+
+dependencies {
+    compile(
+            [group: 'io.mifos.group', name: 'api', version: project.version],
+            [group: 'io.mifos.group', name: 'service', version: project.version],
+            [group: 'io.mifos.core', name: 'api', version: versions.frameworkapi],
+            [group: 'io.mifos.core', name: 'test', version: versions.frameworktest],
+            [group: 'io.mifos.anubis', name: 'test', version: versions.frameworkanubis],
+            [group: 'org.springframework.boot', name: 'spring-boot-starter-test']
+    )
+}
+
+publishing {
+    publications {
+        mavenJava(MavenPublication) {
+            from components.java
+        }
+    }
+}
diff --git a/component-test/settings.gradle b/component-test/settings.gradle
new file mode 100644
index 0000000..b2e36e3
--- /dev/null
+++ b/component-test/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'component-test'
diff --git a/component-test/src/main/java/io/mifos/group/TestGroup.java b/component-test/src/main/java/io/mifos/group/TestGroup.java
new file mode 100644
index 0000000..91110f9
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/group/TestGroup.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group;
+
+import io.mifos.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
+import io.mifos.core.api.context.AutoUserContext;
+import io.mifos.core.test.env.TestEnvironment;
+import io.mifos.core.test.fixture.TenantDataStoreContextTestRule;
+import io.mifos.core.test.fixture.cassandra.CassandraInitializer;
+import io.mifos.core.test.fixture.mariadb.MariaDBInitializer;
+import io.mifos.core.test.listener.EnableEventRecording;
+import io.mifos.core.test.listener.EventRecorder;
+import io.mifos.group.api.v1.EventConstants;
+import io.mifos.group.api.v1.client.GroupClient;
+import io.mifos.group.api.v1.domain.AssignedEmployeeHolder;
+import io.mifos.group.api.v1.domain.Attendee;
+import io.mifos.group.api.v1.domain.Group;
+import io.mifos.group.api.v1.domain.GroupCommand;
+import io.mifos.group.api.v1.domain.GroupDefinition;
+import io.mifos.group.api.v1.domain.Meeting;
+import io.mifos.group.api.v1.domain.SignOffMeeting;
+import io.mifos.group.service.GroupConfiguration;
+import io.mifos.group.util.GroupDefinitionGenerator;
+import io.mifos.group.util.GroupGenerator;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.*;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.netflix.feign.EnableFeignClients;
+import org.springframework.cloud.netflix.ribbon.RibbonClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.time.Clock;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
+public class TestGroup {
+  private static final String APP_NAME = "group-v1";
+  private static final String TEST_USER = "ranefer";
+
+  private final static TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
+  private final static CassandraInitializer cassandraInitializer = new CassandraInitializer();
+  private final static MariaDBInitializer mariaDBInitializer = new MariaDBInitializer();
+  private final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
+
+  @ClassRule
+  public static TestRule orderClassRules = RuleChain
+          .outerRule(testEnvironment)
+          .around(cassandraInitializer)
+          .around(mariaDBInitializer)
+          .around(tenantDataStoreContext);
+
+  @Rule
+  public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
+          = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
+  @Autowired
+  private GroupClient groupClient;
+  @Autowired
+  private EventRecorder eventRecorder;
+
+  private AutoUserContext userContext;
+
+  public TestGroup() {
+    super();
+  }
+
+  @Before
+  public void prepTest() {
+    userContext = this.tenantApplicationSecurityEnvironment.createAutoUserContext(TestGroup.TEST_USER);
+  }
+
+  @After
+  public void cleanTest() {
+    userContext.close();
+  }
+
+  public boolean waitForInitialize() {
+    try {
+      return this.eventRecorder.wait(EventConstants.INITIALIZE, EventConstants.INITIALIZE);
+    } catch (final InterruptedException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  @Test
+  public void shouldCreateGroup() throws Exception {
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+
+    this.groupClient.createGroupDefinition(randomGroupDefinition);
+
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+
+    this.groupClient.createGroup(randomGroup);
+
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.groupClient.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(randomGroup.getIdentifier(), fetchedGroup.getIdentifier());
+    Assert.assertEquals(randomGroup.getGroupDefinitionIdentifier(), fetchedGroup.getGroupDefinitionIdentifier());
+    Assert.assertEquals(randomGroup.getName(), fetchedGroup.getName());
+    Assert.assertEquals(randomGroup.getOffice(), fetchedGroup.getOffice());
+    Assert.assertEquals(randomGroup.getAssignedEmployee(), fetchedGroup.getAssignedEmployee());
+    Assert.assertEquals(randomGroup.getWeekday(), fetchedGroup.getWeekday());
+    Assert.assertEquals(Group.Status.PENDING.name(), fetchedGroup.getStatus());
+    Assert.assertEquals(randomGroup.getLeaders().size(), fetchedGroup.getLeaders().size());
+    Assert.assertEquals(randomGroup.getMembers().size(), fetchedGroup.getMembers().size());
+    Assert.assertNotNull(fetchedGroup.getCreatedBy());
+    Assert.assertNotNull(fetchedGroup.getCreatedOn());
+    Assert.assertNull(fetchedGroup.getLastModifiedBy());
+    Assert.assertNull(fetchedGroup.getLastModifiedOn());
+    Assert.assertNotNull(fetchedGroup.getAddress());
+  }
+
+  @Test
+  public void shouldActivateCommand() throws Exception {
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.groupClient.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.groupClient.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.groupClient.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(Group.Status.PENDING.name(), fetchedGroup.getStatus());
+
+    final GroupCommand activate = new GroupCommand();
+    activate.setAction(GroupCommand.Action.ACTIVATE.name());
+    activate.setNote(RandomStringUtils.randomAlphanumeric(256));
+    activate.setCreatedBy(TestGroup.TEST_USER);
+    activate.setCreatedOn(ZonedDateTime.now(Clock.systemUTC()).format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
+
+    this.groupClient.processGroupCommand(randomGroup.getIdentifier(), activate);
+    this.eventRecorder.wait(EventConstants.ACTIVATE_GROUP, randomGroup.getIdentifier());
+
+    final Group activatedGroup = this.groupClient.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(Group.Status.ACTIVE.name(), activatedGroup.getStatus());
+
+    final List<GroupCommand> groupCommands = this.groupClient.fetchGroupCommands(activatedGroup.getIdentifier());
+    Assert.assertTrue(groupCommands.size() == 1);
+    final GroupCommand groupCommand = groupCommands.get(0);
+    Assert.assertEquals(activate.getAction(), groupCommand.getAction());
+    Assert.assertEquals(activate.getNote(), groupCommand.getNote());
+    Assert.assertEquals(activate.getCreatedBy(), groupCommand.getCreatedBy());
+    Assert.assertNotNull(groupCommand.getCreatedOn());
+
+    final List<Meeting> meetings = this.groupClient.fetchMeetings(activatedGroup.getIdentifier(), Boolean.FALSE);
+    Assert.assertNotNull(meetings);
+    Assert.assertEquals(randomGroupDefinition.getCycle().getNumberOfMeetings(), Integer.valueOf(meetings.size()));
+
+    final Meeting meeting2signOff = meetings.get(0);
+    final SignOffMeeting signOffMeeting = new SignOffMeeting();
+    signOffMeeting.setCycle(meeting2signOff.getCurrentCycle());
+    signOffMeeting.setSequence(meeting2signOff.getMeetingSequence());
+    signOffMeeting.setDuration(120L);
+    signOffMeeting.setAttendees(meeting2signOff.getAttendees()
+        .stream()
+        .map(attendee -> {
+          attendee.setStatus(Attendee.Status.ATTENDED.name());
+          return attendee;
+        })
+        .collect(Collectors.toSet())
+    );
+
+    this.groupClient.closeMeeting(activatedGroup.getIdentifier(), signOffMeeting);
+    this.eventRecorder.wait(EventConstants.PUT_GROUP, activatedGroup.getIdentifier());
+  }
+
+  @Test
+  public void shouldUpdateLeaders() throws Exception {
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.groupClient.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.groupClient.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final int currentLeadersSize = randomGroup.getLeaders().size();
+    randomGroup.getLeaders().add(RandomStringUtils.randomAlphanumeric(32));
+    this.groupClient.updateLeaders(randomGroup.getIdentifier(), randomGroup.getLeaders());
+    this.eventRecorder.wait(EventConstants.PUT_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.groupClient.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals((currentLeadersSize + 1), fetchedGroup.getLeaders().size());
+  }
+
+  @Test
+  public void shouldUpdateMembers() throws Exception {
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.groupClient.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.groupClient.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final int currentMembersSize = randomGroup.getMembers().size();
+    randomGroup.getMembers().addAll(Arrays.asList(
+        RandomStringUtils.randomAlphanumeric(32),
+        RandomStringUtils.randomAlphanumeric(32)
+    ));
+    this.groupClient.updateMembers(randomGroup.getIdentifier(), randomGroup.getMembers());
+    this.eventRecorder.wait(EventConstants.PUT_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.groupClient.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals((currentMembersSize + 2), fetchedGroup.getMembers().size());
+  }
+
+  @Test
+  public void shouldUpdateAssignedEmployee() throws Exception {
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.groupClient.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.groupClient.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final AssignedEmployeeHolder anotherEmployee = new AssignedEmployeeHolder();
+    anotherEmployee.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
+
+    this.groupClient.updateAssignedEmployee(randomGroup.getIdentifier(), anotherEmployee);
+    this.eventRecorder.wait(EventConstants.PUT_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.groupClient.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(anotherEmployee.getIdentifier(), fetchedGroup.getAssignedEmployee());
+  }
+
+  @Configuration
+  @EnableEventRecording
+  @EnableFeignClients(basePackages = {"io.mifos.group.api.v1.client"})
+  @RibbonClient(name = APP_NAME)
+  @Import({GroupConfiguration.class})
+  @ComponentScan("io.mifos.group.listener")
+  public static class TestConfiguration {
+    public TestConfiguration() {
+      super();
+    }
+
+    @Bean()
+    public Logger logger() {
+      return LoggerFactory.getLogger("test-logger");
+    }
+  }
+}
diff --git a/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java b/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java
new file mode 100644
index 0000000..b33ad72
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/group/TestGroupDefinition.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group;
+
+import io.mifos.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
+import io.mifos.core.api.context.AutoUserContext;
+import io.mifos.core.lang.TenantContextHolder;
+import io.mifos.core.test.env.TestEnvironment;
+import io.mifos.core.test.fixture.TenantDataStoreContextTestRule;
+import io.mifos.core.test.fixture.cassandra.CassandraInitializer;
+import io.mifos.core.test.fixture.mariadb.MariaDBInitializer;
+import io.mifos.core.test.listener.EnableEventRecording;
+import io.mifos.core.test.listener.EventRecorder;
+import io.mifos.group.api.v1.EventConstants;
+import io.mifos.group.api.v1.client.GroupClient;
+import io.mifos.group.api.v1.domain.GroupDefinition;
+import io.mifos.group.service.GroupConfiguration;
+import io.mifos.group.util.GroupDefinitionGenerator;
+import org.junit.*;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.netflix.feign.EnableFeignClients;
+import org.springframework.cloud.netflix.ribbon.RibbonClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
+public class TestGroupDefinition {
+  private static final String APP_NAME = "group-v1";
+  private static final String TEST_USER = "ranefer";
+
+  private final static TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
+  private final static CassandraInitializer cassandraInitializer = new CassandraInitializer();
+  private final static MariaDBInitializer mariaDBInitializer = new MariaDBInitializer();
+  private final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
+
+  @ClassRule
+  public static TestRule orderClassRules = RuleChain
+          .outerRule(testEnvironment)
+          .around(cassandraInitializer)
+          .around(mariaDBInitializer)
+          .around(tenantDataStoreContext);
+
+  @Rule
+  public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
+          = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
+
+  @Autowired
+  private GroupClient groupClient;
+  @Autowired
+  private EventRecorder eventRecorder;
+
+  private AutoUserContext userContext;
+
+  public TestGroupDefinition() {
+    super();
+  }
+
+  @Before
+  public void prepTest() {
+    userContext = this.tenantApplicationSecurityEnvironment.createAutoUserContext(TestGroupDefinition.TEST_USER);
+  }
+
+  @After
+  public void cleanTest() {
+    TenantContextHolder.clear();
+    userContext.close();
+  }
+
+  public boolean waitForInitialize() {
+    try {
+      return this.eventRecorder.wait(EventConstants.INITIALIZE, EventConstants.INITIALIZE);
+    } catch (final InterruptedException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  @Test
+  public void shouldCreateGroupDefinition() throws Exception {
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.groupClient.createGroupDefinition(randomGroupDefinition);
+
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final GroupDefinition fetchedGroupDefinition = this.groupClient.findGroupDefinition(randomGroupDefinition.getIdentifier());
+
+    Assert.assertEquals(randomGroupDefinition.getIdentifier(), fetchedGroupDefinition.getIdentifier());
+    Assert.assertEquals(randomGroupDefinition.getDescription(), fetchedGroupDefinition.getDescription());
+    Assert.assertEquals(randomGroupDefinition.getMinimalSize(), fetchedGroupDefinition.getMinimalSize());
+    Assert.assertEquals(randomGroupDefinition.getMaximalSize(), fetchedGroupDefinition.getMaximalSize());
+    Assert.assertNotNull(fetchedGroupDefinition.getCycle());
+    Assert.assertEquals(randomGroupDefinition.getCycle().getNumberOfMeetings(), fetchedGroupDefinition.getCycle().getNumberOfMeetings());
+    Assert.assertEquals(randomGroupDefinition.getCycle().getFrequency(), fetchedGroupDefinition.getCycle().getFrequency());
+    Assert.assertEquals(randomGroupDefinition.getCycle().getAdjustment(), fetchedGroupDefinition.getCycle().getAdjustment());
+    Assert.assertNotNull(fetchedGroupDefinition.getCreatedBy());
+    Assert.assertNotNull(fetchedGroupDefinition.getCreateOn());
+    Assert.assertNull(fetchedGroupDefinition.getLastModifiedBy());
+    Assert.assertNull(fetchedGroupDefinition.getLastModifiedOn());
+  }
+
+  @Configuration
+  @EnableEventRecording
+  @EnableFeignClients(basePackages = {"io.mifos.group.api.v1.client"})
+  @RibbonClient(name = APP_NAME)
+  @Import({GroupConfiguration.class})
+  @ComponentScan("io.mifos.group.listener")
+  public static class TestConfiguration {
+    public TestConfiguration() {
+      super();
+    }
+
+    @Bean()
+    public Logger logger() {
+      return LoggerFactory.getLogger("test-logger");
+    }
+  }
+}
diff --git a/component-test/src/main/java/io/mifos/group/listener/GroupDefinitionEventListener.java b/component-test/src/main/java/io/mifos/group/listener/GroupDefinitionEventListener.java
new file mode 100644
index 0000000..a64b355
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/group/listener/GroupDefinitionEventListener.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.listener;
+
+import io.mifos.core.lang.config.TenantHeaderFilter;
+import io.mifos.core.test.listener.EventRecorder;
+import io.mifos.group.api.v1.EventConstants;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.stereotype.Component;
+
+@SuppressWarnings("unused")
+@Component
+public class GroupDefinitionEventListener {
+
+  private final EventRecorder eventRecorder;
+
+  @Autowired
+  public GroupDefinitionEventListener(final EventRecorder eventRecorder) {
+    super();
+    this.eventRecorder = eventRecorder;
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_POST_GROUP_DEFINITION
+  )
+  public void onGroupDefinitionCreated(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                                       final String payload) {
+    this.eventRecorder.event(tenant, EventConstants.POST_GROUP_DEFINITION, payload, String.class);
+  }
+}
diff --git a/component-test/src/main/java/io/mifos/group/listener/GroupEventListener.java b/component-test/src/main/java/io/mifos/group/listener/GroupEventListener.java
new file mode 100644
index 0000000..32446b3
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/group/listener/GroupEventListener.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.listener;
+
+import io.mifos.core.lang.config.TenantHeaderFilter;
+import io.mifos.core.test.listener.EventRecorder;
+import io.mifos.group.api.v1.EventConstants;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.stereotype.Component;
+
+@SuppressWarnings("unused")
+@Component
+public class GroupEventListener {
+
+  private final EventRecorder eventRecorder;
+
+  @Autowired
+  public GroupEventListener(final EventRecorder eventRecorder) {
+    super();
+    this.eventRecorder = eventRecorder;
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_POST_GROUP
+  )
+  public void onGroupCreated(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                             final String payload) {
+    this.eventRecorder.event(tenant, EventConstants.POST_GROUP, payload, String.class);
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_ACTIVATE_GROUP
+  )
+  public void onGroupActivated(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                             final String payload) {
+    this.eventRecorder.event(tenant, EventConstants.ACTIVATE_GROUP, payload, String.class);
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_PUT_GROUP
+  )
+  public void onGroupUpdated(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                               final String payload) {
+    this.eventRecorder.event(tenant, EventConstants.PUT_GROUP, payload, String.class);
+  }
+}
diff --git a/component-test/src/main/java/io/mifos/group/listener/MigrationEventListener.java b/component-test/src/main/java/io/mifos/group/listener/MigrationEventListener.java
new file mode 100644
index 0000000..df7c8fb
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/group/listener/MigrationEventListener.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.listener;
+
+import io.mifos.core.lang.config.TenantHeaderFilter;
+import io.mifos.core.test.listener.EventRecorder;
+import io.mifos.group.api.v1.EventConstants;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.stereotype.Component;
+
+@SuppressWarnings("unused")
+@Component
+public class MigrationEventListener {
+
+  private final EventRecorder eventRecorder;
+
+  @Autowired
+  public MigrationEventListener(final EventRecorder eventRecorder) {
+    super();
+    this.eventRecorder = eventRecorder;
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_INITIALIZE
+  )
+  public void onInitialization(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                               final String payload) {
+    this.eventRecorder.event(tenant, EventConstants.INITIALIZE, payload, String.class);
+  }
+}
diff --git a/component-test/src/main/java/io/mifos/group/util/GroupDefinitionGenerator.java b/component-test/src/main/java/io/mifos/group/util/GroupDefinitionGenerator.java
new file mode 100644
index 0000000..7024152
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/group/util/GroupDefinitionGenerator.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.util;
+
+import io.mifos.group.api.v1.domain.Cycle;
+import io.mifos.group.api.v1.domain.GroupDefinition;
+import org.apache.commons.lang3.RandomStringUtils;
+
+public class GroupDefinitionGenerator {
+
+  private GroupDefinitionGenerator() {
+    super();
+  }
+
+  public static GroupDefinition createRandomGroupDefinition() {
+    final GroupDefinition groupDefinition = new GroupDefinition();
+    groupDefinition.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
+    groupDefinition.setDescription(RandomStringUtils.randomAlphabetic(2048));
+    groupDefinition.setMinimalSize(10);
+    groupDefinition.setMaximalSize(30);
+    final Cycle cycle = new Cycle();
+    cycle.setNumberOfMeetings(25);
+    cycle.setFrequency(Cycle.Frequency.WEEKLY.name());
+    cycle.setAdjustment(Cycle.Adjustment.NEXT_BUSINESS_DAY.name());
+    groupDefinition.setCycle(cycle);
+    return groupDefinition;
+  }
+}
diff --git a/component-test/src/main/java/io/mifos/group/util/GroupGenerator.java b/component-test/src/main/java/io/mifos/group/util/GroupGenerator.java
new file mode 100644
index 0000000..d00bde4
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/group/util/GroupGenerator.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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 io.mifos.group.util;
+
+import io.mifos.group.api.v1.domain.Address;
+import io.mifos.group.api.v1.domain.Group;
+import org.apache.commons.lang3.RandomStringUtils;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+public class GroupGenerator {
+
+  private GroupGenerator() {
+    super();
+  }
+
+  public static Group createRandomGroup(final String definitionIdentifier) {
+    final Group group = new Group();
+    group.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
+    group.setGroupDefinitionIdentifier(definitionIdentifier);
+    group.setName(RandomStringUtils.randomAlphanumeric(256));
+    group.setOffice(RandomStringUtils.randomAlphanumeric(32));
+    group.setAssignedEmployee(RandomStringUtils.randomAlphanumeric(32));
+    group.setLeaders(new HashSet<>(Arrays.asList(
+        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32)
+    )));
+    group.setMembers(new HashSet<>(Arrays.asList(
+        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
+        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
+        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
+        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
+        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32)
+    )));
+    group.setWeekday(Group.Weekday.WEDNESDAY.getValue());
+    final Address address = new Address();
+    address.setStreet(RandomStringUtils.randomAlphanumeric(256));
+    address.setCity(RandomStringUtils.randomAlphanumeric(256));
+    address.setRegion(RandomStringUtils.randomAlphanumeric(256));
+    address.setPostalCode(RandomStringUtils.randomAlphanumeric(2));
+    address.setCountry(RandomStringUtils.randomAlphanumeric(256));
+    address.setCountryCode(RandomStringUtils.randomAlphanumeric(2));
+    group.setAddress(address);
+    return group;
+  }
+}
diff --git a/component-test/src/main/resources/logback.xml b/component-test/src/main/resources/logback.xml
new file mode 100644
index 0000000..e0b1e5e
--- /dev/null
+++ b/component-test/src/main/resources/logback.xml
@@ -0,0 +1,28 @@
+<!--
+
+    Copyright 2017 The Mifos Initiative
+
+    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.
+
+-->
+<configuration>
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <root level="INFO">
+        <appender-ref ref="STDOUT"/>
+    </root>
+</configuration>
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..c733004
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..4aca373
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Mar 16 14:47:20 CET 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-bin.zip
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..4453cce
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save ( ) {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/service/build.gradle b/service/build.gradle
new file mode 100644
index 0000000..09e8a22
--- /dev/null
+++ b/service/build.gradle
@@ -0,0 +1,63 @@
+buildscript {
+    ext {
+        springBootVersion = '1.4.1.RELEASE'
+    }
+
+    repositories {
+        jcenter()
+    }
+
+    dependencies {
+        classpath ("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
+    }
+}
+
+plugins {
+    id "com.github.hierynomus.license" version "0.13.1"
+}
+
+apply from: '../shared.gradle'
+
+apply plugin: 'spring-boot'
+
+springBoot {
+    executable = true
+    classifier = 'boot'
+}
+
+dependencies {
+    compile(
+            [group: 'org.springframework.cloud', name: 'spring-cloud-starter-config'],
+            [group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka'],
+            [group: 'org.springframework.boot', name: 'spring-boot-starter-jetty'],
+            [group: 'io.mifos.group', name: 'api', version: project.version],
+            [group: 'io.mifos.anubis', name: 'library', version: versions.frameworkanubis],
+            [group: 'com.google.code.gson', name: 'gson'],
+            [group: 'io.mifos.core', name: 'lang', version: versions.frameworklang],
+            [group: 'io.mifos.core', name: 'async', version: versions.frameworkasync],
+            [group: 'io.mifos.core', name: 'cassandra', version: versions.frameworkcassandra],
+            [group: 'io.mifos.core', name: 'mariadb', version: versions.frameworkmariadb],
+            [group: 'io.mifos.core', name: 'command', version: versions.frameworkcommand],
+            [group: 'org.hibernate', name: 'hibernate-validator', version: versions.validator]
+    )
+}
+
+publishToMavenLocal.dependsOn bootRepackage
+
+publishing {
+    publications {
+        service(MavenPublication) {
+            from components.java
+            groupId project.group
+            artifactId project.name
+            version project.version
+        }
+        bootService(MavenPublication) {
+            // "boot" jar
+            artifact ("$buildDir/libs/$project.name-$version-boot.jar")
+            groupId project.group
+            artifactId ("$project.name-boot")
+            version project.version
+        }
+    }
+}
diff --git a/service/settings.gradle b/service/settings.gradle
new file mode 100644
index 0000000..1ed471d
--- /dev/null
+++ b/service/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'service'
diff --git a/service/src/main/java/io/mifos/group/service/GroupApplication.java b/service/src/main/java/io/mifos/group/service/GroupApplication.java
new file mode 100644
index 0000000..1dac37d
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/GroupApplication.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service;
+
+import org.springframework.boot.SpringApplication;
+
+public class GroupApplication {
+
+  public GroupApplication() {
+    super();
+  }
+
+  public static void main(String[] args) {
+    SpringApplication.run(GroupConfiguration.class, args);
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/GroupConfiguration.java b/service/src/main/java/io/mifos/group/service/GroupConfiguration.java
new file mode 100644
index 0000000..0ecceeb
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/GroupConfiguration.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service;
+
+import io.mifos.anubis.config.EnableAnubis;
+import io.mifos.core.async.config.EnableAsync;
+import io.mifos.core.cassandra.config.EnableCassandra;
+import io.mifos.core.command.config.EnableCommandProcessing;
+import io.mifos.core.lang.config.EnableServiceException;
+import io.mifos.core.lang.config.EnableTenantContext;
+import io.mifos.core.mariadb.config.EnableMariaDB;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+@SuppressWarnings("WeakerAccess")
+@Configuration
+@EnableAutoConfiguration
+@EnableDiscoveryClient
+@EnableAsync
+@EnableTenantContext
+@EnableCassandra
+@EnableMariaDB
+@EnableCommandProcessing
+@EnableAnubis
+@EnableServiceException
+@ComponentScan({
+    "io.mifos.group.service.rest",
+    "io.mifos.group.service.internal.service",
+    "io.mifos.group.service.internal.repository",
+    "io.mifos.group.service.internal.command.handler"
+})
+@EnableJpaRepositories({
+    "io.mifos.group.service.internal.repository"
+})
+public class GroupConfiguration {
+
+  public GroupConfiguration() {
+    super();
+  }
+
+  @Bean(name = ServiceConstants.LOGGER_NAME)
+  public Logger logger() {
+    return LoggerFactory.getLogger(ServiceConstants.LOGGER_NAME);
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/ServiceConstants.java b/service/src/main/java/io/mifos/group/service/ServiceConstants.java
new file mode 100644
index 0000000..07ae9a0
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/ServiceConstants.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service;
+
+public interface ServiceConstants {
+  String LOGGER_NAME = "group-logger";
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/ActivateGroupCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/ActivateGroupCommand.java
new file mode 100644
index 0000000..6e03951
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/command/ActivateGroupCommand.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.command;
+
+import io.mifos.group.api.v1.domain.GroupCommand;
+
+public class ActivateGroupCommand {
+
+  private final String identifier;
+  private final GroupCommand groupCommand;
+
+  public ActivateGroupCommand(final String identifier, final GroupCommand groupCommand) {
+    super();
+    this.identifier = identifier;
+    this.groupCommand = groupCommand;
+  }
+
+  public String identifier() {
+    return this.identifier;
+  }
+
+  public GroupCommand groupCommand() {
+    return this.groupCommand;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/CloseGroupCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/CloseGroupCommand.java
new file mode 100644
index 0000000..e599458
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/command/CloseGroupCommand.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.command;
+
+import io.mifos.group.api.v1.domain.GroupCommand;
+
+public class CloseGroupCommand {
+
+  private final String identifier;
+  private final GroupCommand groupCommand;
+
+  public CloseGroupCommand(final String identifier, final GroupCommand groupCommand) {
+    super();
+    this.identifier = identifier;
+    this.groupCommand = groupCommand;
+  }
+
+  public String identifier() {
+    return this.identifier;
+  }
+
+  public GroupCommand groupCommand() {
+    return this.groupCommand;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupCommand.java
new file mode 100644
index 0000000..88515db
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupCommand.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.command;
+
+import io.mifos.group.api.v1.domain.Group;
+
+public class CreateGroupCommand {
+
+  private final Group group;
+
+  public CreateGroupCommand(final Group group) {
+    super();
+    this.group = group;
+  }
+
+  public Group group() {
+    return this.group;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupDefinitionCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupDefinitionCommand.java
new file mode 100644
index 0000000..5c85f8d
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/command/CreateGroupDefinitionCommand.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.command;
+
+import io.mifos.group.api.v1.domain.GroupDefinition;
+
+public class CreateGroupDefinitionCommand {
+
+  private final GroupDefinition groupDefinition;
+
+  public CreateGroupDefinitionCommand(final GroupDefinition groupDefinition) {
+    super();
+    this.groupDefinition = groupDefinition;
+  }
+
+  public GroupDefinition groupDefinition() {
+    return this.groupDefinition;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/InitializeServiceCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/InitializeServiceCommand.java
new file mode 100644
index 0000000..a5e28da
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/command/InitializeServiceCommand.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.command;
+
+public class InitializeServiceCommand {
+
+  public InitializeServiceCommand() {
+    super();
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/ReopenGroupCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/ReopenGroupCommand.java
new file mode 100644
index 0000000..0e83570
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/command/ReopenGroupCommand.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.command;
+
+import io.mifos.group.api.v1.domain.GroupCommand;
+
+public class ReopenGroupCommand {
+
+  private final String identifier;
+  private final GroupCommand groupCommand;
+
+  public ReopenGroupCommand(final String identifier, final GroupCommand groupCommand) {
+    super();
+    this.identifier = identifier;
+    this.groupCommand = groupCommand;
+  }
+
+  public String identifier() {
+    return this.identifier;
+  }
+
+  public GroupCommand groupCommand() {
+    return this.groupCommand;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/SignOffMeetingCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/SignOffMeetingCommand.java
new file mode 100644
index 0000000..0144b32
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/command/SignOffMeetingCommand.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.command;
+
+import io.mifos.group.api.v1.domain.SignOffMeeting;
+
+public class SignOffMeetingCommand {
+
+  private final String groupIdentifier;
+  private final SignOffMeeting signOffMeeting;
+
+  public SignOffMeetingCommand(final String groupIdentifier, final SignOffMeeting signOffMeeting) {
+    super();
+    this.groupIdentifier = groupIdentifier;
+    this.signOffMeeting = signOffMeeting;
+  }
+
+  public String groupIdentifier() {
+    return this.groupIdentifier;
+  }
+
+  public SignOffMeeting signOffMeeting() {
+    return this.signOffMeeting;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/UpdateAssignedEmployeeCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/UpdateAssignedEmployeeCommand.java
new file mode 100644
index 0000000..e664ac1
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/command/UpdateAssignedEmployeeCommand.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.command;
+
+public class UpdateAssignedEmployeeCommand {
+
+  private final String identifier;
+  private final String employeeIdentifier;
+
+  public UpdateAssignedEmployeeCommand(final String identifier, final String employeeIdentifier) {
+    super();
+    this.identifier = identifier;
+    this.employeeIdentifier = employeeIdentifier;
+  }
+
+  public String identifier() {
+    return this.identifier;
+  }
+
+  public String employeeIdentifier() {
+    return this.employeeIdentifier;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/UpdateLeadersCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/UpdateLeadersCommand.java
new file mode 100644
index 0000000..7167aeb
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/command/UpdateLeadersCommand.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.command;
+
+import java.util.Set;
+
+public class UpdateLeadersCommand {
+
+  private final String identifier;
+  private final Set<String> customerIdentifiers;
+
+  public UpdateLeadersCommand(final String identifier, final Set<String> customerIdentifiers) {
+    super();
+    this.identifier = identifier;
+    this.customerIdentifiers = customerIdentifiers;
+  }
+
+  public String identifier() {
+    return this.identifier;
+  }
+
+  public Set<String> customerIdentifiers() {
+    return this.customerIdentifiers;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/UpdateMembersCommand.java b/service/src/main/java/io/mifos/group/service/internal/command/UpdateMembersCommand.java
new file mode 100644
index 0000000..935257a
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/command/UpdateMembersCommand.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.command;
+
+import java.util.Set;
+
+public class UpdateMembersCommand {
+
+  private final String identifier;
+  private final Set<String> customerIdentifiers;
+
+  public UpdateMembersCommand(final String identifier, final Set<String> customerIdentifiers) {
+    super();
+    this.identifier = identifier;
+    this.customerIdentifiers = customerIdentifiers;
+  }
+
+  public String identifier() {
+    return this.identifier;
+  }
+
+  public Set<String> customerIdentifiers() {
+    return this.customerIdentifiers;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/handler/GroupAggregate.java b/service/src/main/java/io/mifos/group/service/internal/command/handler/GroupAggregate.java
new file mode 100644
index 0000000..49074ce
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/command/handler/GroupAggregate.java
@@ -0,0 +1,332 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.command.handler;
+
+import io.mifos.core.api.util.UserContextHolder;
+import io.mifos.core.command.annotation.Aggregate;
+import io.mifos.core.command.annotation.CommandHandler;
+import io.mifos.core.command.annotation.EventEmitter;
+import io.mifos.core.lang.DateConverter;
+import io.mifos.core.lang.ServiceException;
+import io.mifos.group.service.internal.command.ActivateGroupCommand;
+import io.mifos.group.service.internal.command.CloseGroupCommand;
+import io.mifos.group.service.internal.command.CreateGroupCommand;
+import io.mifos.group.service.internal.command.CreateGroupDefinitionCommand;
+import io.mifos.group.service.internal.command.ReopenGroupCommand;
+import io.mifos.group.service.internal.command.SignOffMeetingCommand;
+import io.mifos.group.service.internal.command.UpdateAssignedEmployeeCommand;
+import io.mifos.group.service.internal.command.UpdateLeadersCommand;
+import io.mifos.group.service.internal.command.UpdateMembersCommand;
+import io.mifos.group.service.internal.repository.AddressEntity;
+import io.mifos.group.service.internal.repository.AddressRepository;
+import io.mifos.group.service.internal.repository.AttendeeEntity;
+import io.mifos.group.service.internal.repository.AttendeeRepository;
+import io.mifos.group.service.internal.repository.GroupCommandEntity;
+import io.mifos.group.service.internal.repository.GroupCommandRepository;
+import io.mifos.group.service.internal.repository.GroupDefinitionEntity;
+import io.mifos.group.service.internal.repository.GroupDefinitionRepository;
+import io.mifos.group.service.internal.repository.GroupEntity;
+import io.mifos.group.service.internal.repository.GroupRepository;
+import io.mifos.group.service.internal.repository.MeetingEntity;
+import io.mifos.group.service.internal.repository.MeetingRepository;
+import io.mifos.group.api.v1.EventConstants;
+import io.mifos.group.api.v1.domain.*;
+import io.mifos.group.service.internal.mapper.AddressMapper;
+import io.mifos.group.service.internal.mapper.GroupCommandMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import java.time.Clock;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoField;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@SuppressWarnings("unused")
+@Aggregate
+public class GroupAggregate {
+
+  private final GroupDefinitionRepository groupDefinitionRepository;
+  private final GroupRepository groupRepository;
+  private final GroupCommandRepository groupCommandRepository;
+  private final MeetingRepository meetingRepository;
+  private final AttendeeRepository attendeeRepository;
+  private final AddressRepository addressRepository;
+
+  @Autowired
+  public GroupAggregate(final GroupDefinitionRepository groupDefinitionRepository,
+                        final GroupRepository groupRepository,
+                        final GroupCommandRepository groupCommandRepository,
+                        final MeetingRepository meetingRepository,
+                        final AttendeeRepository attendeeRepository,
+                        final AddressRepository addressRepository) {
+    super();
+    this.groupDefinitionRepository = groupDefinitionRepository;
+    this.groupRepository = groupRepository;
+    this.groupCommandRepository = groupCommandRepository;
+    this.meetingRepository = meetingRepository;
+    this.attendeeRepository = attendeeRepository;
+    this.addressRepository = addressRepository;
+  }
+
+  @Transactional
+  @CommandHandler
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.POST_GROUP_DEFINITION)
+  public String createDefinition(final CreateGroupDefinitionCommand createGroupDefinitionCommand) {
+    final GroupDefinition groupDefinition = createGroupDefinitionCommand.groupDefinition();
+    final GroupDefinitionEntity groupDefinitionEntity = new GroupDefinitionEntity();
+    groupDefinitionEntity.setIdentifier(groupDefinition.getIdentifier());
+    groupDefinitionEntity.setDescription(groupDefinition.getDescription());
+    groupDefinitionEntity.setMinimalSize(groupDefinition.getMinimalSize());
+    groupDefinitionEntity.setMaximalSize(groupDefinition.getMaximalSize());
+    final Cycle cycle = groupDefinition.getCycle();
+    groupDefinitionEntity.setNumberOfMeetings(cycle.getNumberOfMeetings());
+    groupDefinitionEntity.setFrequency(cycle.getFrequency());
+    groupDefinitionEntity.setAdjustment(cycle.getAdjustment());
+    groupDefinitionEntity.setCreatedBy(UserContextHolder.checkedGetUser());
+    groupDefinitionEntity.setCreatedOn(LocalDateTime.now(Clock.systemUTC()));
+    this.groupDefinitionRepository.save(groupDefinitionEntity);
+
+    return groupDefinition.getIdentifier();
+  }
+
+  @Transactional
+  @CommandHandler
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.POST_GROUP)
+  public String createGroup(final CreateGroupCommand createGroupCommand) {
+    final Group group = createGroupCommand.group();
+    final GroupDefinitionEntity groupDefinitionEntity =
+        this.groupDefinitionRepository.findByIdentifier(group.getGroupDefinitionIdentifier())
+            .orElseThrow(
+                () -> ServiceException.notFound("Group definition {0} not found.", group.getGroupDefinitionIdentifier())
+            );
+
+    final AddressEntity savedAddress = this.addressRepository.save(AddressMapper.map(group.getAddress()));
+
+    final GroupEntity groupEntity = new GroupEntity();
+    groupEntity.setGroupDefinition(groupDefinitionEntity);
+    groupEntity.setIdentifier(group.getIdentifier());
+    groupEntity.setName(group.getName());
+    groupEntity.setLeaders(StringUtils.collectionToCommaDelimitedString(group.getLeaders()));
+    groupEntity.setMembers(StringUtils.collectionToCommaDelimitedString(group.getMembers()));
+    groupEntity.setOffice(group.getOffice());
+    groupEntity.setAddressEntity(savedAddress);
+    groupEntity.setAssignedEmployee(group.getAssignedEmployee());
+    groupEntity.setWeekday(group.getWeekday());
+    groupEntity.setGroupStatus(Group.Status.PENDING.name());
+    groupEntity.setCreatedBy(UserContextHolder.checkedGetUser());
+    groupEntity.setCreatedOn(LocalDateTime.now(Clock.systemUTC()));
+    this.groupRepository.save(groupEntity);
+    return group.getIdentifier();
+  }
+
+  @Transactional
+  @CommandHandler
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.ACTIVATE_GROUP)
+  public String activateGroup(final ActivateGroupCommand activateGroupCommand) {
+    this.groupRepository.findByIdentifier(activateGroupCommand.identifier())
+        .ifPresent(groupEntity -> {
+          final GroupEntity savedGroupEntity = this.processCommandInternally(groupEntity, activateGroupCommand.groupCommand());
+          this.createMeetingSchedule(groupEntity.getGroupDefinition(), savedGroupEntity);
+        });
+    return activateGroupCommand.identifier();
+  }
+
+  @Transactional
+  @CommandHandler
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.CLOSE_GROUP)
+  public String closeGroup(final CloseGroupCommand closeGroupCommand) {
+    this.groupRepository.findByIdentifier(closeGroupCommand.identifier())
+        .ifPresent(groupEntity -> {
+          final List<MeetingEntity> currentMeetings =
+              this.meetingRepository.findByGroupEntityAndCurrentCycleOrderByMeetingSequenceDesc(groupEntity, groupEntity.getCurrentCycle());
+          if (currentMeetings.stream().anyMatch(meetingEntity -> meetingEntity.getHeldOn() == null)) {
+            throw ServiceException.conflict("Not all meetings for group {0} signed off.", closeGroupCommand.identifier());
+          }
+          this.processCommandInternally(groupEntity, closeGroupCommand.groupCommand());
+        });
+    return closeGroupCommand.identifier();
+  }
+
+  @Transactional
+  @CommandHandler
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.REOPEN_GROUP)
+  public String reopenGroup(final ReopenGroupCommand reopenGroupCommand) {
+    this.groupRepository.findByIdentifier(reopenGroupCommand.identifier())
+        .ifPresent(groupEntity -> {
+          final GroupEntity savedGroupEntity = this.processCommandInternally(groupEntity, reopenGroupCommand.groupCommand());
+          this.createMeetingSchedule(groupEntity.getGroupDefinition(), savedGroupEntity);
+        });
+    return reopenGroupCommand.identifier();
+  }
+
+  @Transactional
+  @CommandHandler
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_GROUP)
+  public String updateLeaders(final UpdateLeadersCommand updateLeadersCommand) {
+    this.groupRepository.findByIdentifier(updateLeadersCommand.identifier())
+        .ifPresent(groupEntity -> {
+          groupEntity.setLeaders(StringUtils.collectionToCommaDelimitedString(updateLeadersCommand.customerIdentifiers()));
+          groupEntity.setLastModifiedBy(UserContextHolder.checkedGetUser());
+          groupEntity.setLastModifiedOn(LocalDateTime.now(Clock.systemUTC()));
+          this.groupRepository.save(groupEntity);
+        });
+    return updateLeadersCommand.identifier();
+  }
+
+  @Transactional
+  @CommandHandler
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_GROUP)
+  public String updateMembers(final UpdateMembersCommand updateMembersCommand) {
+    this.groupRepository.findByIdentifier(updateMembersCommand.identifier())
+        .ifPresent(groupEntity -> {
+          groupEntity.setMembers(StringUtils.collectionToCommaDelimitedString(updateMembersCommand.customerIdentifiers()));
+          groupEntity.setLastModifiedBy(UserContextHolder.checkedGetUser());
+          groupEntity.setLastModifiedOn(LocalDateTime.now(Clock.systemUTC()));
+          this.groupRepository.save(groupEntity);
+        });
+    return updateMembersCommand.identifier();
+  }
+
+  @Transactional
+  @CommandHandler
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_GROUP)
+  public String updateAssignedEmployee(final UpdateAssignedEmployeeCommand updateAssignedEmployeeCommand) {
+    this.groupRepository.findByIdentifier(updateAssignedEmployeeCommand.identifier())
+        .ifPresent(groupEntity -> {
+          groupEntity.setAssignedEmployee(updateAssignedEmployeeCommand.employeeIdentifier());
+          groupEntity.setLastModifiedBy(UserContextHolder.checkedGetUser());
+          groupEntity.setLastModifiedOn(LocalDateTime.now(Clock.systemUTC()));
+          this.groupRepository.save(groupEntity);
+        });
+    return updateAssignedEmployeeCommand.identifier();
+  }
+
+  @Transactional
+  @CommandHandler
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_GROUP)
+  public String signOffMeeting(final SignOffMeetingCommand signOffMeetingCommand) {
+    this.groupRepository.findByIdentifier(signOffMeetingCommand.groupIdentifier())
+        .ifPresent(groupEntity -> {
+          final SignOffMeeting signOffMeeting = signOffMeetingCommand.signOffMeeting();
+          this.meetingRepository
+              .findByGroupEntityAndCurrentCycleAndMeetingSequence(groupEntity,
+                  signOffMeeting.getCycle(), signOffMeeting.getSequence())
+              .ifPresent(meetingEntity -> {
+                meetingEntity.setDuration(signOffMeeting.getDuration());
+                meetingEntity.setHeldOn(LocalDate.now(Clock.systemUTC()));
+                this.meetingRepository.save(meetingEntity);
+
+                final List<AttendeeEntity> attendeeEntities = this.attendeeRepository.findByMeeting(meetingEntity);
+                attendeeEntities.forEach(attendeeEntity -> signOffMeeting.getAttendees()
+                    .stream()
+                    .filter(attendee -> attendee.getCustomerIdentifier().equals(attendeeEntity.getCustomerIdentifier()))
+                    .findFirst()
+                    .ifPresent(attendee -> {
+                      attendeeEntity.setStatus(attendee.getStatus());
+                      this.attendeeRepository.save(attendeeEntity);
+                }));
+              });
+        });
+    return signOffMeetingCommand.groupIdentifier();
+  }
+
+  private void createMeetingSchedule(final GroupDefinitionEntity groupDefinitionEntity, final GroupEntity groupEntity) {
+    final Integer numberOfMeetings = groupDefinitionEntity.getNumberOfMeetings();
+    final Cycle.Frequency frequency = Cycle.Frequency.valueOf(groupDefinitionEntity.getFrequency());
+    final Cycle.Adjustment adjustment = Cycle.Adjustment.valueOf(groupDefinitionEntity.getAdjustment());
+    final Group.Weekday weekday = Group.Weekday.from(groupEntity.getWeekday());
+
+    final Set<String> members = StringUtils.commaDelimitedListToSet(groupEntity.getMembers());
+
+    LocalDate meeting = LocalDate.now(Clock.systemUTC());
+    if (frequency != Cycle.Frequency.DAILY) {
+      meeting = meeting.with(ChronoField.DAY_OF_WEEK, weekday.getValue());
+    }
+
+    for (int i = 0; i < numberOfMeetings; i++) {
+      switch (frequency) {
+        case DAILY:
+          meeting = meeting.plusDays(1L);
+          break;
+        case WEEKLY:
+          meeting = meeting.plusWeeks(1L);
+          break;
+        case FORTNIGHTLY:
+          meeting = meeting.plusWeeks(2L);
+          break;
+        case MONTHLY:
+          meeting.plusMonths(1L);
+          break;
+      }
+
+      final MeetingEntity meetingEntity = new MeetingEntity();
+      meetingEntity.setGroupEntity(groupEntity);
+      meetingEntity.setCurrentCycle(groupEntity.getCurrentCycle());
+      meetingEntity.setMeetingSequence((i + 1));
+      meetingEntity.setScheduledFor(meeting);
+      meetingEntity.setCreatedBy(UserContextHolder.checkedGetUser());
+      meetingEntity.setCreatedOn(LocalDateTime.now(Clock.systemUTC()));
+      final MeetingEntity savedMeeting = this.meetingRepository.save(meetingEntity);
+
+      this.attendeeRepository.save(
+          members
+              .stream()
+              .map(member -> {
+                final AttendeeEntity attendeeEntity = new AttendeeEntity();
+                attendeeEntity.setMeeting(savedMeeting);
+                attendeeEntity.setCustomerIdentifier(member);
+                attendeeEntity.setStatus(Attendee.Status.EXPECTED.name());
+                return attendeeEntity;
+              })
+              .collect(Collectors.toList())
+      );
+    }
+  }
+
+  private GroupEntity processCommandInternally(final GroupEntity groupEntity, final GroupCommand groupCommand) {
+    this.saveGroupCommand(groupEntity, groupCommand);
+
+    final GroupCommand.Action action = GroupCommand.Action.valueOf(groupCommand.getAction());
+    switch (action) {
+      case ACTIVATE:
+        groupEntity.setGroupStatus(Group.Status.ACTIVE.name());
+        groupEntity.setCurrentCycle(groupEntity.getCurrentCycle() + 1);
+        break;
+      case CLOSE:
+        groupEntity.setGroupStatus(Group.Status.CLOSED.name());
+        break;
+      case REOPEN:
+        groupEntity.setGroupStatus(Group.Status.PENDING.name());
+        groupEntity.setCurrentCycle(groupEntity.getCurrentCycle() + 1);
+        break;
+      default:
+        throw ServiceException.badRequest("Unsupported command {}.", action.name());
+    }
+    groupEntity.setLastModifiedBy(groupCommand.getCreatedBy());
+    groupEntity.setLastModifiedOn(DateConverter.fromIsoString(groupCommand.getCreatedOn()));
+    return this.groupRepository.save(groupEntity);
+  }
+
+  private void saveGroupCommand(final GroupEntity groupEntity, final GroupCommand groupCommand) {
+    final GroupCommandEntity groupCommandEntity = GroupCommandMapper.map(groupCommand);
+    groupCommandEntity.setGroup(groupEntity);
+    this.groupCommandRepository.save(groupCommandEntity);
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/command/handler/MigrationAggregate.java b/service/src/main/java/io/mifos/group/service/internal/command/handler/MigrationAggregate.java
new file mode 100644
index 0000000..3d93d3b
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/command/handler/MigrationAggregate.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.command.handler;
+
+import io.mifos.core.command.annotation.Aggregate;
+import io.mifos.core.command.annotation.CommandHandler;
+import io.mifos.core.command.annotation.EventEmitter;
+import io.mifos.core.mariadb.domain.FlywayFactoryBean;
+import io.mifos.group.api.v1.EventConstants;
+import io.mifos.group.service.ServiceConstants;
+import io.mifos.group.service.internal.command.InitializeServiceCommand;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.sql.DataSource;
+
+@SuppressWarnings("unused")
+@Aggregate
+public class MigrationAggregate {
+
+  private final Logger logger;
+  private final DataSource dataSource;
+  private final FlywayFactoryBean flywayFactoryBean;
+
+  @Autowired
+  public MigrationAggregate(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+                            final DataSource dataSource,
+                            final FlywayFactoryBean flywayFactoryBean) {
+    super();
+    this.logger = logger;
+    this.dataSource = dataSource;
+    this.flywayFactoryBean = flywayFactoryBean;
+  }
+
+  @Transactional
+  @CommandHandler
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.INITIALIZE)
+  public String initialize(final InitializeServiceCommand initializeServiceCommand) {
+    this.logger.debug("Start service migration.");
+    this.flywayFactoryBean.create(this.dataSource).migrate();
+    return EventConstants.INITIALIZE;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/AddressMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/AddressMapper.java
new file mode 100644
index 0000000..7ff897a
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/AddressMapper.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.mapper;
+
+import io.mifos.group.service.internal.repository.AddressEntity;
+import io.mifos.group.api.v1.domain.Address;
+
+public class AddressMapper {
+
+  private AddressMapper() {
+    super();
+  }
+
+  public static Address map(final AddressEntity addressEntity) {
+    final Address address = new Address();
+    address.setStreet(addressEntity.getStreet());
+    address.setCity(addressEntity.getCity());
+    address.setRegion(addressEntity.getRegion());
+    address.setPostalCode(addressEntity.getPostalCode());
+    address.setCountry(addressEntity.getCountry());
+    address.setCountryCode(addressEntity.getCountryCode());
+    return address;
+  }
+
+  public static AddressEntity map(final Address address) {
+    final AddressEntity addressEntity = new AddressEntity();
+    addressEntity.setStreet(address.getStreet());
+    addressEntity.setCity(address.getCity());
+    addressEntity.setRegion(address.getRegion());
+    addressEntity.setPostalCode(address.getPostalCode());
+    addressEntity.setCountry(address.getCountry());
+    addressEntity.setCountryCode(address.getCountryCode());
+    return addressEntity;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/AttendeeMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/AttendeeMapper.java
new file mode 100644
index 0000000..58cc7bb
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/AttendeeMapper.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.mapper;
+
+import io.mifos.group.api.v1.domain.Attendee;
+import io.mifos.group.service.internal.repository.AttendeeEntity;
+
+public class AttendeeMapper {
+
+  private AttendeeMapper() {
+    super();
+  }
+
+  public static Attendee map(final AttendeeEntity attendeeEntity) {
+    final Attendee attendee = new Attendee();
+    attendee.setCustomerIdentifier(attendeeEntity.getCustomerIdentifier());
+    attendee.setStatus(attendeeEntity.getStatus());
+    return attendee;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupCommandMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupCommandMapper.java
new file mode 100644
index 0000000..c1bbca0
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupCommandMapper.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.mapper;
+
+import io.mifos.core.api.util.UserContextHolder;
+import io.mifos.core.lang.DateConverter;
+import io.mifos.group.service.internal.repository.GroupCommandEntity;
+import io.mifos.group.api.v1.domain.GroupCommand;
+
+import java.time.Clock;
+import java.time.LocalDateTime;
+
+public class GroupCommandMapper {
+
+  private GroupCommandMapper() {
+    super();
+  }
+
+  public static GroupCommand map(final GroupCommandEntity groupCommandEntity) {
+    final GroupCommand groupCommand = new GroupCommand();
+    groupCommand.setAction(groupCommandEntity.getAction());
+    groupCommand.setNote(groupCommandEntity.getNote());
+    groupCommand.setCreatedBy(groupCommandEntity.getCreatedBy());
+    groupCommand.setCreatedOn(DateConverter.toIsoString(groupCommandEntity.getCreatedOn()));
+    return groupCommand;
+  }
+
+  public static GroupCommandEntity map(final GroupCommand groupCommand) {
+    final GroupCommandEntity groupCommandEntity = new GroupCommandEntity();
+    groupCommandEntity.setAction(groupCommand.getAction());
+    groupCommandEntity.setNote(groupCommand.getNote());
+    groupCommandEntity.setCreatedBy(UserContextHolder.checkedGetUser());
+    groupCommandEntity.setCreatedOn(LocalDateTime.now(Clock.systemUTC()));
+    return groupCommandEntity;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupDefinitionMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupDefinitionMapper.java
new file mode 100644
index 0000000..88cf2c4
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupDefinitionMapper.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.mapper;
+
+import io.mifos.core.lang.DateConverter;
+import io.mifos.group.service.internal.repository.GroupDefinitionEntity;
+import io.mifos.group.api.v1.domain.Cycle;
+import io.mifos.group.api.v1.domain.GroupDefinition;
+
+public class GroupDefinitionMapper {
+
+  private GroupDefinitionMapper() {
+    super();
+  }
+
+  public static GroupDefinition map(final GroupDefinitionEntity groupDefinitionEntity) {
+    final GroupDefinition groupDefinition = new GroupDefinition();
+    groupDefinition.setIdentifier(groupDefinitionEntity.getIdentifier());
+    groupDefinition.setDescription(groupDefinitionEntity.getDescription());
+    groupDefinition.setMinimalSize(groupDefinitionEntity.getMinimalSize());
+    groupDefinition.setMaximalSize(groupDefinitionEntity.getMaximalSize());
+    groupDefinition.setCreateOn(DateConverter.toIsoString(groupDefinitionEntity.getCreatedOn()));
+    groupDefinition.setCreatedBy(groupDefinitionEntity.getCreatedBy());
+
+    if (groupDefinitionEntity.getLastModifiedOn() != null) {
+      groupDefinition.setLastModifiedOn(DateConverter.toIsoString(groupDefinitionEntity.getLastModifiedOn()));
+      groupDefinition.setLastModifiedBy(groupDefinitionEntity.getLastModifiedBy());
+    }
+
+    final Cycle cycle = new Cycle();
+    cycle.setNumberOfMeetings(groupDefinitionEntity.getNumberOfMeetings());
+    cycle.setFrequency(groupDefinitionEntity.getFrequency());
+    cycle.setAdjustment(groupDefinitionEntity.getAdjustment());
+    groupDefinition.setCycle(cycle);
+
+    return groupDefinition;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/GroupMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupMapper.java
new file mode 100644
index 0000000..a345c2a
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/GroupMapper.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.mapper;
+
+import io.mifos.core.lang.DateConverter;
+import io.mifos.group.service.internal.repository.GroupEntity;
+import io.mifos.group.api.v1.domain.Group;
+import org.springframework.util.StringUtils;
+
+public class GroupMapper {
+
+  private GroupMapper() {
+    super();
+  }
+
+  public static Group map(final GroupEntity groupEntity) {
+    final Group group = new Group();
+    group.setIdentifier(groupEntity.getIdentifier());
+    group.setGroupDefinitionIdentifier(groupEntity.getGroupDefinition().getIdentifier());
+    group.setName(groupEntity.getName());
+    group.setLeaders(StringUtils.commaDelimitedListToSet(groupEntity.getLeaders()));
+    group.setMembers(StringUtils.commaDelimitedListToSet(groupEntity.getMembers()));
+    group.setOffice(groupEntity.getOffice());
+    group.setAssignedEmployee(groupEntity.getAssignedEmployee());
+    group.setWeekday(groupEntity.getWeekday());
+    group.setStatus(groupEntity.getGroupStatus());
+    group.setCreatedOn(DateConverter.toIsoString(groupEntity.getCreatedOn()));
+    group.setCreatedBy(groupEntity.getCreatedBy());
+    if (groupEntity.getLastModifiedOn() != null) {
+      group.setLastModifiedOn(DateConverter.toIsoString(groupEntity.getLastModifiedOn()));
+      group.setLastModifiedBy(groupEntity.getLastModifiedBy());
+    }
+    return group;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/mapper/MeetingMapper.java b/service/src/main/java/io/mifos/group/service/internal/mapper/MeetingMapper.java
new file mode 100644
index 0000000..9e67548
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/mapper/MeetingMapper.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.mapper;
+
+import io.mifos.core.lang.DateConverter;
+import io.mifos.group.api.v1.domain.Meeting;
+import io.mifos.group.service.internal.repository.MeetingEntity;
+
+public class MeetingMapper {
+
+  private MeetingMapper() {
+    super();
+  }
+
+  public static Meeting map(final MeetingEntity meetingEntity) {
+    final Meeting meeting = new Meeting();
+    meeting.setCurrentCycle(meetingEntity.getCurrentCycle());
+    meeting.setMeetingSequence(meetingEntity.getMeetingSequence());
+    meeting.setScheduledFor(DateConverter.toIsoString(meetingEntity.getScheduledFor()));
+    if (meetingEntity.getHeldOn() != null) {
+      meeting.setHeldOn(DateConverter.toIsoString(meetingEntity.getHeldOn()));
+    }
+    if (meetingEntity.getCreatedBy() != null) {
+      meeting.setCreatedBy(meetingEntity.getCreatedBy());
+      meeting.setCreatedOn(DateConverter.toIsoString(meetingEntity.getCreatedOn()));
+    }
+    meeting.setDuration(meetingEntity.getDuration());
+    return meeting;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/AddressEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/AddressEntity.java
new file mode 100644
index 0000000..f456da2
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/AddressEntity.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.repository;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "ptah_addresses")
+public class AddressEntity {
+
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "id")
+  private Long id;
+  @Column(name = "street")
+  private String street;
+  @Column(name = "city")
+  private String city;
+  @Column(name = "postal_code")
+  private String postalCode;
+  @Column(name = "region")
+  private String region;
+  @Column(name = "country_code")
+  private String countryCode;
+  @Column(name = "country")
+  private String country;
+
+  public AddressEntity() {
+    super();
+  }
+
+  public Long getId() {
+    return this.id;
+  }
+
+  public void setId(final Long id) {
+    this.id = id;
+  }
+
+  public String getStreet() {
+    return this.street;
+  }
+
+  public void setStreet(final String street) {
+    this.street = street;
+  }
+
+  public String getCity() {
+    return this.city;
+  }
+
+  public void setCity(final String city) {
+    this.city = city;
+  }
+
+  public String getPostalCode() {
+    return this.postalCode;
+  }
+
+  public void setPostalCode(final String postalCode) {
+    this.postalCode = postalCode;
+  }
+
+  public String getRegion() {
+    return this.region;
+  }
+
+  public void setRegion(final String region) {
+    this.region = region;
+  }
+
+  public String getCountryCode() {
+    return this.countryCode;
+  }
+
+  public void setCountryCode(final String countryCode) {
+    this.countryCode = countryCode;
+  }
+
+  public String getCountry() {
+    return this.country;
+  }
+
+  public void setCountry(final String country) {
+    this.country = country;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/AddressRepository.java b/service/src/main/java/io/mifos/group/service/internal/repository/AddressRepository.java
new file mode 100644
index 0000000..b3dfdfb
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/AddressRepository.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface AddressRepository extends JpaRepository<AddressEntity, Long> {
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeEntity.java
new file mode 100644
index 0000000..f0b37db
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeEntity.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.repository;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "ptah_attendees")
+public class AttendeeEntity {
+
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "id", nullable = false)
+  private Long id;
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "meeting_id", nullable = false)
+  private MeetingEntity meeting;
+  @Column(name = "customer_identifier", nullable = false)
+  private String customerIdentifier;
+  @Column(name = "a_status", nullable = false)
+  private String status;
+
+  public AttendeeEntity() {
+    super();
+  }
+
+  public Long getId() {
+    return this.id;
+  }
+
+  public void setId(final Long id) {
+    this.id = id;
+  }
+
+  public MeetingEntity getMeeting() {
+    return this.meeting;
+  }
+
+  public void setMeeting(final MeetingEntity meeting) {
+    this.meeting = meeting;
+  }
+
+  public String getCustomerIdentifier() {
+    return this.customerIdentifier;
+  }
+
+  public void setCustomerIdentifier(final String customerIdentifier) {
+    this.customerIdentifier = customerIdentifier;
+  }
+
+  public String getStatus() {
+    return this.status;
+  }
+
+  public void setStatus(final String status) {
+    this.status = status;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeRepository.java b/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeRepository.java
new file mode 100644
index 0000000..b718aa6
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/AttendeeRepository.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface AttendeeRepository extends JpaRepository<AttendeeEntity, Long> {
+
+  List<AttendeeEntity> findByMeeting(final MeetingEntity meetingEntity);
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandEntity.java
new file mode 100644
index 0000000..332c02e
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandEntity.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.repository;
+
+import io.mifos.core.mariadb.util.LocalDateTimeConverter;
+
+import javax.persistence.Column;
+import javax.persistence.Convert;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "ptah_group_commands")
+public class GroupCommandEntity {
+
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "id", nullable = false)
+  private Long id;
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "group_id", nullable = false)
+  private GroupEntity group;
+  @Column(name = "a_action")
+  private String action;
+  @Column(name = "note")
+  private String note;
+  @Column(name = "created_on", nullable = false)
+  @Convert(converter = LocalDateTimeConverter.class)
+  private LocalDateTime createdOn;
+  @Column(name = "created_by", nullable = false)
+  private String createdBy;
+
+  public GroupCommandEntity() {
+    super();
+  }
+
+  public Long getId() {
+    return this.id;
+  }
+
+  public void setId(final Long id) {
+    this.id = id;
+  }
+
+  public GroupEntity getGroup() {
+    return this.group;
+  }
+
+  public void setGroup(final GroupEntity group) {
+    this.group = group;
+  }
+
+  public String getAction() {
+    return this.action;
+  }
+
+  public void setAction(final String action) {
+    this.action = action;
+  }
+
+  public String getNote() {
+    return this.note;
+  }
+
+  public void setNote(final String note) {
+    this.note = note;
+  }
+
+  public LocalDateTime getCreatedOn() {
+    return this.createdOn;
+  }
+
+  public void setCreatedOn(final LocalDateTime createdOn) {
+    this.createdOn = createdOn;
+  }
+
+  public String getCreatedBy() {
+    return this.createdBy;
+  }
+
+  public void setCreatedBy(final String createdBy) {
+    this.createdBy = createdBy;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandRepository.java b/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandRepository.java
new file mode 100644
index 0000000..9313514
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/GroupCommandRepository.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface GroupCommandRepository extends JpaRepository<GroupCommandEntity, Long> {
+
+  List<GroupCommandEntity> findByGroup(final GroupEntity group);
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionEntity.java
new file mode 100644
index 0000000..926e832
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionEntity.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.repository;
+
+import io.mifos.core.mariadb.util.LocalDateTimeConverter;
+
+import javax.persistence.Column;
+import javax.persistence.Convert;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "ptah_group_definitions")
+public class GroupDefinitionEntity {
+
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "id", nullable = false)
+  private Long id;
+  @Column(name = "identifier", nullable = false)
+  private String identifier;
+  @Column(name = "description")
+  private String description;
+  @Column(name = "minimal_size", nullable = false)
+  private Integer minimalSize;
+  @Column(name = "maximal_size", nullable = false)
+  private Integer maximalSize;
+  @Column(name = "number_of_meetings", nullable = false)
+  private Integer numberOfMeetings;
+  @Column(name = "frequency", nullable = false)
+  private String frequency;
+  @Column(name = "adjustment")
+  private String adjustment;
+  @Column(name = "created_on", nullable = false)
+  @Convert(converter = LocalDateTimeConverter.class)
+  private LocalDateTime createdOn;
+  @Column(name = "created_by", nullable = false)
+  private String createdBy;
+  @Column(name = "last_modified_on")
+  @Convert(converter = LocalDateTimeConverter.class)
+  private LocalDateTime lastModifiedOn;
+  @Column(name = "last_modified_by")
+  private String lastModifiedBy;
+
+  public GroupDefinitionEntity() {
+    super();
+  }
+
+  public Long getId() {
+    return this.id;
+  }
+
+  public void setId(final Long id) {
+    this.id = id;
+  }
+
+  public String getIdentifier() {
+    return this.identifier;
+  }
+
+  public void setIdentifier(final String identifier) {
+    this.identifier = identifier;
+  }
+
+  public String getDescription() {
+    return this.description;
+  }
+
+  public void setDescription(final String description) {
+    this.description = description;
+  }
+
+  public Integer getMinimalSize() {
+    return this.minimalSize;
+  }
+
+  public void setMinimalSize(final Integer minimalSize) {
+    this.minimalSize = minimalSize;
+  }
+
+  public Integer getMaximalSize() {
+    return this.maximalSize;
+  }
+
+  public void setMaximalSize(final Integer maximalSize) {
+    this.maximalSize = maximalSize;
+  }
+
+  public Integer getNumberOfMeetings() {
+    return this.numberOfMeetings;
+  }
+
+  public void setNumberOfMeetings(final Integer numberOfMeetings) {
+    this.numberOfMeetings = numberOfMeetings;
+  }
+
+  public String getFrequency() {
+    return this.frequency;
+  }
+
+  public void setFrequency(final String frequency) {
+    this.frequency = frequency;
+  }
+
+  public String getAdjustment() {
+    return this.adjustment;
+  }
+
+  public void setAdjustment(final String adjustment) {
+    this.adjustment = adjustment;
+  }
+
+  public LocalDateTime getCreatedOn() {
+    return this.createdOn;
+  }
+
+  public void setCreatedOn(final LocalDateTime createdOn) {
+    this.createdOn = createdOn;
+  }
+
+  public String getCreatedBy() {
+    return this.createdBy;
+  }
+
+  public void setCreatedBy(final String createdBy) {
+    this.createdBy = createdBy;
+  }
+
+  public LocalDateTime getLastModifiedOn() {
+    return this.lastModifiedOn;
+  }
+
+  public void setLastModifiedOn(final LocalDateTime lastModifiedOn) {
+    this.lastModifiedOn = lastModifiedOn;
+  }
+
+  public String getLastModifiedBy() {
+    return this.lastModifiedBy;
+  }
+
+  public void setLastModifiedBy(final String lastModifiedBy) {
+    this.lastModifiedBy = lastModifiedBy;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionRepository.java b/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionRepository.java
new file mode 100644
index 0000000..e274b95
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/GroupDefinitionRepository.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public interface GroupDefinitionRepository extends JpaRepository<GroupDefinitionEntity, Long> {
+
+  Optional<GroupDefinitionEntity> findByIdentifier(final String identifier);
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/GroupEntity.java
new file mode 100644
index 0000000..da5a423
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/GroupEntity.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.repository;
+
+import io.mifos.core.mariadb.util.LocalDateTimeConverter;
+
+import javax.persistence.Column;
+import javax.persistence.Convert;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "ptah_groups")
+public class GroupEntity {
+
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "id", nullable = false)
+  private Long id;
+  @Column(name = "identifier", nullable = false)
+  private String identifier;
+  @ManyToOne(fetch = FetchType.EAGER)
+  @JoinColumn(name = "group_definition_id", nullable = false)
+  private GroupDefinitionEntity groupDefinition;
+  @Column(name = "a_name", nullable = false)
+  private String name;
+  @Column(name = "leaders")
+  private String leaders;
+  @Column(name = "members", nullable = false)
+  private String members;
+  @Column(name = "office", nullable = false)
+  private String office;
+  @OneToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "address_id", nullable = false)
+  private AddressEntity addressEntity;
+  @Column(name = "assigned_employee", nullable = false)
+  private String assignedEmployee;
+  @Column(name = "weekday", nullable = false)
+  private Integer weekday;
+  @Column(name = "group_status", nullable = false)
+  private String groupStatus;
+  @Column(name = "current_cycle", nullable = false)
+  private Integer currentCycle = Integer.valueOf(0);
+  @Column(name = "created_on", nullable = false)
+  @Convert(converter = LocalDateTimeConverter.class)
+  private LocalDateTime createdOn;
+  @Column(name = "created_by", nullable = false)
+  private String createdBy;
+  @Column(name = "last_modified_on")
+  @Convert(converter = LocalDateTimeConverter.class)
+  private LocalDateTime lastModifiedOn;
+  @Column(name = "last_modified_by")
+  private String lastModifiedBy;
+
+  public GroupEntity() {
+    super();
+  }
+
+  public Long getId() {
+    return this.id;
+  }
+
+  public void setId(final Long id) {
+    this.id = id;
+  }
+
+  public String getIdentifier() {
+    return this.identifier;
+  }
+
+  public void setIdentifier(final String identifier) {
+    this.identifier = identifier;
+  }
+
+  public GroupDefinitionEntity getGroupDefinition() {
+    return this.groupDefinition;
+  }
+
+  public void setGroupDefinition(final GroupDefinitionEntity groupDefinition) {
+    this.groupDefinition = groupDefinition;
+  }
+
+  public String getName() {
+    return this.name;
+  }
+
+  public void setName(final String name) {
+    this.name = name;
+  }
+
+  public String getLeaders() {
+    return this.leaders;
+  }
+
+  public void setLeaders(final String leaders) {
+    this.leaders = leaders;
+  }
+
+  public String getMembers() {
+    return this.members;
+  }
+
+  public void setMembers(final String members) {
+    this.members = members;
+  }
+
+  public String getOffice() {
+    return this.office;
+  }
+
+  public void setOffice(final String office) {
+    this.office = office;
+  }
+
+  public String getAssignedEmployee() {
+    return this.assignedEmployee;
+  }
+
+  public void setAssignedEmployee(final String assignedEmployee) {
+    this.assignedEmployee = assignedEmployee;
+  }
+
+  public AddressEntity getAddressEntity() {
+    return this.addressEntity;
+  }
+
+  public void setAddressEntity(final AddressEntity addressEntity) {
+    this.addressEntity = addressEntity;
+  }
+
+  public Integer getWeekday() {
+    return this.weekday;
+  }
+
+  public void setWeekday(final Integer weekday) {
+    this.weekday = weekday;
+  }
+
+  public String getGroupStatus() {
+    return this.groupStatus;
+  }
+
+  public void setGroupStatus(final String groupStatus) {
+    this.groupStatus = groupStatus;
+  }
+
+  public Integer getCurrentCycle() {
+    return this.currentCycle;
+  }
+
+  public void setCurrentCycle(final Integer currentCycle) {
+    this.currentCycle = currentCycle;
+  }
+
+  public LocalDateTime getCreatedOn() {
+    return this.createdOn;
+  }
+
+  public void setCreatedOn(final LocalDateTime createdOn) {
+    this.createdOn = createdOn;
+  }
+
+  public String getCreatedBy() {
+    return this.createdBy;
+  }
+
+  public void setCreatedBy(final String createdBy) {
+    this.createdBy = createdBy;
+  }
+
+  public LocalDateTime getLastModifiedOn() {
+    return this.lastModifiedOn;
+  }
+
+  public void setLastModifiedOn(final LocalDateTime lastModifiedOn) {
+    this.lastModifiedOn = lastModifiedOn;
+  }
+
+  public String getLastModifiedBy() {
+    return this.lastModifiedBy;
+  }
+
+  public void setLastModifiedBy(final String lastModifiedBy) {
+    this.lastModifiedBy = lastModifiedBy;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/GroupRepository.java b/service/src/main/java/io/mifos/group/service/internal/repository/GroupRepository.java
new file mode 100644
index 0000000..7398865
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/GroupRepository.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.repository;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public interface GroupRepository extends JpaRepository<GroupEntity, Long> {
+
+  Optional<GroupEntity> findByIdentifier(final String identifier);
+
+  Page<GroupEntity> findByAssignedEmployee(final String employee, final Pageable pageable);
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/MeetingEntity.java b/service/src/main/java/io/mifos/group/service/internal/repository/MeetingEntity.java
new file mode 100644
index 0000000..2733c5a
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/MeetingEntity.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.repository;
+
+import io.mifos.core.mariadb.util.LocalDateConverter;
+import io.mifos.core.mariadb.util.LocalDateTimeConverter;
+
+import javax.persistence.Column;
+import javax.persistence.Convert;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "ptah_meetings")
+public class MeetingEntity {
+
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "id", nullable = false)
+  private Long id;
+  @Column(name = "meeting_sequence", nullable = false)
+  private Integer meetingSequence;
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "group_id", nullable = false)
+  private GroupEntity groupEntity;
+  @Column(name = "current_cycle", nullable = false)
+  private Integer currentCycle;
+  @Column(name = "scheduled_for", nullable = false)
+  @Convert(converter = LocalDateConverter.class)
+  private LocalDate scheduledFor;
+  @Column(name = "held_on", nullable = true)
+  @Convert(converter = LocalDateConverter.class)
+  private LocalDate heldOn;
+  @Column(name = "duration", nullable = true)
+  private Long duration;
+  @Column(name = "created_on", nullable = false)
+  @Convert(converter = LocalDateTimeConverter.class)
+  private LocalDateTime createdOn;
+  @Column(name = "created_by", nullable = false)
+  private String createdBy;
+
+  public MeetingEntity() {
+    super();
+  }
+
+  public Long getId() {
+    return this.id;
+  }
+
+  public void setId(final Long id) {
+    this.id = id;
+  }
+
+  public Integer getMeetingSequence() {
+    return this.meetingSequence;
+  }
+
+  public void setMeetingSequence(final Integer meetingSequence) {
+    this.meetingSequence = meetingSequence;
+  }
+
+  public GroupEntity getGroupEntity() {
+    return this.groupEntity;
+  }
+
+  public void setGroupEntity(final GroupEntity groupEntity) {
+    this.groupEntity = groupEntity;
+  }
+
+  public Integer getCurrentCycle() {
+    return this.currentCycle;
+  }
+
+  public void setCurrentCycle(final Integer currentCycle) {
+    this.currentCycle = currentCycle;
+  }
+
+  public LocalDate getScheduledFor() {
+    return this.scheduledFor;
+  }
+
+  public void setScheduledFor(final LocalDate scheduledFor) {
+    this.scheduledFor = scheduledFor;
+  }
+
+  public LocalDate getHeldOn() {
+    return this.heldOn;
+  }
+
+  public void setHeldOn(final LocalDate heldOn) {
+    this.heldOn = heldOn;
+  }
+
+  public Long getDuration() {
+    return this.duration;
+  }
+
+  public void setDuration(final Long duration) {
+    this.duration = duration;
+  }
+
+  public LocalDateTime getCreatedOn() {
+    return this.createdOn;
+  }
+
+  public void setCreatedOn(final LocalDateTime createdOn) {
+    this.createdOn = createdOn;
+  }
+
+  public String getCreatedBy() {
+    return this.createdBy;
+  }
+
+  public void setCreatedBy(final String createdBy) {
+    this.createdBy = createdBy;
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/repository/MeetingRepository.java b/service/src/main/java/io/mifos/group/service/internal/repository/MeetingRepository.java
new file mode 100644
index 0000000..6875ba7
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/repository/MeetingRepository.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.repository;
+
+import io.mifos.core.mariadb.util.LocalDateConverter;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.Convert;
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Optional;
+
+@Repository
+public interface MeetingRepository extends JpaRepository<MeetingEntity, Long> {
+
+  @Convert(converter = LocalDateConverter.class)
+  List<MeetingEntity> findTopByGroupEntityAndScheduledForAfter(final GroupEntity groupEntity, final LocalDate date);
+
+  List<MeetingEntity> findByGroupEntityAndCurrentCycleOrderByMeetingSequenceDesc(
+      final GroupEntity groupEntity, final Integer currentCycle);
+
+  List<MeetingEntity> findByGroupEntityOrderByCurrentCycleDescMeetingSequenceDesc(final GroupEntity groupEntity);
+
+  Optional<MeetingEntity> findByGroupEntityAndCurrentCycleAndMeetingSequence(final GroupEntity groupEntity, final Integer cycle, final Integer sequence);
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/service/GroupDefinitionService.java b/service/src/main/java/io/mifos/group/service/internal/service/GroupDefinitionService.java
new file mode 100644
index 0000000..2bc03cb
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/service/GroupDefinitionService.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.service;
+
+import io.mifos.group.api.v1.domain.GroupDefinition;
+import io.mifos.group.service.ServiceConstants;
+import io.mifos.group.service.internal.mapper.GroupDefinitionMapper;
+import io.mifos.group.service.internal.repository.GroupDefinitionRepository;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+@Service
+public class GroupDefinitionService {
+
+  private final Logger logger;
+  private final GroupDefinitionRepository groupDefinitionRepository;
+
+  @Autowired
+  public GroupDefinitionService(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+                                final GroupDefinitionRepository groupDefinitionRepository) {
+    super();
+    this.logger = logger;
+    this.groupDefinitionRepository = groupDefinitionRepository;
+  }
+
+  public Optional<GroupDefinition> findByIdentifier(final String identifier) {
+    return this.groupDefinitionRepository.findByIdentifier(identifier).map(GroupDefinitionMapper::map);
+  }
+
+  public List<GroupDefinition> fetchAllGroupDefinitions() {
+    return this.groupDefinitionRepository.findAll()
+        .stream()
+        .map(GroupDefinitionMapper::map)
+        .collect(Collectors.toList());
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/internal/service/GroupService.java b/service/src/main/java/io/mifos/group/service/internal/service/GroupService.java
new file mode 100644
index 0000000..76ce37e
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/internal/service/GroupService.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.internal.service;
+
+import io.mifos.core.lang.ServiceException;
+import io.mifos.group.service.internal.repository.AttendeeRepository;
+import io.mifos.group.service.internal.repository.GroupRepository;
+import io.mifos.group.api.v1.domain.Group;
+import io.mifos.group.api.v1.domain.GroupCommand;
+import io.mifos.group.api.v1.domain.GroupPage;
+import io.mifos.group.api.v1.domain.Meeting;
+import io.mifos.group.service.ServiceConstants;
+import io.mifos.group.service.internal.mapper.AddressMapper;
+import io.mifos.group.service.internal.mapper.AttendeeMapper;
+import io.mifos.group.service.internal.mapper.GroupCommandMapper;
+import io.mifos.group.service.internal.mapper.GroupMapper;
+import io.mifos.group.service.internal.mapper.MeetingMapper;
+import io.mifos.group.service.internal.repository.GroupCommandRepository;
+import io.mifos.group.service.internal.repository.GroupEntity;
+import io.mifos.group.service.internal.repository.MeetingEntity;
+import io.mifos.group.service.internal.repository.MeetingRepository;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+import java.time.Clock;
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+@Service
+public class GroupService {
+
+  private final Logger logger;
+  private final GroupRepository groupRepository;
+  private final GroupCommandRepository groupCommandRepository;
+  private final MeetingRepository meetingRepository;
+  private final AttendeeRepository attendeeRepository;
+
+  @Autowired
+  public GroupService(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+                      final GroupRepository groupRepository,
+                      final GroupCommandRepository groupCommandRepository,
+                      final MeetingRepository meetingRepository,
+                      final AttendeeRepository attendeeRepository) {
+    super();
+    this.logger = logger;
+    this.groupRepository = groupRepository;
+    this.groupCommandRepository = groupCommandRepository;
+    this.meetingRepository = meetingRepository;
+    this.attendeeRepository = attendeeRepository;
+  }
+
+  public Optional<Group> findByIdentifier(final String identifier) {
+    final Optional<GroupEntity> optionalGroup = this.groupRepository.findByIdentifier(identifier);
+    if (optionalGroup.isPresent()) {
+      final GroupEntity groupEntity = optionalGroup.get();
+      final Group group = GroupMapper.map(groupEntity);
+      group.setAddress(AddressMapper.map(groupEntity.getAddressEntity()));
+      return Optional.of(group);
+    } else {
+      return Optional.empty();
+    }
+  }
+
+  public GroupPage fetchGroups(final String employee, final Pageable pageable) {
+    final Page<GroupEntity> page;
+    if (employee != null) {
+      page = this.groupRepository.findByAssignedEmployee(employee, pageable);
+    } else {
+      page = this.groupRepository.findAll(pageable);
+    }
+
+    final GroupPage groupPage = new GroupPage();
+    groupPage.setGroups(page.map(GroupMapper::map).getContent());
+    groupPage.setTotalPages(page.getTotalPages());
+    groupPage.setTotalElements(page.getTotalElements());
+
+    return groupPage;
+  }
+
+  public List<GroupCommand> findCommandsByIdentifier(final String identifier) {
+    final GroupEntity groupEntity =
+        this.groupRepository.findByIdentifier(identifier)
+            .orElseThrow(() -> ServiceException.notFound("Group {0} not found.", identifier));
+    return this.groupCommandRepository.findByGroup(groupEntity)
+        .stream()
+        .map(GroupCommandMapper::map)
+        .collect(Collectors.toList());
+  }
+
+  public List<Meeting> findMeetings(final String identifier, final Boolean upcoming) {
+    final GroupEntity groupEntity = this.groupRepository.findByIdentifier(identifier)
+        .orElseThrow(() -> ServiceException.notFound("Group {0} not found.", identifier));
+
+    final List<MeetingEntity> meetings;
+    if (upcoming) {
+      meetings = this.meetingRepository.findTopByGroupEntityAndScheduledForAfter(groupEntity, LocalDate.now(Clock.systemUTC()));
+    } else {
+      meetings = this.meetingRepository.findByGroupEntityOrderByCurrentCycleDescMeetingSequenceDesc(groupEntity);
+    }
+
+    return meetings
+        .stream()
+        .map(meetingEntity -> {
+          final Meeting meeting = MeetingMapper.map(meetingEntity);
+          meeting.setGroupIdentifier(groupEntity.getIdentifier());
+          meeting.setAttendees(
+              this.attendeeRepository.findByMeeting(meetingEntity)
+                  .stream().map(AttendeeMapper::map).collect(Collectors.toSet())
+          );
+          meeting.setLocation(AddressMapper.map(groupEntity.getAddressEntity()));
+          return meeting;
+        })
+        .collect(Collectors.toList());
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/rest/GroupDefinitionRestController.java b/service/src/main/java/io/mifos/group/service/rest/GroupDefinitionRestController.java
new file mode 100644
index 0000000..7b78586
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/rest/GroupDefinitionRestController.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.rest;
+
+import io.mifos.anubis.annotation.AcceptedTokenType;
+import io.mifos.anubis.annotation.Permittable;
+import io.mifos.core.command.gateway.CommandGateway;
+import io.mifos.core.lang.ServiceException;
+import io.mifos.group.service.ServiceConstants;
+import io.mifos.group.service.internal.command.CreateGroupDefinitionCommand;
+import io.mifos.group.service.internal.service.GroupDefinitionService;
+import io.mifos.group.api.v1.domain.GroupDefinition;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+
+@RestController
+@RequestMapping("/definitions")
+public class GroupDefinitionRestController {
+
+  private final Logger logger;
+  private final CommandGateway commandGateway;
+  private final GroupDefinitionService groupDefinitionService;
+
+  @Autowired
+  public GroupDefinitionRestController(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+                                       final CommandGateway commandGateway,
+                                       final GroupDefinitionService groupDefinitionService) {
+    super();
+    this.logger = logger;
+    this.commandGateway = commandGateway;
+    this.groupDefinitionService = groupDefinitionService;
+  }
+
+  @Permittable(AcceptedTokenType.TENANT)
+  @RequestMapping(
+      method = RequestMethod.POST,
+      consumes = MediaType.APPLICATION_JSON_VALUE,
+      produces = MediaType.APPLICATION_JSON_VALUE
+  )
+  public
+  @ResponseBody
+  ResponseEntity<Void> createDefinition(@RequestBody @Valid final GroupDefinition groupDefinition) {
+    this.groupDefinitionService.findByIdentifier(groupDefinition.getIdentifier())
+        .ifPresent(gd -> {
+          throw ServiceException.conflict("Group definition {0} already exists.", gd.getIdentifier());
+        });
+
+    this.commandGateway.process(new CreateGroupDefinitionCommand(groupDefinition));
+    return ResponseEntity.accepted().build();
+  }
+
+  @Permittable(AcceptedTokenType.TENANT)
+  @RequestMapping(
+      method = RequestMethod.GET,
+      consumes = MediaType.ALL_VALUE,
+      produces = MediaType.APPLICATION_JSON_VALUE
+  )
+  public
+  @ResponseBody
+  ResponseEntity<List<GroupDefinition>> fetchAllGroupDefinitions() {
+    return ResponseEntity.ok(this.groupDefinitionService.fetchAllGroupDefinitions());
+  }
+
+  @Permittable(AcceptedTokenType.TENANT)
+  @RequestMapping(
+      value = "/{identifier}",
+      method = RequestMethod.GET,
+      consumes = MediaType.ALL_VALUE,
+      produces = MediaType.APPLICATION_JSON_VALUE
+  )
+  public
+  @ResponseBody
+  ResponseEntity<GroupDefinition> findGroupDefinitionByIdentifier(
+      @PathVariable("identifier") final String identifier) {
+    return this.groupDefinitionService.findByIdentifier(identifier)
+        .map(ResponseEntity::ok)
+        .orElseThrow(() -> ServiceException.notFound("Group definition {0} not found.", identifier));
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/rest/GroupRestController.java b/service/src/main/java/io/mifos/group/service/rest/GroupRestController.java
new file mode 100644
index 0000000..7aad78b
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/rest/GroupRestController.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.rest;
+
+import io.mifos.anubis.annotation.AcceptedTokenType;
+import io.mifos.anubis.annotation.Permittable;
+import io.mifos.core.command.gateway.CommandGateway;
+import io.mifos.core.lang.ServiceException;
+import io.mifos.group.service.internal.command.SignOffMeetingCommand;
+import io.mifos.group.service.internal.command.UpdateLeadersCommand;
+import io.mifos.group.service.internal.command.UpdateMembersCommand;
+import io.mifos.group.service.internal.service.GroupDefinitionService;
+import io.mifos.group.service.internal.service.GroupService;
+import io.mifos.group.api.v1.domain.AssignedEmployeeHolder;
+import io.mifos.group.api.v1.domain.Group;
+import io.mifos.group.api.v1.domain.GroupCommand;
+import io.mifos.group.api.v1.domain.GroupPage;
+import io.mifos.group.api.v1.domain.Meeting;
+import io.mifos.group.api.v1.domain.SignOffMeeting;
+import io.mifos.group.service.ServiceConstants;
+import io.mifos.group.service.internal.command.ActivateGroupCommand;
+import io.mifos.group.service.internal.command.CloseGroupCommand;
+import io.mifos.group.service.internal.command.CreateGroupCommand;
+import io.mifos.group.service.internal.command.ReopenGroupCommand;
+import io.mifos.group.service.internal.command.UpdateAssignedEmployeeCommand;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Set;
+
+@RestController
+@RequestMapping("/groups")
+public class GroupRestController {
+
+  private final Logger logger;
+  private final CommandGateway commandGateway;
+  private final GroupService groupService;
+  private final GroupDefinitionService groupDefinitionService;
+
+
+  @Autowired
+  public GroupRestController(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+                             final CommandGateway commandGateway,
+                             final GroupService groupService,
+                             final GroupDefinitionService groupDefinitionService) {
+    super();
+    this.logger = logger;
+    this.commandGateway = commandGateway;
+    this.groupService = groupService;
+    this.groupDefinitionService = groupDefinitionService;
+  }
+
+  @Permittable(AcceptedTokenType.TENANT)
+  @RequestMapping(
+      method = RequestMethod.POST,
+      consumes = MediaType.APPLICATION_JSON_VALUE,
+      produces = MediaType.APPLICATION_JSON_VALUE
+  )
+  public
+  @ResponseBody
+  ResponseEntity<Void> createGroup(@RequestBody @Valid final Group group) {
+    this.groupService.findByIdentifier(group.getIdentifier())
+        .ifPresent(g -> {
+          throw ServiceException.conflict("Group {0} already exists.", g.getIdentifier());
+        });
+
+    if (!this.groupDefinitionService.findByIdentifier(group.getGroupDefinitionIdentifier()).isPresent()) {
+      throw ServiceException.notFound("Unknown group definition {0}.", group.getGroupDefinitionIdentifier());
+    }
+
+    this.commandGateway.process(new CreateGroupCommand(group));
+    return ResponseEntity.accepted().build();
+  }
+
+  @Permittable(AcceptedTokenType.TENANT)
+  @RequestMapping(
+      method = RequestMethod.GET,
+      consumes = MediaType.ALL_VALUE,
+      produces = MediaType.APPLICATION_JSON_VALUE
+  )
+  public
+  @ResponseBody
+  ResponseEntity<GroupPage> fetchGroups(
+      @RequestParam("employee") final String employee,
+      @RequestParam("page") final Integer page,
+      @RequestParam("size") final Integer size,
+      @RequestParam("sortColumn") final String sortColumn,
+      @RequestParam("sortDirection") final String sortDirection) {
+    return ResponseEntity.ok(
+        this.groupService.fetchGroups(employee, this.createPageRequest(page, size, sortColumn, sortDirection))
+    );
+  }
+
+  @Permittable(AcceptedTokenType.TENANT)
+  @RequestMapping(
+      value = "/{identifier}",
+      method = RequestMethod.GET,
+      consumes = MediaType.ALL_VALUE,
+      produces = MediaType.APPLICATION_JSON_VALUE
+  )
+  public
+  @ResponseBody
+  ResponseEntity<Group> findByIdentifier(@PathVariable("identifier") final String identifier) {
+    return this.groupService.findByIdentifier(identifier)
+        .map(ResponseEntity::ok)
+        .orElseThrow(() -> ServiceException.notFound("Group {0} not found.", identifier));
+  }
+
+  @RequestMapping(
+      value = "/{identifier}/commands",
+      method = RequestMethod.POST,
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  public
+  @ResponseBody
+  ResponseEntity<Void> processGroupCommand(@PathVariable("identifier") final String identifier, @RequestBody final GroupCommand groupCommand) {
+    this.groupService.findByIdentifier(identifier).orElseThrow(() -> ServiceException.notFound("Group {0} not found.", identifier));
+    final GroupCommand.Action action = GroupCommand.Action.valueOf(groupCommand.getAction());
+    switch (action) {
+      case ACTIVATE:
+        this.commandGateway.process(new ActivateGroupCommand(identifier, groupCommand));
+        break;
+      case CLOSE:
+        this.commandGateway.process(new CloseGroupCommand(identifier, groupCommand));
+        break;
+      case REOPEN:
+        this.commandGateway.process(new ReopenGroupCommand(identifier, groupCommand));
+        break;
+      default:
+        throw ServiceException.badRequest("Unsupported command {0}.", action.name());
+    }
+    return ResponseEntity.accepted().build();
+  }
+
+  @RequestMapping(
+      value = "/{identifier}/commands",
+      method = RequestMethod.GET,
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.ALL_VALUE
+  )
+  public
+  @ResponseBody
+  ResponseEntity<List<GroupCommand>> getGroupCommands(@PathVariable("identifier") final String identifier) {
+    return ResponseEntity.ok(this.groupService.findCommandsByIdentifier(identifier));
+  }
+
+  @RequestMapping(
+      value = "/{identifier}/leaders",
+      method = RequestMethod.PUT,
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  public
+  @ResponseBody
+  ResponseEntity<Void> updateLeaders(@PathVariable("identifier") final String identifier,
+                                     @RequestBody final Set<String> customerIdentifiers) {
+    this.groupService.findByIdentifier(identifier)
+        .orElseThrow(() -> ServiceException.notFound("Group {0} not found.", identifier));
+
+    this.commandGateway.process(new UpdateLeadersCommand(identifier, customerIdentifiers));
+
+    return ResponseEntity.accepted().build();
+  }
+
+  @RequestMapping(
+      value = "/{identifier}/members",
+      method = RequestMethod.PUT,
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  public
+  @ResponseBody
+  ResponseEntity<Void> updateMembers(@PathVariable("identifier") final String identifier,
+                                     @RequestBody final Set<String> customerIdentifiers) {
+    this.groupService.findByIdentifier(identifier)
+        .orElseThrow(() -> ServiceException.notFound("Group {0} not found.", identifier));
+
+    this.commandGateway.process(new UpdateMembersCommand(identifier, customerIdentifiers));
+
+    return ResponseEntity.accepted().build();
+  }
+
+  @RequestMapping(
+      value = "/{identifier}/employee",
+      method = RequestMethod.PUT,
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  public
+  @ResponseBody
+  ResponseEntity<Void> updateAssignedEmployee(@PathVariable("identifier") final String identifier,
+                                              @RequestBody final AssignedEmployeeHolder assignedEmployeeHolder) {
+
+    this.groupService.findByIdentifier(identifier)
+        .orElseThrow(() -> ServiceException.notFound("Group {0} not found.", identifier));
+
+    this.commandGateway.process(new UpdateAssignedEmployeeCommand(identifier, assignedEmployeeHolder.getIdentifier()));
+
+    return ResponseEntity.accepted().build();
+  }
+
+  @RequestMapping(
+      value = "/{identifier}/meetings",
+      method = RequestMethod.GET,
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.ALL_VALUE
+  )
+  public
+  @ResponseBody
+  ResponseEntity<List<Meeting>> fetchMeetings(@PathVariable("identifier") final String groupIdentifier,
+                                              @RequestParam(value = "upcoming", required = false, defaultValue = "false") final Boolean upcoming) {
+    this.groupService.findByIdentifier(groupIdentifier)
+        .orElseThrow(() -> ServiceException.notFound("Group {0} not found.", groupIdentifier));
+    return ResponseEntity.ok(this.groupService.findMeetings(groupIdentifier, upcoming));
+  }
+
+  @RequestMapping(
+      value = "/{identifier}/meetings",
+      method = RequestMethod.PUT,
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  public
+  ResponseEntity<Void> closeMeeting(@PathVariable("identifier") final String groupIdentifier,
+                                    @RequestBody final SignOffMeeting signOffMeeting) {
+    this.groupService.findByIdentifier(groupIdentifier)
+        .orElseThrow(() -> ServiceException.notFound("Group {0} not found.", groupIdentifier));
+
+    this.commandGateway.process(new SignOffMeetingCommand(groupIdentifier, signOffMeeting));
+    return ResponseEntity.accepted().build();
+  }
+
+  private Pageable createPageRequest(final Integer page, final Integer size, final String sortColumn, final String sortDirection) {
+    final Integer pageToUse = page != null ? page : 0;
+    final Integer sizeToUse = size != null ? size : 20;
+    final String sortColumnToUse = sortColumn != null ? sortColumn : "identifier";
+    final Sort.Direction direction = sortDirection != null ? Sort.Direction.valueOf(sortDirection.toUpperCase()) : Sort.Direction.ASC;
+    return new PageRequest(pageToUse, sizeToUse, direction, sortColumnToUse);
+  }
+}
diff --git a/service/src/main/java/io/mifos/group/service/rest/MigrationRestController.java b/service/src/main/java/io/mifos/group/service/rest/MigrationRestController.java
new file mode 100644
index 0000000..e656b2a
--- /dev/null
+++ b/service/src/main/java/io/mifos/group/service/rest/MigrationRestController.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2016 The Mifos Initiative.
+ *
+ * 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 io.mifos.group.service.rest;
+
+import io.mifos.anubis.annotation.AcceptedTokenType;
+import io.mifos.anubis.annotation.Permittable;
+import io.mifos.core.command.gateway.CommandGateway;
+import io.mifos.group.service.ServiceConstants;
+import io.mifos.group.service.internal.command.InitializeServiceCommand;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/initialize")
+public class MigrationRestController {
+
+  private final Logger logger;
+  private final CommandGateway commandGateway;
+
+  @Autowired
+  public MigrationRestController(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+                                 final CommandGateway commandGateway) {
+    super();
+    this.logger = logger;
+    this.commandGateway = commandGateway;
+  }
+
+  @Permittable(AcceptedTokenType.SYSTEM)
+  @RequestMapping(
+      method = RequestMethod.POST,
+      consumes = MediaType.ALL_VALUE,
+      produces = MediaType.APPLICATION_JSON_VALUE
+  )
+  public
+  @ResponseBody
+  ResponseEntity<Void> initialize() throws InterruptedException {
+    this.commandGateway.process(new InitializeServiceCommand());
+    return ResponseEntity.accepted().build();
+  }
+}
diff --git a/service/src/main/resources/application.yml b/service/src/main/resources/application.yml
new file mode 100644
index 0000000..fbbfa68
--- /dev/null
+++ b/service/src/main/resources/application.yml
@@ -0,0 +1,67 @@
+
+#
+# Copyright 2016 The Mifos Initiative.
+#
+# 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.
+#
+
+spring:
+  cloud:
+    discovery:
+      enabled: false
+    config:
+      enabled: false
+
+eureka:
+  client:
+    serviceUrl:
+      defaultZone: http://localhost:8761/eureka/
+
+server:
+  port: 8081
+  contextPath: /group/v1/*
+
+cassandra:
+  clusterName: staging_cluster
+  contactPoints: 127.0.0.1:9042,127.0.0.2:9042,127.0.0.3:9042
+  keyspace: seshat
+  cl:
+    read: LOCAL_QUORUM
+    write: LOCAL_QUORUM
+    delete: LOCAL_QUORUM
+
+mariadb:
+  driverClass: org.mariadb.jdbc.Driver
+  database: seshat
+  host: localhost
+  port: 3306
+  user: root
+  password: mysql
+
+bonecp:
+  idleMaxAgeInMinutes: 240
+  idleConnectionTestPeriodInMinutes: 60
+  maxConnectionsPerPartition: 10
+  minConnectionsPerPartition: 1
+  partitionCount: 2
+  acquireIncrement: 5
+  statementsCacheSize: 100
+
+async:
+  corePoolSize: 32
+  maxPoolSize: 16384
+  queueCapacity: 0
+  threadName: async-processor-
+
+flyway:
+  enabled: false
diff --git a/service/src/main/resources/bootstrap.yml b/service/src/main/resources/bootstrap.yml
new file mode 100644
index 0000000..93080e3
--- /dev/null
+++ b/service/src/main/resources/bootstrap.yml
@@ -0,0 +1,19 @@
+#
+# Copyright 2016 The Mifos Initiative.
+#
+# 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.
+#
+
+spring:
+    application:
+        name: group-api
diff --git a/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql b/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
new file mode 100644
index 0000000..ab45c4b
--- /dev/null
+++ b/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
@@ -0,0 +1,100 @@
+--
+-- Copyright 2016 The Mifos Initiative.
+--
+-- 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.
+--
+
+CREATE TABLE ptah_addresses (
+  id BIGINT NOT NULL AUTO_INCREMENT,
+  street       VARCHAR(256) NOT NULL,
+  city         VARCHAR(256) NOT NULL,
+  postal_code  VARCHAR(32) NULL,
+  region       VARCHAR(256) NULL,
+  country_code VARCHAR(2) NOT NULL,
+  country      VARCHAR(256) NOT NULL,
+  CONSTRAINT ptah_addresses_pk PRIMARY KEY (id)
+);
+
+CREATE TABLE ptah_group_definitions (
+  id                 BIGINT        NOT NULL AUTO_INCREMENT,
+  identifier         VARCHAR(32)   NOT NULL,
+  description        VARCHAR(2048) NULL,
+  minimal_size       INTEGER       NOT NULL,
+  maximal_size       INTEGER       NOT NULL,
+  number_of_meetings INTEGER       NOT NULL,
+  frequency          VARCHAR(32)   NOT NULL,
+  adjustment         VARCHAR(32)   NULL,
+  created_on         TIMESTAMP(3)  NOT NULL,
+  created_by         VARCHAR(32)   NOT NULL,
+  last_modified_on   TIMESTAMP(3)  NULL,
+  last_modified_by   VARCHAR(32)   NULL,
+  CONSTRAINT ptah_group_definitions_pk PRIMARY KEY (id),
+  CONSTRAINT ptah_group_definitions_identifier_uq UNIQUE (identifier)
+);
+
+CREATE TABLE ptah_groups (
+  id                  BIGINT        NOT NULL AUTO_INCREMENT,
+  identifier          VARCHAR(32)   NOT NULL,
+  group_definition_id BIGINT        NOT NULL,
+  a_name              VARCHAR(256)  NOT NULL,
+  leaders             VARCHAR(512)  NULL,
+  members             VARCHAR(2048) NOT NULL,
+  office              VARCHAR(32)   NOT NULL,
+  assigned_employee   VARCHAR(32)   NOT NULL,
+  weekday             INTEGER       NOT NULL,
+  group_status        VARCHAR(32)   NOT NULL,
+  current_cycle       BIGINT        NOT NULL ,
+  address_id          BIGINT        NOT NULL,
+  created_on          TIMESTAMP(3)  NOT NULL,
+  created_by          VARCHAR(32)   NOT NULL,
+  last_modified_on    TIMESTAMP(3)  NULL,
+  last_modified_by    VARCHAR(32)   NULL,
+  CONSTRAINT ptah_groups_pk PRIMARY KEY (id),
+  CONSTRAINT ptah_groups_identifier_uq UNIQUE (identifier),
+  CONSTRAINT ptah_groups_definitions_fk FOREIGN KEY (group_definition_id) REFERENCES ptah_group_definitions (id),
+  CONSTRAINT ptah_group_addresses_fk FOREIGN KEY (address_id) REFERENCES ptah_addresses (id)
+);
+
+CREATE TABLE ptah_group_commands (
+  id         BIGINT       NOT NULL AUTO_INCREMENT,
+  group_id   BIGINT       NOT NULL,
+  a_action   VARCHAR(32)  NOT NULL,
+  note       VARCHAR(256) NOT NULL,
+  created_on TIMESTAMP(3) NOT NULL,
+  created_by VARCHAR(32)  NOT NULL,
+  CONSTRAINT ptah_group_commands_pk PRIMARY KEY (id),
+  CONSTRAINT ptah_group_commands_definitions_fk FOREIGN KEY (group_id) REFERENCES ptah_groups (id)
+);
+
+CREATE TABLE ptah_meetings (
+  id               BIGINT       NOT NULL AUTO_INCREMENT,
+  group_id         BIGINT       NOT NULL,
+  meeting_sequence BIGINT       NOT NULL,
+  current_cycle    BIGINT       NOT NULL,
+  scheduled_for    DATE         NOT NULL,
+  held_on          DATE         NULL,
+  duration         BIGINT       NULL,
+  created_on       TIMESTAMP(3) NOT NULL,
+  created_by       VARCHAR(32)  NOT NULL,
+  CONSTRAINT ptah_meetings_pk PRIMARY KEY (id),
+  CONSTRAINT ptah_group_meetings_fk FOREIGN KEY (group_id) REFERENCES ptah_groups (id)
+);
+
+CREATE TABLE ptah_attendees (
+  id                  BIGINT       NOT NULL AUTO_INCREMENT,
+  meeting_id          BIGINT       NOT NULL,
+  customer_identifier VARCHAR(32)  NOT NULL,
+  a_status            VARCHAR(256) NOT NULL,
+  CONSTRAINT ptah_attendees_pk PRIMARY KEY (id),
+  CONSTRAINT ptah_meeting_attendees_fk FOREIGN KEY (meeting_id) REFERENCES ptah_attendees (id)
+);
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..c82a6db
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,5 @@
+rootProject.name = 'group'
+
+includeBuild 'api'
+includeBuild 'service'
+includeBuild 'component-test'
diff --git a/shared.gradle b/shared.gradle
new file mode 100644
index 0000000..c54ad58
--- /dev/null
+++ b/shared.gradle
@@ -0,0 +1,64 @@
+group 'io.mifos.group'
+version '0.1.0-BUILD-SNAPSHOT'
+
+ext.versions = [
+        frameworkapi : '0.1.0-BUILD-SNAPSHOT',
+        frameworklang : '0.1.0-BUILD-SNAPSHOT',
+        frameworkasync : '0.1.0-BUILD-SNAPSHOT',
+        frameworkcassandra : '0.1.0-BUILD-SNAPSHOT',
+        frameworkmariadb : '0.1.0-BUILD-SNAPSHOT',
+        frameworkcommand : '0.1.0-BUILD-SNAPSHOT',
+        frameworktest: '0.1.0-BUILD-SNAPSHOT',
+        frameworkanubis: '0.1.0-BUILD-SNAPSHOT',
+        validator  : '5.3.0.Final'
+]
+
+apply plugin: 'java'
+apply plugin: 'idea'
+apply plugin: 'maven-publish'
+apply plugin: 'io.spring.dependency-management'
+
+sourceCompatibility = JavaVersion.VERSION_1_8
+targetCompatibility = JavaVersion.VERSION_1_8
+
+repositories {
+    jcenter()
+    mavenLocal()
+}
+
+dependencyManagement {
+    imports {
+        mavenBom 'io.spring.platform:platform-bom:Athens-RELEASE'
+        mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Camden.SR1'
+    }
+}
+
+// override certain dependency provided by Spring platform using newer releases
+ext['cassandra.version'] = '3.6'
+ext['cassandra-driver.version'] = '3.1.2'
+ext['activemq.version'] = '5.13.2'
+ext['spring-data-releasetrain.version'] = 'Gosling-SR2A'
+
+dependencies {
+    compile(
+            [group: 'com.google.code.findbugs', name: 'jsr305']
+    )
+
+    testCompile(
+            [group: 'org.springframework.boot', name: 'spring-boot-starter-test']
+    )
+}
+
+license {
+    header rootProject.file('../HEADER')
+    strictCheck true
+    mapping {
+        java = 'SLASHSTAR_STYLE'
+        xml = 'XML_STYLE'
+        yml = 'SCRIPT_STYLE'
+        yaml = 'SCRIPT_STYLE'
+        uxf = 'XML_STYLE'
+    }
+    ext.year = Calendar.getInstance().get(Calendar.YEAR)
+    ext.name = 'The Mifos Initiative'
+}


[fineract-cn-group] 24/40: modified requestparams in GrouprestController and some modifications in GroupDefinitionRestController

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 62c4bd0584773e11f9a703063d9fa2faa927b46d
Author: kengneruphine <ru...@gmail.com>
AuthorDate: Tue Jun 19 16:46:14 2018 +0100

    modified requestparams in GrouprestController and some modifications in GroupDefinitionRestController
---
 .gitignore                                             |  2 ++
 .../fineract/cn/group/api/v1/client/GroupManager.java  | 10 +++++-----
 .../internal/repository/GroupDefinitionRepository.java |  5 ++++-
 .../group/internal/service/GroupDefinitionService.java |  4 ++++
 .../cn/group/rest/GroupDefinitionRestController.java   | 18 ++++++++++++------
 .../fineract/cn/group/rest/GroupRestController.java    | 10 +++++-----
 6 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/.gitignore b/.gitignore
index 95274b9..5f934cb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
 .gradle
 .idea
+.project
+.settings
 **/build/
 **/target/
 
diff --git a/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupManager.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupManager.java
index b64b390..e146987 100644
--- a/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupManager.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupManager.java
@@ -93,11 +93,11 @@ public interface GroupManager {
       produces = MediaType.ALL_VALUE,
       consumes = MediaType.APPLICATION_JSON_VALUE
   )
-  GroupPage fetchGroups(@RequestParam("employee") final String employee,
-                        @RequestParam("page") final Integer page,
-                        @RequestParam("size") final Integer size,
-                        @RequestParam("sortColumn") final String sortColumn,
-                        @RequestParam("sortDirection") final String sortDirection);
+  GroupPage fetchGroups(@RequestParam(value="employee", required=false) final String employee,
+                        @RequestParam(value="page", required=false) final Integer page,
+                        @RequestParam(value="size",required=false) final Integer size,
+                        @RequestParam(value="sortColumn", required=false) final String sortColumn,
+                        @RequestParam(value="sortDirection",required=false) final String sortDirection);
 
   @RequestMapping(
       value = "/groups/{identifier}",
diff --git a/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupDefinitionRepository.java b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupDefinitionRepository.java
index 5bb130b..b70d029 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupDefinitionRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/repository/GroupDefinitionRepository.java
@@ -19,12 +19,15 @@
 package org.apache.fineract.cn.group.internal.repository;
 
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Repository;
 
 import java.util.Optional;
 
 @Repository
 public interface GroupDefinitionRepository extends JpaRepository<GroupDefinitionEntity, Long> {
-
+  @Query("SELECT CASE WHEN COUNT(c) > 0 THEN 'true' ELSE 'false' END FROM GroupDefinitionEntity c WHERE c.identifier = :identifier")
+  Boolean existsByIdentifier(@Param("identifier") final String identifier);
   Optional<GroupDefinitionEntity> findByIdentifier(final String identifier);
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/group/internal/service/GroupDefinitionService.java b/service/src/main/java/org/apache/fineract/cn/group/internal/service/GroupDefinitionService.java
index 6d34e81..19f1c9d 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/internal/service/GroupDefinitionService.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/service/GroupDefinitionService.java
@@ -45,6 +45,10 @@ public class GroupDefinitionService {
     this.groupDefinitionRepository = groupDefinitionRepository;
   }
 
+  public Boolean groupDefinitionExists(final String identifier) {
+    return this.groupDefinitionRepository.existsByIdentifier(identifier);
+  }
+
   public Optional<GroupDefinition> findByIdentifier(final String identifier) {
     return this.groupDefinitionRepository.findByIdentifier(identifier).map(GroupDefinitionMapper::map);
   }
diff --git a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
index 1250560..8874e76 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupDefinitionRestController.java
@@ -68,13 +68,19 @@ public class GroupDefinitionRestController {
   public
   @ResponseBody
   ResponseEntity<Void> createDefinition(@RequestBody @Valid final GroupDefinition groupDefinition) {
-    this.groupDefinitionService.findByIdentifier(groupDefinition.getIdentifier())
-        .ifPresent(gd -> {
-          throw ServiceException.conflict("Group definition {0} already exists.", gd.getIdentifier());
-        });
-
-    this.commandGateway.process(new CreateGroupDefinitionCommand(groupDefinition));
+    if (this.groupDefinitionService.groupDefinitionExists(groupDefinition.getIdentifier())) {
+      throw ServiceException.conflict("Group definition {0} already exists.", groupDefinition.getIdentifier());
+    }
+      this.commandGateway.process(new CreateGroupDefinitionCommand(groupDefinition));
     return ResponseEntity.accepted().build();
+
+//    this.groupDefinitionService.findByIdentifier(groupDefinition.getIdentifier())
+//        .ifPresent(gd -> {
+//          throw ServiceException.conflict("Group definition {0} already exists.", gd.getIdentifier());
+//        });
+//
+//    this.commandGateway.process(new CreateGroupDefinitionCommand(groupDefinition));
+//    return ResponseEntity.accepted().build();
   }
 
   @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEFINITION)
diff --git a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupRestController.java b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupRestController.java
index ee0e55e..0db02d0 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupRestController.java
@@ -112,11 +112,11 @@ public class GroupRestController {
   public
   @ResponseBody
   ResponseEntity<GroupPage> fetchGroups(
-      @RequestParam("employee") final String employee,
-      @RequestParam("page") final Integer page,
-      @RequestParam("size") final Integer size,
-      @RequestParam("sortColumn") final String sortColumn,
-      @RequestParam("sortDirection") final String sortDirection) {
+      @RequestParam(value="employee",required=false) final String employee,
+      @RequestParam(value="page", required=false) final Integer page,
+      @RequestParam(value="size",required=false) final Integer size,
+      @RequestParam(value="sortColumn",required=false) final String sortColumn,
+      @RequestParam(value="sortDirection", required=false) final String sortDirection) {
     return ResponseEntity.ok(
         this.groupService.fetchGroups(employee, this.createPageRequest(page, size, sortColumn, sortDirection))
     );


[fineract-cn-group] 40/40: Merge pull request #10 from aasaru/artifactory

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 91baf565eaa8cb07f86d3a5958defb906be89854
Merge: 3fa8488 1af5beb
Author: Awasum Yannick <aw...@apache.org>
AuthorDate: Tue Apr 30 09:24:30 2019 +0100

    Merge pull request #10 from aasaru/artifactory
    
    FINCN-148 build with travis-ci.com and upload artifacts to Artifactory

 .travis.yml                 | 30 +++++++++++++++++++
 README.md                   |  2 +-
 api/build.gradle            |  3 +-
 build.gradle                | 10 ++++++-
 component-test/build.gradle |  6 ++--
 service/build.gradle        |  5 ++--
 shared.gradle               | 17 +++++++++++
 travis.sh                   | 71 +++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 137 insertions(+), 7 deletions(-)


[fineract-cn-group] 19/40: Document the Group API

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 892d1db2bd6c55a8c57d9f9053800128fc5d0979
Author: Isaac Kamga <u2...@gmail.com>
AuthorDate: Mon Apr 23 17:23:59 2018 +0100

    Document the Group API
---
 service/build.gradle                               |  20 +-
 service/src/doc/asciidoc/api-docs.adoc             |  89 +++
 .../curl-request.adoc                              |   4 +
 .../http-request.adoc                              |  10 +
 .../http-response.adoc                             |   5 +
 .../httpie-request.adoc                            |   4 +
 .../should-activate-command/curl-request.adoc      |   4 +
 .../should-activate-command/http-request.adoc      |  10 +
 .../should-activate-command/http-response.adoc     |   5 +
 .../should-activate-command/httpie-request.adoc    |   4 +
 .../should-create-group/curl-request.adoc          |   4 +
 .../should-create-group/http-request.adoc          |  10 +
 .../should-create-group/http-response.adoc         |   5 +
 .../should-create-group/httpie-request.adoc        |   4 +
 .../curl-request.adoc                              |   4 +
 .../http-request.adoc                              |  10 +
 .../http-response.adoc                             |   5 +
 .../httpie-request.adoc                            |   4 +
 .../should-update-leaders/curl-request.adoc        |   4 +
 .../should-update-leaders/http-request.adoc        |  10 +
 .../should-update-leaders/http-response.adoc       |   5 +
 .../should-update-leaders/httpie-request.adoc      |   4 +
 .../should-update-members/curl-request.adoc        |   4 +
 .../should-update-members/http-request.adoc        |  10 +
 .../should-update-members/http-response.adoc       |   5 +
 .../should-update-members/httpie-request.adoc      |   4 +
 service/src/doc/html5/html5/api-docs.html          | 648 +++++++++++++++++++++
 .../org/apache/fineract/cn/group/TestGroup.java    | 335 +++++++++++
 .../fineract/cn/group/TestGroupDefinition.java     | 181 ++++++
 .../listener/GroupDefinitionEventListener.java     |  50 ++
 .../cn/group/listener/GroupEventListener.java      |  70 +++
 .../cn/group/listener/MigrationEventListener.java  |  50 ++
 .../cn/group/util/GroupDefinitionGenerator.java    |  44 ++
 .../fineract/cn/group/util/GroupGenerator.java     |  62 ++
 34 files changed, 1686 insertions(+), 1 deletion(-)

diff --git a/service/build.gradle b/service/build.gradle
index 11b1a51..d06cf5d 100644
--- a/service/build.gradle
+++ b/service/build.gradle
@@ -26,6 +26,7 @@ buildscript {
 
     dependencies {
         classpath ("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
+        classpath("org.asciidoctor:asciidoctor-gradle-plugin:1.5.3")
     }
 }
 
@@ -35,7 +36,7 @@ plugins {
 }
 
 apply from: '../shared.gradle'
-
+apply plugin: 'org.asciidoctor.convert'
 apply plugin: 'spring-boot'
 
 springBoot {
@@ -58,6 +59,23 @@ dependencies {
             [group: 'org.apache.fineract.cn', name: 'command', version: versions.frameworkcommand],
             [group: 'org.hibernate', name: 'hibernate-validator', version: versions.validator]
     )
+    testCompile(
+            [group: 'org.apache.fineract.cn.group', name: 'api', version: project.version],
+            [group: 'org.apache.fineract.cn', name: 'api', version: versions.frameworkapi],
+            [group: 'org.apache.fineract.cn', name: 'test', version: versions.frameworktest],
+            [group: 'org.apache.fineract.cn.anubis', name: 'test', version: versions.frameworkanubis],
+            [group: 'org.springframework.restdocs', name: 'spring-restdocs-mockmvc'],
+            [group: 'org.springframework.boot', name: 'spring-boot-starter-test'],
+            [group: 'junit', name: 'junit', version: '4.12']
+    )
+}
+
+asciidoctor {
+    sourceDir 'src/doc/asciidoc/'
+    outputDir 'src/doc/html5'
+    options backend: "html", doctype: "book"
+    attributes "source-highlighter": "highlightjs", \
+                'snippets': file('src/doc/generated-snippets/')
 }
 
 publishToMavenLocal.dependsOn bootRepackage
diff --git a/service/src/doc/asciidoc/api-docs.adoc b/service/src/doc/asciidoc/api-docs.adoc
new file mode 100644
index 0000000..0c8d64b
--- /dev/null
+++ b/service/src/doc/asciidoc/api-docs.adoc
@@ -0,0 +1,89 @@
+== Apache Fineract CN Group Management API Documentation ==
+
+== Groups ==
+
+==== Create A Group ====
+
+.curl-request
+include::{snippets}/test-group/should-create-group/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-group/should-create-group/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-group/should-create-group/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-group/should-create-group/httpie-request.adoc[]
+
+==== Activate A Group ====
+
+.curl-request
+include::{snippets}/test-group/should-activate-command/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-group/should-activate-command/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-group/should-activate-command/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-group/should-activate-command/httpie-request.adoc[]
+
+==== Update Assigned Employee ====
+
+.curl-request
+include::{snippets}/test-group/should-update-assigned-employee/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-group/should-update-assigned-employee/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-group/should-update-assigned-employee/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-group/should-update-assigned-employee/httpie-request.adoc[]
+
+==== Update Group Leaders ====
+
+.curl-request
+include::{snippets}/test-group/should-update-leaders/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-group/should-update-leaders/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-group/should-update-leaders/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-group/should-update-leaders/httpie-request.adoc[]
+
+==== Update Group Members ====
+
+.curl-request
+include::{snippets}/test-group/should-update-members/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-group/should-update-members/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-group/should-update-members/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-group/should-update-members/httpie-request.adoc[]
+
+== Group Definitions ==
+
+==== Create A Group Definition ====
+
+.curl-request
+include::{snippets}/test-group-definition/should-create-group-definition/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-group-definition/should-create-group-definition/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-group-definition/should-create-group-definition/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-group-definition/should-create-group-definition/httpie-request.adoc[]
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/curl-request.adoc b/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/curl-request.adoc
new file mode 100644
index 0000000..a6bf5fa
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/group/v1/definitions' -i -X POST -H 'Accept: */*' -H 'Content-Type: application/json' -d 'f56iUIk58phhM1kgYJpSsXjoxrIESX7K'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/http-request.adoc b/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/http-request.adoc
new file mode 100644
index 0000000..ea1512c
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/http-request.adoc
@@ -0,0 +1,10 @@
+[source,http,options="nowrap"]
+----
+POST /group/v1/definitions HTTP/1.1
+Accept: */*
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+f56iUIk58phhM1kgYJpSsXjoxrIESX7K
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/http-response.adoc b/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/httpie-request.adoc b/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/httpie-request.adoc
new file mode 100644
index 0000000..f3dda49
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group-definition/should-create-group-definition/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ echo 'f56iUIk58phhM1kgYJpSsXjoxrIESX7K' | http POST 'http://localhost:8080/group/v1/definitions' 'Accept:*/*' 'Content-Type:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-activate-command/curl-request.adoc b/service/src/doc/generated-snippets/test-group/should-activate-command/curl-request.adoc
new file mode 100644
index 0000000..f91951f
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-activate-command/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/group/v1/groups/G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6/commands' -i -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-activate-command/http-request.adoc b/service/src/doc/generated-snippets/test-group/should-activate-command/http-request.adoc
new file mode 100644
index 0000000..3a29a86
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-activate-command/http-request.adoc
@@ -0,0 +1,10 @@
+[source,http,options="nowrap"]
+----
+POST /group/v1/groups/G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6/commands HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-activate-command/http-response.adoc b/service/src/doc/generated-snippets/test-group/should-activate-command/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-activate-command/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-activate-command/httpie-request.adoc b/service/src/doc/generated-snippets/test-group/should-activate-command/httpie-request.adoc
new file mode 100644
index 0000000..baeda7e
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-activate-command/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ echo 'G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6' | http POST 'http://localhost:8080/group/v1/groups/G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6/commands' 'Accept:application/json' 'Content-Type:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-create-group/curl-request.adoc b/service/src/doc/generated-snippets/test-group/should-create-group/curl-request.adoc
new file mode 100644
index 0000000..6ed8be5
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-create-group/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/group/v1/groups' -i -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'K083BUcl4wFgwV5vfyNevzMcU5Skz3d5'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-create-group/http-request.adoc b/service/src/doc/generated-snippets/test-group/should-create-group/http-request.adoc
new file mode 100644
index 0000000..6dcda88
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-create-group/http-request.adoc
@@ -0,0 +1,10 @@
+[source,http,options="nowrap"]
+----
+POST /group/v1/groups HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+K083BUcl4wFgwV5vfyNevzMcU5Skz3d5
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-create-group/http-response.adoc b/service/src/doc/generated-snippets/test-group/should-create-group/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-create-group/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-create-group/httpie-request.adoc b/service/src/doc/generated-snippets/test-group/should-create-group/httpie-request.adoc
new file mode 100644
index 0000000..9395e0d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-create-group/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ echo 'K083BUcl4wFgwV5vfyNevzMcU5Skz3d5' | http POST 'http://localhost:8080/group/v1/groups' 'Accept:application/json' 'Content-Type:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/curl-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/curl-request.adoc
new file mode 100644
index 0000000..a61f6d5
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/group/v1/groups/KsbSd2TGf95VYynRjiZfXiUX75ahKD8v/employee' -i -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'KsbSd2TGf95VYynRjiZfXiUX75ahKD8v'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/http-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/http-request.adoc
new file mode 100644
index 0000000..0487bbe
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/http-request.adoc
@@ -0,0 +1,10 @@
+[source,http,options="nowrap"]
+----
+PUT /group/v1/groups/KsbSd2TGf95VYynRjiZfXiUX75ahKD8v/employee HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+KsbSd2TGf95VYynRjiZfXiUX75ahKD8v
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/http-response.adoc b/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/httpie-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/httpie-request.adoc
new file mode 100644
index 0000000..6a43f7c
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-update-assigned-employee/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ echo 'KsbSd2TGf95VYynRjiZfXiUX75ahKD8v' | http PUT 'http://localhost:8080/group/v1/groups/KsbSd2TGf95VYynRjiZfXiUX75ahKD8v/employee' 'Accept:application/json' 'Content-Type:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-leaders/curl-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-leaders/curl-request.adoc
new file mode 100644
index 0000000..a47e208
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-update-leaders/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/group/v1/groups/DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera/leaders' -i -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-leaders/http-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-leaders/http-request.adoc
new file mode 100644
index 0000000..b870cd0
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-update-leaders/http-request.adoc
@@ -0,0 +1,10 @@
+[source,http,options="nowrap"]
+----
+PUT /group/v1/groups/DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera/leaders HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-leaders/http-response.adoc b/service/src/doc/generated-snippets/test-group/should-update-leaders/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-update-leaders/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-leaders/httpie-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-leaders/httpie-request.adoc
new file mode 100644
index 0000000..6bbd4dc
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-update-leaders/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ echo 'DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera' | http PUT 'http://localhost:8080/group/v1/groups/DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera/leaders' 'Accept:application/json' 'Content-Type:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-members/curl-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-members/curl-request.adoc
new file mode 100644
index 0000000..25101f4
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-update-members/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/group/v1/groups/t7r2iJxzq957elzLHGdoa7JDedy2h0sQ/members' -i -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -d 't7r2iJxzq957elzLHGdoa7JDedy2h0sQ'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-members/http-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-members/http-request.adoc
new file mode 100644
index 0000000..06e9713
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-update-members/http-request.adoc
@@ -0,0 +1,10 @@
+[source,http,options="nowrap"]
+----
+PUT /group/v1/groups/t7r2iJxzq957elzLHGdoa7JDedy2h0sQ/members HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+t7r2iJxzq957elzLHGdoa7JDedy2h0sQ
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-members/http-response.adoc b/service/src/doc/generated-snippets/test-group/should-update-members/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-update-members/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-group/should-update-members/httpie-request.adoc b/service/src/doc/generated-snippets/test-group/should-update-members/httpie-request.adoc
new file mode 100644
index 0000000..c785bfc
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-group/should-update-members/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ echo 't7r2iJxzq957elzLHGdoa7JDedy2h0sQ' | http PUT 'http://localhost:8080/group/v1/groups/t7r2iJxzq957elzLHGdoa7JDedy2h0sQ/members' 'Accept:application/json' 'Content-Type:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/html5/html5/api-docs.html b/service/src/doc/html5/html5/api-docs.html
new file mode 100644
index 0000000..41b233c
--- /dev/null
+++ b/service/src/doc/html5/html5/api-docs.html
@@ -0,0 +1,648 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<meta name="generator" content="Asciidoctor 1.5.3">
+<title>Apache Fineract CN Group Management API Documentation</title>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
+<style>
+/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
+/* Remove comment around @import statement below when using as a custom stylesheet */
+/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
+article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
+audio,canvas,video{display:inline-block}
+audio:not([controls]){display:none;height:0}
+[hidden],template{display:none}
+script{display:none!important}
+html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
+body{margin:0}
+a{background:transparent}
+a:focus{outline:thin dotted}
+a:active,a:hover{outline:0}
+h1{font-size:2em;margin:.67em 0}
+abbr[title]{border-bottom:1px dotted}
+b,strong{font-weight:bold}
+dfn{font-style:italic}
+hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
+mark{background:#ff0;color:#000}
+code,kbd,pre,samp{font-family:monospace;font-size:1em}
+pre{white-space:pre-wrap}
+q{quotes:"\201C" "\201D" "\2018" "\2019"}
+small{font-size:80%}
+sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
+sup{top:-.5em}
+sub{bottom:-.25em}
+img{border:0}
+svg:not(:root){overflow:hidden}
+figure{margin:0}
+fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
+legend{border:0;padding:0}
+button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
+button,input{line-height:normal}
+button,select{text-transform:none}
+button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
+button[disabled],html input[disabled]{cursor:default}
+input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
+input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
+input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}
+button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
+textarea{overflow:auto;vertical-align:top}
+table{border-collapse:collapse;border-spacing:0}
+*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
+html,body{font-size:100%}
+body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto}
+a:hover{cursor:pointer}
+img,object,embed{max-width:100%;height:auto}
+object,embed{height:100%}
+img{-ms-interpolation-mode:bicubic}
+.left{float:left!important}
+.right{float:right!important}
+.text-left{text-align:left!important}
+.text-right{text-align:right!important}
+.text-center{text-align:center!important}
+.text-justify{text-align:justify!important}
+.hide{display:none}
+body{-webkit-font-smoothing:antialiased}
+img,object,svg{display:inline-block;vertical-align:middle}
+textarea{height:auto;min-height:50px}
+select{width:100%}
+.center{margin-left:auto;margin-right:auto}
+.spread{width:100%}
+p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}
+.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
+div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
+a{color:#2156a5;text-decoration:underline;line-height:inherit}
+a:hover,a:focus{color:#1d4b8f}
+a img{border:none}
+p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
+p aside{font-size:.875em;line-height:1.35;font-style:italic}
+h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
+h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
+h1{font-size:2.125em}
+h2{font-size:1.6875em}
+h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
+h4,h5{font-size:1.125em}
+h6{font-size:1em}
+hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
+em,i{font-style:italic;line-height:inherit}
+strong,b{font-weight:bold;line-height:inherit}
+small{font-size:60%;line-height:inherit}
+code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
+ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
+ul,ol,ul.no-bullet,ol.no-bullet{margin-left:1.5em}
+ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
+ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
+ul.square{list-style-type:square}
+ul.circle{list-style-type:circle}
+ul.disc{list-style-type:disc}
+ul.no-bullet{list-style:none}
+ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
+dl dt{margin-bottom:.3125em;font-weight:bold}
+dl dd{margin-bottom:1.25em}
+abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
+abbr{text-transform:none}
+blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
+blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
+blockquote cite:before{content:"\2014 \0020"}
+blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
+blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
+@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
+h1{font-size:2.75em}
+h2{font-size:2.3125em}
+h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
+h4{font-size:1.4375em}}
+table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
+table thead,table tfoot{background:#f7f8f7;font-weight:bold}
+table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
+table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
+table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
+table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
+body{tab-size:4}
+h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
+h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
+.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}
+.clearfix:after,.float-group:after{clear:both}
+*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
+pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
+.keyseq{color:rgba(51,51,51,.8)}
+kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
+.keyseq kbd:first-child{margin-left:0}
+.keyseq kbd:last-child{margin-right:0}
+.menuseq,.menu{color:rgba(0,0,0,.8)}
+b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}
+b.button:before{content:"[";padding:0 3px 0 2px}
+b.button:after{content:"]";padding:0 2px 0 3px}
+p a>code:hover{color:rgba(0,0,0,.9)}
+#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
+#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}
+#header:after,#content:after,#footnotes:after,#footer:after{clear:both}
+#content{margin-top:1.25em}
+#content:before{content:none}
+#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
+#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}
+#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}
+#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
+#header .details span:first-child{margin-left:-.125em}
+#header .details span.email a{color:rgba(0,0,0,.85)}
+#header .details br{display:none}
+#header .details br+span:before{content:"\00a0\2013\00a0"}
+#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
+#header .details br+span#revremark:before{content:"\00a0|\00a0"}
+#header #revnumber{text-transform:capitalize}
+#header #revnumber:after{content:"\00a0"}
+#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
+#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}
+#toc>ul{margin-left:.125em}
+#toc ul.sectlevel0>li>a{font-style:italic}
+#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
+#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
+#toc li{line-height:1.3334;margin-top:.3334em}
+#toc a{text-decoration:none}
+#toc a:active{text-decoration:underline}
+#toctitle{color:#7a2518;font-size:1.2em}
+@media only screen and (min-width:768px){#toctitle{font-size:1.375em}
+body.toc2{padding-left:15em;padding-right:0}
+#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
+#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
+#toc.toc2>ul{font-size:.9em;margin-bottom:0}
+#toc.toc2 ul ul{margin-left:0;padding-left:1em}
+#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
+body.toc2.toc-right{padding-left:0;padding-right:15em}
+body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}
+@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
+#toc.toc2{width:20em}
+#toc.toc2 #toctitle{font-size:1.375em}
+#toc.toc2>ul{font-size:.95em}
+#toc.toc2 ul ul{padding-left:1.25em}
+body.toc2.toc-right{padding-left:0;padding-right:20em}}
+#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
+#content #toc>:first-child{margin-top:0}
+#content #toc>:last-child{margin-bottom:0}
+#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
+#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
+.sect1{padding-bottom:.625em}
+@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}
+.sect1+.sect1{border-top:1px solid #efefed}
+#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
+#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
+#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
+#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
+#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
+.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
+.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
+table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}
+.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}
+table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}
+.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
+.admonitionblock>table td.icon{text-align:center;width:80px}
+.admonitionblock>table td.icon img{max-width:none}
+.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
+.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}
+.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
+.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
+.exampleblock>.content>:first-child{margin-top:0}
+.exampleblock>.content>:last-child{margin-bottom:0}
+.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
+.sidebarblock>:first-child{margin-top:0}
+.sidebarblock>:last-child{margin-bottom:0}
+.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
+.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
+.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
+.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
+.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}
+.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}
+@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
+@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
+.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
+.listingblock pre.highlightjs{padding:0}
+.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
+.listingblock pre.prettyprint{border-width:0}
+.listingblock>.content{position:relative}
+.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
+.listingblock:hover code[data-lang]:before{display:block}
+.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}
+.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}
+table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
+table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
+table.pyhltable td.code{padding-left:.75em;padding-right:0}
+pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}
+pre.pygments .lineno{display:inline-block;margin-right:.25em}
+table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
+.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
+.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
+.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
+.quoteblock blockquote{margin:0;padding:0;border:0}
+.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
+.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
+.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}
+.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}
+.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}
+.quoteblock .quoteblock blockquote:before{display:none}
+.verseblock{margin:0 1em 1.25em 1em}
+.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
+.verseblock pre strong{font-weight:400}
+.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
+.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
+.quoteblock .attribution br,.verseblock .attribution br{display:none}
+.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
+.quoteblock.abstract{margin:0 0 1.25em 0;display:block}
+.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}
+.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}
+table.tableblock{max-width:100%;border-collapse:separate}
+table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}
+table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
+table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0}
+table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0}
+table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0}
+table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0}
+table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0}
+table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0}
+table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0}
+table.frame-all{border-width:1px}
+table.frame-sides{border-width:0 1px}
+table.frame-topbot{border-width:1px 0}
+th.halign-left,td.halign-left{text-align:left}
+th.halign-right,td.halign-right{text-align:right}
+th.halign-center,td.halign-center{text-align:center}
+th.valign-top,td.valign-top{vertical-align:top}
+th.valign-bottom,td.valign-bottom{vertical-align:bottom}
+th.valign-middle,td.valign-middle{vertical-align:middle}
+table thead th,table tfoot th{font-weight:bold}
+tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
+tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
+p.tableblock>code:only-child{background:none;padding:0}
+p.tableblock{font-size:1em}
+td>div.verse{white-space:pre}
+ol{margin-left:1.75em}
+ul li ol{margin-left:1.5em}
+dl dd{margin-left:1.125em}
+dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
+ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
+ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none}
+ul.unstyled,ol.unnumbered,ul.checklist{margin-left:.625em}
+ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1em;font-size:.85em}
+ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px}
+ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}
+ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}
+ul.inline>li>*{display:block}
+.unstyled dl dt{font-weight:400;font-style:normal}
+ol.arabic{list-style-type:decimal}
+ol.decimal{list-style-type:decimal-leading-zero}
+ol.loweralpha{list-style-type:lower-alpha}
+ol.upperalpha{list-style-type:upper-alpha}
+ol.lowerroman{list-style-type:lower-roman}
+ol.upperroman{list-style-type:upper-roman}
+ol.lowergreek{list-style-type:lower-greek}
+.hdlist>table,.colist>table{border:0;background:none}
+.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
+td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
+td.hdlist1{font-weight:bold;padding-bottom:1.25em}
+.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
+.colist>table tr>td:first-of-type{padding:0 .75em;line-height:1}
+.colist>table tr>td:last-of-type{padding:.25em 0}
+.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
+.imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0}
+.imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em}
+.imageblock>.title{margin-bottom:0}
+.imageblock.thumb,.imageblock.th{border-width:6px}
+.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
+.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
+.image.left{margin-right:.625em}
+.image.right{margin-left:.625em}
+a.image{text-decoration:none;display:inline-block}
+a.image object{pointer-events:none}
+sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
+sup.footnote a,sup.footnoteref a{text-decoration:none}
+sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
+#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
+#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}
+#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}
+#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}
+#footnotes .footnote:last-of-type{margin-bottom:0}
+#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
+.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
+.gist .file-data>table td.line-data{width:99%}
+div.unbreakable{page-break-inside:avoid}
+.big{font-size:larger}
+.small{font-size:smaller}
+.underline{text-decoration:underline}
+.overline{text-decoration:overline}
+.line-through{text-decoration:line-through}
+.aqua{color:#00bfbf}
+.aqua-background{background-color:#00fafa}
+.black{color:#000}
+.black-background{background-color:#000}
+.blue{color:#0000bf}
+.blue-background{background-color:#0000fa}
+.fuchsia{color:#bf00bf}
+.fuchsia-background{background-color:#fa00fa}
+.gray{color:#606060}
+.gray-background{background-color:#7d7d7d}
+.green{color:#006000}
+.green-background{background-color:#007d00}
+.lime{color:#00bf00}
+.lime-background{background-color:#00fa00}
+.maroon{color:#600000}
+.maroon-background{background-color:#7d0000}
+.navy{color:#000060}
+.navy-background{background-color:#00007d}
+.olive{color:#606000}
+.olive-background{background-color:#7d7d00}
+.purple{color:#600060}
+.purple-background{background-color:#7d007d}
+.red{color:#bf0000}
+.red-background{background-color:#fa0000}
+.silver{color:#909090}
+.silver-background{background-color:#bcbcbc}
+.teal{color:#006060}
+.teal-background{background-color:#007d7d}
+.white{color:#bfbfbf}
+.white-background{background-color:#fafafa}
+.yellow{color:#bfbf00}
+.yellow-background{background-color:#fafa00}
+span.icon>.fa{cursor:default}
+.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
+.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}
+.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
+.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}
+.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}
+.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}
+.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
+.conum[data-value] *{color:#fff!important}
+.conum[data-value]+b{display:none}
+.conum[data-value]:after{content:attr(data-value)}
+pre .conum[data-value]{position:relative;top:-.125em}
+b.conum *{color:inherit!important}
+.conum:not([data-value]):empty{display:none}
+dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
+h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
+p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
+p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
+p{margin-bottom:1.25rem}
+.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
+.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
+.print-only{display:none!important}
+@media print{@page{margin:1.25cm .75cm}
+*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
+a{color:inherit!important;text-decoration:underline!important}
+a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
+a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
+abbr[title]:after{content:" (" attr(title) ")"}
+pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
+thead{display:table-header-group}
+svg{max-width:100%}
+p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
+h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
+#toc,.sidebarblock,.exampleblock>.content{background:none!important}
+#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}
+.sect1{padding-bottom:0!important}
+.sect1+.sect1{border:0!important}
+#header>h1:first-child{margin-top:1.25rem}
+body.book #header{text-align:center}
+body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}
+body.book #header .details{border:0!important;display:block;padding:0!important}
+body.book #header .details span:first-child{margin-left:0!important}
+body.book #header .details br{display:block}
+body.book #header .details br+span:before{content:none!important}
+body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
+body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
+.listingblock code[data-lang]:before{display:block}
+#footer{background:none!important;padding:0 .9375em}
+#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}
+.hide-on-print{display:none!important}
+.print-only{display:block!important}
+.hide-for-print{display:none!important}
+.show-for-print{display:inherit!important}}
+</style>
+</head>
+<body class="book">
+<div id="header">
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_apache_fineract_cn_group_management_api_documentation">Apache Fineract CN Group Management API Documentation</h2>
+<div class="sectionbody">
+
+</div>
+</div>
+<div class="sect1">
+<h2 id="_groups">Groups</h2>
+<div class="sectionbody">
+<div class="sect3">
+<h4 id="_create_a_group">Create A Group</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/group/v1/groups' -i -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'K083BUcl4wFgwV5vfyNevzMcU5Skz3d5'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">POST /group/v1/groups HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+K083BUcl4wFgwV5vfyNevzMcU5Skz3d5</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'K083BUcl4wFgwV5vfyNevzMcU5Skz3d5' | http POST 'http://localhost:8080/group/v1/groups' 'Accept:application/json' 'Content-Type:application/json'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_activate_a_group">Activate A Group</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/group/v1/groups/G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6/commands' -i -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">POST /group/v1/groups/G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6/commands HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6' | http POST 'http://localhost:8080/group/v1/groups/G3JyVMs1g6S5lNyA5whinxEuyM9tRkP6/commands' 'Accept:application/json' 'Content-Type:application/json'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_update_assigned_employee">Update Assigned Employee</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/group/v1/groups/KsbSd2TGf95VYynRjiZfXiUX75ahKD8v/employee' -i -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'KsbSd2TGf95VYynRjiZfXiUX75ahKD8v'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">PUT /group/v1/groups/KsbSd2TGf95VYynRjiZfXiUX75ahKD8v/employee HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+KsbSd2TGf95VYynRjiZfXiUX75ahKD8v</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'KsbSd2TGf95VYynRjiZfXiUX75ahKD8v' | http PUT 'http://localhost:8080/group/v1/groups/KsbSd2TGf95VYynRjiZfXiUX75ahKD8v/employee' 'Accept:application/json' 'Content-Type:application/json'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_update_group_leaders">Update Group Leaders</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/group/v1/groups/DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera/leaders' -i -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -d 'DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">PUT /group/v1/groups/DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera/leaders HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera' | http PUT 'http://localhost:8080/group/v1/groups/DMnO30IXH6Ru9rfC2VHN3k6GpbjRjera/leaders' 'Accept:application/json' 'Content-Type:application/json'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_update_group_members">Update Group Members</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/group/v1/groups/t7r2iJxzq957elzLHGdoa7JDedy2h0sQ/members' -i -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -d 't7r2iJxzq957elzLHGdoa7JDedy2h0sQ'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">PUT /group/v1/groups/t7r2iJxzq957elzLHGdoa7JDedy2h0sQ/members HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+t7r2iJxzq957elzLHGdoa7JDedy2h0sQ</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 't7r2iJxzq957elzLHGdoa7JDedy2h0sQ' | http PUT 'http://localhost:8080/group/v1/groups/t7r2iJxzq957elzLHGdoa7JDedy2h0sQ/members' 'Accept:application/json' 'Content-Type:application/json'</code></pre>
+</div>
+</div>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_group_definitions">Group Definitions</h2>
+<div class="sectionbody">
+<div class="sect3">
+<h4 id="_create_a_group_definition">Create A Group Definition</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/group/v1/definitions' -i -X POST -H 'Accept: */*' -H 'Content-Type: application/json' -d 'f56iUIk58phhM1kgYJpSsXjoxrIESX7K'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">POST /group/v1/definitions HTTP/1.1
+Accept: */*
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+f56iUIk58phhM1kgYJpSsXjoxrIESX7K</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'f56iUIk58phhM1kgYJpSsXjoxrIESX7K' | http POST 'http://localhost:8080/group/v1/definitions' 'Accept:*/*' 'Content-Type:application/json'</code></pre>
+</div>
+</div>
+</div>
+</div>
+</div>
+</div>
+<div id="footer">
+<div id="footer-text">
+Last updated 2018-04-13 05:40:16 +01:00
+</div>
+</div>
+<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/styles/github.min.css">
+<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/highlight.min.js"></script>
+<script>hljs.initHighlighting()</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/service/src/test/java/org/apache/fineract/cn/group/TestGroup.java b/service/src/test/java/org/apache/fineract/cn/group/TestGroup.java
new file mode 100644
index 0000000..e4bcaf5
--- /dev/null
+++ b/service/src/test/java/org/apache/fineract/cn/group/TestGroup.java
@@ -0,0 +1,335 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.fineract.cn.group;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.fineract.cn.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
+import org.apache.fineract.cn.api.context.AutoUserContext;
+import org.apache.fineract.cn.group.api.v1.EventConstants;
+import org.apache.fineract.cn.group.api.v1.client.GroupManager;
+import org.apache.fineract.cn.group.api.v1.domain.*;
+import org.apache.fineract.cn.group.util.GroupDefinitionGenerator;
+import org.apache.fineract.cn.group.util.GroupGenerator;
+import org.apache.fineract.cn.test.env.TestEnvironment;
+import org.apache.fineract.cn.test.fixture.TenantDataStoreContextTestRule;
+import org.apache.fineract.cn.test.fixture.cassandra.CassandraInitializer;
+import org.apache.fineract.cn.test.fixture.mariadb.MariaDBInitializer;
+import org.apache.fineract.cn.test.listener.EnableEventRecording;
+import org.apache.fineract.cn.test.listener.EventRecorder;
+import org.junit.*;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.netflix.feign.EnableFeignClients;
+import org.springframework.cloud.netflix.ribbon.RibbonClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.http.MediaType;
+import org.springframework.restdocs.JUnitRestDocumentation;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import java.time.Clock;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.put;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
+public class TestGroup {
+
+  @Rule
+  public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("src/doc/generated-snippets/test-group");
+
+  @Autowired
+  private WebApplicationContext context;
+
+  private MockMvc mockMvc;
+
+  final String path = "/group/v1";
+
+  @Before
+  public void setUp(){
+
+    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
+            .apply(documentationConfiguration(this.restDocumentation))
+            .alwaysDo(document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())))
+            .build();
+  }
+
+  private static final String APP_NAME = "group-v1";
+  private static final String TEST_USER = "ranefer";
+
+  private final static TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
+  private final static CassandraInitializer cassandraInitializer = new CassandraInitializer();
+  private final static MariaDBInitializer mariaDBInitializer = new MariaDBInitializer();
+  private final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
+
+  @ClassRule
+  public static TestRule orderClassRules = RuleChain
+          .outerRule(testEnvironment)
+          .around(cassandraInitializer)
+          .around(mariaDBInitializer)
+          .around(tenantDataStoreContext);
+
+  @Rule
+  public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
+          = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
+  @Autowired
+  private GroupManager testSubject;
+  @Autowired
+  private EventRecorder eventRecorder;
+
+  private AutoUserContext userContext;
+
+  public TestGroup() {
+    super();
+  }
+
+  @Before
+  public void prepTest() {
+    userContext = this.tenantApplicationSecurityEnvironment.createAutoUserContext(TestGroup.TEST_USER);
+  }
+
+  @After
+  public void cleanTest() {
+    userContext.close();
+  }
+
+  public boolean waitForInitialize() {
+    try {
+      return this.eventRecorder.wait(EventConstants.INITIALIZE, EventConstants.INITIALIZE);
+    } catch (final InterruptedException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  @Test
+  public void shouldCreateGroup() throws Exception {
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+
+    this.testSubject.createGroup(randomGroup);
+
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(randomGroup.getIdentifier(), fetchedGroup.getIdentifier());
+    Assert.assertEquals(randomGroup.getGroupDefinitionIdentifier(), fetchedGroup.getGroupDefinitionIdentifier());
+    Assert.assertEquals(randomGroup.getName(), fetchedGroup.getName());
+    Assert.assertEquals(randomGroup.getOffice(), fetchedGroup.getOffice());
+    Assert.assertEquals(randomGroup.getAssignedEmployee(), fetchedGroup.getAssignedEmployee());
+    Assert.assertEquals(randomGroup.getWeekday(), fetchedGroup.getWeekday());
+    Assert.assertEquals(Group.Status.PENDING.name(), fetchedGroup.getStatus());
+    Assert.assertEquals(randomGroup.getLeaders().size(), fetchedGroup.getLeaders().size());
+    Assert.assertEquals(randomGroup.getMembers().size(), fetchedGroup.getMembers().size());
+    Assert.assertNotNull(fetchedGroup.getCreatedBy());
+    Assert.assertNotNull(fetchedGroup.getCreatedOn());
+    Assert.assertNull(fetchedGroup.getLastModifiedBy());
+    Assert.assertNull(fetchedGroup.getLastModifiedOn());
+    Assert.assertNotNull(fetchedGroup.getAddress());
+
+    this.mockMvc.perform(post(path + "/groups")
+            .accept(MediaType.APPLICATION_JSON_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(fetchedGroup.getIdentifier()))
+            .andExpect(status().isNotFound());
+  }
+
+  @Test
+  public void shouldActivateCommand() throws Exception {
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.testSubject.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(Group.Status.PENDING.name(), fetchedGroup.getStatus());
+
+    final GroupCommand activate = new GroupCommand();
+    activate.setAction(GroupCommand.Action.ACTIVATE.name());
+    activate.setNote(RandomStringUtils.randomAlphanumeric(256));
+    activate.setCreatedBy(TestGroup.TEST_USER);
+    activate.setCreatedOn(ZonedDateTime.now(Clock.systemUTC()).format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
+
+    this.testSubject.processGroupCommand(randomGroup.getIdentifier(), activate);
+    this.eventRecorder.wait(EventConstants.ACTIVATE_GROUP, randomGroup.getIdentifier());
+
+    final Group activatedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(Group.Status.ACTIVE.name(), activatedGroup.getStatus());
+
+    final List<GroupCommand> groupCommands = this.testSubject.fetchGroupCommands(activatedGroup.getIdentifier());
+    Assert.assertTrue(groupCommands.size() == 1);
+    final GroupCommand groupCommand = groupCommands.get(0);
+    Assert.assertEquals(activate.getAction(), groupCommand.getAction());
+    Assert.assertEquals(activate.getNote(), groupCommand.getNote());
+    Assert.assertEquals(activate.getCreatedBy(), groupCommand.getCreatedBy());
+    Assert.assertNotNull(groupCommand.getCreatedOn());
+
+    final List<Meeting> meetings = this.testSubject.fetchMeetings(activatedGroup.getIdentifier(), Boolean.FALSE);
+    Assert.assertNotNull(meetings);
+    Assert.assertEquals(randomGroupDefinition.getCycle().getNumberOfMeetings(), Integer.valueOf(meetings.size()));
+
+    final Meeting meeting2signOff = meetings.get(0);
+    final SignOffMeeting signOffMeeting = new SignOffMeeting();
+    signOffMeeting.setCycle(meeting2signOff.getCurrentCycle());
+    signOffMeeting.setSequence(meeting2signOff.getMeetingSequence());
+    signOffMeeting.setDuration(120L);
+    signOffMeeting.setAttendees(meeting2signOff.getAttendees()
+            .stream()
+            .map(attendee -> {
+              attendee.setStatus(Attendee.Status.ATTENDED.name());
+              return attendee;
+            })
+            .collect(Collectors.toSet())
+    );
+
+    this.testSubject.closeMeeting(activatedGroup.getIdentifier(), signOffMeeting);
+    this.eventRecorder.wait(EventConstants.PUT_GROUP, activatedGroup.getIdentifier());
+
+    this.mockMvc.perform(post(path + "/groups/" + fetchedGroup.getIdentifier() + "/commands")
+            .accept(MediaType.APPLICATION_JSON_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(fetchedGroup.getIdentifier()))
+            .andExpect(status().isNotFound());
+  }
+
+  @Test
+  public void shouldUpdateLeaders() throws Exception {
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.testSubject.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final int currentLeadersSize = randomGroup.getLeaders().size();
+    randomGroup.getLeaders().add(RandomStringUtils.randomAlphanumeric(32));
+    this.testSubject.updateLeaders(randomGroup.getIdentifier(), randomGroup.getLeaders());
+    this.eventRecorder.wait(EventConstants.PUT_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals((currentLeadersSize + 1), fetchedGroup.getLeaders().size());
+
+    this.mockMvc.perform(put(path + "/groups/" + fetchedGroup.getIdentifier() + "/leaders" )
+            .accept(MediaType.APPLICATION_JSON_VALUE)
+            .contentType(MediaType.APPLICATION_JSON)
+            .content(fetchedGroup.getIdentifier()))
+            .andExpect(status().is4xxClientError());
+  }
+
+  @Test
+  public void shouldUpdateMembers() throws Exception {
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.testSubject.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final int currentMembersSize = randomGroup.getMembers().size();
+    randomGroup.getMembers().addAll(Arrays.asList(
+            RandomStringUtils.randomAlphanumeric(32),
+            RandomStringUtils.randomAlphanumeric(32)
+    ));
+    this.testSubject.updateMembers(randomGroup.getIdentifier(), randomGroup.getMembers());
+    this.eventRecorder.wait(EventConstants.PUT_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals((currentMembersSize + 2), fetchedGroup.getMembers().size());
+
+    this.mockMvc.perform(put(path + "/groups/" + fetchedGroup.getIdentifier() + "/members" )
+            .accept(MediaType.APPLICATION_JSON_VALUE)
+            .contentType(MediaType.APPLICATION_JSON)
+            .content(fetchedGroup.getIdentifier()))
+            .andExpect(status().is4xxClientError());
+  }
+
+  @Test
+  public void shouldUpdateAssignedEmployee() throws Exception {
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final Group randomGroup = GroupGenerator.createRandomGroup(randomGroupDefinition.getIdentifier());
+    this.testSubject.createGroup(randomGroup);
+    this.eventRecorder.wait(EventConstants.POST_GROUP, randomGroup.getIdentifier());
+
+    final AssignedEmployeeHolder anotherEmployee = new AssignedEmployeeHolder();
+    anotherEmployee.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
+
+    this.testSubject.updateAssignedEmployee(randomGroup.getIdentifier(), anotherEmployee);
+    this.eventRecorder.wait(EventConstants.PUT_GROUP, randomGroup.getIdentifier());
+
+    final Group fetchedGroup = this.testSubject.findGroup(randomGroup.getIdentifier());
+    Assert.assertEquals(anotherEmployee.getIdentifier(), fetchedGroup.getAssignedEmployee());
+
+    this.mockMvc.perform(put(path + "/groups/" + fetchedGroup.getIdentifier() + "/employee")
+            .accept(MediaType.APPLICATION_JSON_VALUE)
+            .contentType(MediaType.APPLICATION_JSON)
+            .content(fetchedGroup.getIdentifier()))
+            .andExpect(status().is4xxClientError());
+  }
+
+  @Configuration
+  @EnableEventRecording
+  @EnableFeignClients(basePackages = {"org.apache.fineract.cn.group.api.v1.client"})
+  @RibbonClient(name = APP_NAME)
+  @Import({GroupConfiguration.class})
+  @ComponentScan("org.apache.fineract.cn.group.listener")
+  public static class TestConfiguration {
+    public TestConfiguration() {
+      super();
+    }
+
+    @Bean()
+    public Logger logger() {
+      return LoggerFactory.getLogger("test-logger");
+    }
+  }
+}
diff --git a/service/src/test/java/org/apache/fineract/cn/group/TestGroupDefinition.java b/service/src/test/java/org/apache/fineract/cn/group/TestGroupDefinition.java
new file mode 100644
index 0000000..239fb8a
--- /dev/null
+++ b/service/src/test/java/org/apache/fineract/cn/group/TestGroupDefinition.java
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.fineract.cn.group;
+
+import org.apache.fineract.cn.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
+import org.apache.fineract.cn.api.context.AutoUserContext;
+import org.apache.fineract.cn.group.api.v1.EventConstants;
+import org.apache.fineract.cn.group.api.v1.client.GroupManager;
+import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
+import org.apache.fineract.cn.group.util.GroupDefinitionGenerator;
+import org.apache.fineract.cn.lang.TenantContextHolder;
+import org.apache.fineract.cn.test.env.TestEnvironment;
+import org.apache.fineract.cn.test.fixture.TenantDataStoreContextTestRule;
+import org.apache.fineract.cn.test.fixture.cassandra.CassandraInitializer;
+import org.apache.fineract.cn.test.fixture.mariadb.MariaDBInitializer;
+import org.apache.fineract.cn.test.listener.EnableEventRecording;
+import org.apache.fineract.cn.test.listener.EventRecorder;
+import org.junit.*;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.netflix.feign.EnableFeignClients;
+import org.springframework.cloud.netflix.ribbon.RibbonClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.http.MediaType;
+import org.springframework.restdocs.JUnitRestDocumentation;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
+public class TestGroupDefinition {
+
+  @Rule
+  public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("src/doc/generated-snippets/test-group-definition");
+
+  @Autowired
+  private WebApplicationContext context;
+
+  private MockMvc mockMvc;
+
+  final String path = "/group/v1";
+
+  @Before
+  public void setUp(){
+
+    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
+            .apply(documentationConfiguration(this.restDocumentation))
+            .alwaysDo(document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())))
+            .build();
+  }
+
+  private static final String APP_NAME = "group-v1";
+  private static final String TEST_USER = "ranefer";
+
+  private final static TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
+  private final static CassandraInitializer cassandraInitializer = new CassandraInitializer();
+  private final static MariaDBInitializer mariaDBInitializer = new MariaDBInitializer();
+  private final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
+
+  @ClassRule
+  public static TestRule orderClassRules = RuleChain
+          .outerRule(testEnvironment)
+          .around(cassandraInitializer)
+          .around(mariaDBInitializer)
+          .around(tenantDataStoreContext);
+
+  @Rule
+  public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
+          = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
+
+  @Autowired
+  private GroupManager testSubject;
+  @Autowired
+  private EventRecorder eventRecorder;
+
+  private AutoUserContext userContext;
+
+  public TestGroupDefinition() {
+    super();
+  }
+
+  @Before
+  public void prepTest() {
+    userContext = this.tenantApplicationSecurityEnvironment.createAutoUserContext(TestGroupDefinition.TEST_USER);
+  }
+
+  @After
+  public void cleanTest() {
+    TenantContextHolder.clear();
+    userContext.close();
+  }
+
+  public boolean waitForInitialize() {
+    try {
+      return this.eventRecorder.wait(EventConstants.INITIALIZE, EventConstants.INITIALIZE);
+    } catch (final InterruptedException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  @Test
+  public void shouldCreateGroupDefinition() throws Exception {
+    final GroupDefinition randomGroupDefinition = GroupDefinitionGenerator.createRandomGroupDefinition();
+    this.testSubject.createGroupDefinition(randomGroupDefinition);
+
+    this.eventRecorder.wait(EventConstants.POST_GROUP_DEFINITION, randomGroupDefinition.getIdentifier());
+
+    final GroupDefinition fetchedGroupDefinition = this.testSubject.findGroupDefinition(randomGroupDefinition.getIdentifier());
+
+    Assert.assertEquals(randomGroupDefinition.getIdentifier(), fetchedGroupDefinition.getIdentifier());
+    Assert.assertEquals(randomGroupDefinition.getDescription(), fetchedGroupDefinition.getDescription());
+    Assert.assertEquals(randomGroupDefinition.getMinimalSize(), fetchedGroupDefinition.getMinimalSize());
+    Assert.assertEquals(randomGroupDefinition.getMaximalSize(), fetchedGroupDefinition.getMaximalSize());
+    Assert.assertNotNull(fetchedGroupDefinition.getCycle());
+    Assert.assertEquals(randomGroupDefinition.getCycle().getNumberOfMeetings(), fetchedGroupDefinition.getCycle().getNumberOfMeetings());
+    Assert.assertEquals(randomGroupDefinition.getCycle().getFrequency(), fetchedGroupDefinition.getCycle().getFrequency());
+    Assert.assertEquals(randomGroupDefinition.getCycle().getAdjustment(), fetchedGroupDefinition.getCycle().getAdjustment());
+    Assert.assertNotNull(fetchedGroupDefinition.getCreatedBy());
+    Assert.assertNotNull(fetchedGroupDefinition.getCreateOn());
+    Assert.assertNull(fetchedGroupDefinition.getLastModifiedBy());
+    Assert.assertNull(fetchedGroupDefinition.getLastModifiedOn());
+
+    this.mockMvc.perform(post(path + "/definitions")
+            .accept(MediaType.ALL_VALUE)
+            .contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(fetchedGroupDefinition.getIdentifier()))
+            .andExpect(status().is4xxClientError());
+
+  }
+
+  @Configuration
+  @EnableEventRecording
+  @EnableFeignClients(basePackages = {"org.apache.fineract.cn.group.api.v1.client"})
+  @RibbonClient(name = APP_NAME)
+  @Import({GroupConfiguration.class})
+  @ComponentScan("org.apache.fineract.cn.group.listener")
+  public static class TestConfiguration {
+    public TestConfiguration() {
+      super();
+    }
+
+    @Bean()
+    public Logger logger() {
+      return LoggerFactory.getLogger("test-logger");
+    }
+  }
+}
diff --git a/service/src/test/java/org/apache/fineract/cn/group/listener/GroupDefinitionEventListener.java b/service/src/test/java/org/apache/fineract/cn/group/listener/GroupDefinitionEventListener.java
new file mode 100644
index 0000000..13dad62
--- /dev/null
+++ b/service/src/test/java/org/apache/fineract/cn/group/listener/GroupDefinitionEventListener.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.fineract.cn.group.listener;
+
+import org.apache.fineract.cn.group.api.v1.EventConstants;
+import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
+import org.apache.fineract.cn.test.listener.EventRecorder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.stereotype.Component;
+
+@SuppressWarnings("unused")
+@Component
+public class GroupDefinitionEventListener {
+
+  private final EventRecorder eventRecorder;
+
+  @Autowired
+  public GroupDefinitionEventListener(final EventRecorder eventRecorder) {
+    super();
+    this.eventRecorder = eventRecorder;
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_POST_GROUP_DEFINITION
+  )
+  public void onGroupDefinitionCreated(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                                       final String payload) {
+    this.eventRecorder.event(tenant, EventConstants.POST_GROUP_DEFINITION, payload, String.class);
+  }
+}
diff --git a/service/src/test/java/org/apache/fineract/cn/group/listener/GroupEventListener.java b/service/src/test/java/org/apache/fineract/cn/group/listener/GroupEventListener.java
new file mode 100644
index 0000000..a453f68
--- /dev/null
+++ b/service/src/test/java/org/apache/fineract/cn/group/listener/GroupEventListener.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.fineract.cn.group.listener;
+
+import org.apache.fineract.cn.group.api.v1.EventConstants;
+import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
+import org.apache.fineract.cn.test.listener.EventRecorder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.stereotype.Component;
+
+@SuppressWarnings("unused")
+@Component
+public class GroupEventListener {
+
+  private final EventRecorder eventRecorder;
+
+  @Autowired
+  public GroupEventListener(final EventRecorder eventRecorder) {
+    super();
+    this.eventRecorder = eventRecorder;
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_POST_GROUP
+  )
+  public void onGroupCreated(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                             final String payload) {
+    this.eventRecorder.event(tenant, EventConstants.POST_GROUP, payload, String.class);
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_ACTIVATE_GROUP
+  )
+  public void onGroupActivated(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                             final String payload) {
+    this.eventRecorder.event(tenant, EventConstants.ACTIVATE_GROUP, payload, String.class);
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_PUT_GROUP
+  )
+  public void onGroupUpdated(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                               final String payload) {
+    this.eventRecorder.event(tenant, EventConstants.PUT_GROUP, payload, String.class);
+  }
+}
diff --git a/service/src/test/java/org/apache/fineract/cn/group/listener/MigrationEventListener.java b/service/src/test/java/org/apache/fineract/cn/group/listener/MigrationEventListener.java
new file mode 100644
index 0000000..027688a
--- /dev/null
+++ b/service/src/test/java/org/apache/fineract/cn/group/listener/MigrationEventListener.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.fineract.cn.group.listener;
+
+import org.apache.fineract.cn.group.api.v1.EventConstants;
+import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
+import org.apache.fineract.cn.test.listener.EventRecorder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.stereotype.Component;
+
+@SuppressWarnings("unused")
+@Component
+public class MigrationEventListener {
+
+  private final EventRecorder eventRecorder;
+
+  @Autowired
+  public MigrationEventListener(final EventRecorder eventRecorder) {
+    super();
+    this.eventRecorder = eventRecorder;
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_INITIALIZE
+  )
+  public void onInitialization(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                               final String payload) {
+    this.eventRecorder.event(tenant, EventConstants.INITIALIZE, payload, String.class);
+  }
+}
diff --git a/service/src/test/java/org/apache/fineract/cn/group/util/GroupDefinitionGenerator.java b/service/src/test/java/org/apache/fineract/cn/group/util/GroupDefinitionGenerator.java
new file mode 100644
index 0000000..6d33221
--- /dev/null
+++ b/service/src/test/java/org/apache/fineract/cn/group/util/GroupDefinitionGenerator.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.fineract.cn.group.util;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.fineract.cn.group.api.v1.domain.Cycle;
+import org.apache.fineract.cn.group.api.v1.domain.GroupDefinition;
+
+public class GroupDefinitionGenerator {
+
+  private GroupDefinitionGenerator() {
+    super();
+  }
+
+  public static GroupDefinition createRandomGroupDefinition() {
+    final GroupDefinition groupDefinition = new GroupDefinition();
+    groupDefinition.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
+    groupDefinition.setDescription(RandomStringUtils.randomAlphabetic(2048));
+    groupDefinition.setMinimalSize(10);
+    groupDefinition.setMaximalSize(30);
+    final Cycle cycle = new Cycle();
+    cycle.setNumberOfMeetings(25);
+    cycle.setFrequency(Cycle.Frequency.WEEKLY.name());
+    cycle.setAdjustment(Cycle.Adjustment.NEXT_BUSINESS_DAY.name());
+    groupDefinition.setCycle(cycle);
+    return groupDefinition;
+  }
+}
diff --git a/service/src/test/java/org/apache/fineract/cn/group/util/GroupGenerator.java b/service/src/test/java/org/apache/fineract/cn/group/util/GroupGenerator.java
new file mode 100644
index 0000000..112fe07
--- /dev/null
+++ b/service/src/test/java/org/apache/fineract/cn/group/util/GroupGenerator.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.fineract.cn.group.util;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.fineract.cn.group.api.v1.domain.Address;
+import org.apache.fineract.cn.group.api.v1.domain.Group;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+public class GroupGenerator {
+
+  private GroupGenerator() {
+    super();
+  }
+
+  public static Group createRandomGroup(final String definitionIdentifier) {
+    final Group group = new Group();
+    group.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
+    group.setGroupDefinitionIdentifier(definitionIdentifier);
+    group.setName(RandomStringUtils.randomAlphanumeric(256));
+    group.setOffice(RandomStringUtils.randomAlphanumeric(32));
+    group.setAssignedEmployee(RandomStringUtils.randomAlphanumeric(32));
+    group.setLeaders(new HashSet<>(Arrays.asList(
+        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32)
+    )));
+    group.setMembers(new HashSet<>(Arrays.asList(
+        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
+        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
+        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
+        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32),
+        RandomStringUtils.randomAlphanumeric(32), RandomStringUtils.randomAlphanumeric(32)
+    )));
+    group.setWeekday(Group.Weekday.WEDNESDAY.getValue());
+    final Address address = new Address();
+    address.setStreet(RandomStringUtils.randomAlphanumeric(256));
+    address.setCity(RandomStringUtils.randomAlphanumeric(256));
+    address.setRegion(RandomStringUtils.randomAlphanumeric(256));
+    address.setPostalCode(RandomStringUtils.randomAlphanumeric(2));
+    address.setCountry(RandomStringUtils.randomAlphanumeric(256));
+    address.setCountryCode(RandomStringUtils.randomAlphanumeric(2));
+    group.setAddress(address);
+    return group;
+  }
+}


[fineract-cn-group] 27/40: implemeting UpdateGroup request

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 4bd0052c741593bd13f67c3da0a0b76de1c8ff9f
Author: kengneruphine <ru...@gmail.com>
AuthorDate: Fri Jul 6 09:55:50 2018 +0100

    implemeting UpdateGroup request
---
 .../cn/group/api/v1/client/GroupManager.java       | 13 ++++++
 .../cn/group/api/v1/domain/GroupCommand.java       |  2 +-
 .../group/internal/command/UpdateGroupCommand.java | 17 ++++++++
 .../internal/command/handler/GroupAggregate.java   | 49 ++++++++++++++++++++++
 .../cn/group/rest/GroupRestController.java         | 21 ++++++++++
 5 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupManager.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupManager.java
index dac2955..12c563d 100644
--- a/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupManager.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/client/GroupManager.java
@@ -121,6 +121,19 @@ public interface GroupManager {
   Group findGroup(@PathVariable("identifier") final String identifier);
 
   @RequestMapping(
+          value = "/groups/{identifier}",
+          method = RequestMethod.PUT,
+          produces = MediaType.APPLICATION_JSON_VALUE,
+          consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ThrowsExceptions({
+          @ThrowsException(status = HttpStatus.NOT_FOUND, exception = GroupNotFoundException.class),
+          @ThrowsException(status = HttpStatus.BAD_REQUEST, exception = GroupValidationException.class)
+  })
+  void updateGroup(@PathVariable("identifier") final String identifier, @RequestBody final Group group);
+
+
+  @RequestMapping(
       value = "/groups/{identifier}/leaders",
       method = RequestMethod.PUT,
       produces = MediaType.APPLICATION_JSON_VALUE,
diff --git a/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/GroupCommand.java b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/GroupCommand.java
index 526e5b7..3ca7996 100644
--- a/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/GroupCommand.java
+++ b/api/src/main/java/org/apache/fineract/cn/group/api/v1/domain/GroupCommand.java
@@ -18,7 +18,7 @@
  */
 package org.apache.fineract.cn.group.api.v1.domain;
 
-public class GroupCommand {
+public class    GroupCommand {
 
   private Action action;
   private String note;
diff --git a/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateGroupCommand.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateGroupCommand.java
new file mode 100644
index 0000000..5951ba3
--- /dev/null
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/UpdateGroupCommand.java
@@ -0,0 +1,17 @@
+package org.apache.fineract.cn.group.internal.command;
+
+import org.apache.fineract.cn.group.api.v1.domain.Group;
+
+public class UpdateGroupCommand {
+
+    private final Group group;
+
+    public UpdateGroupCommand(final Group group) {
+        super();
+        this.group = group;
+    }
+
+    public Group group() {
+        return this.group;
+    }
+}
\ No newline at end of file
diff --git a/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
index 9402729..804aa26 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
@@ -35,6 +35,7 @@ import org.apache.fineract.cn.group.internal.command.SignOffMeetingCommand;
 import org.apache.fineract.cn.group.internal.command.UpdateAssignedEmployeeCommand;
 import org.apache.fineract.cn.group.internal.command.UpdateLeadersCommand;
 import org.apache.fineract.cn.group.internal.command.UpdateMembersCommand;
+import org.apache.fineract.cn.group.internal.command.UpdateGroupCommand;
 import org.apache.fineract.cn.group.internal.mapper.AddressMapper;
 import org.apache.fineract.cn.group.internal.mapper.GroupCommandMapper;
 import org.apache.fineract.cn.group.internal.repository.AddressEntity;
@@ -184,6 +185,49 @@ public class GroupAggregate {
     return group.getIdentifier();
   }
 
+  // Updating Group
+  @Transactional
+  @CommandHandler
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_GROUP)
+  public String updateGroup(final UpdateGroupCommand updateGroupCommand) {
+      final Group group = updateGroupCommand.group();
+      final GroupDefinitionEntity groupDefinitionEntity =
+              this.groupDefinitionRepository.findByIdentifier(group.getGroupDefinitionIdentifier())
+                      .orElseThrow(
+                              () -> ServiceException.notFound("Group definition {0} not found.", group.getGroupDefinitionIdentifier())
+                      );
+
+      final AddressEntity savedAddress = this.addressRepository.save(AddressMapper.map(group.getAddress()));
+      final GroupEntity groupEntity = findGroupEntityOrThrow(group.getIdentifier());
+
+      groupEntity.setGroupDefinition(groupDefinitionEntity);
+      groupEntity.setIdentifier(group.getIdentifier());
+      groupEntity.setName(group.getName());
+      groupEntity.setOffice(group.getOffice());
+      groupEntity.setWeekday(group.getWeekday());
+      groupEntity.setGroupStatus(group.getStatus());
+      //groupEntity.setAddressEntity(group.getAddress());
+
+      if (group.getAssignedEmployee() != null) {
+          this.updateAssignedEmployee(new UpdateAssignedEmployeeCommand(group.getIdentifier(), group.getAssignedEmployee()));
+      }
+
+      if (group.getLeaders() != null) {
+          this.updateLeaders(new UpdateLeadersCommand(group.getIdentifier(), group.getLeaders()));
+      }
+
+      if (group.getMembers() != null) {
+          this.updateMembers(new UpdateMembersCommand(group.getIdentifier(), group.getMembers()));
+      }
+
+
+      groupEntity.setLastModifiedBy(UserContextHolder.checkedGetUser());
+      groupEntity.setLastModifiedOn(LocalDateTime.now(Clock.systemUTC()));
+
+      this.groupRepository.save(groupEntity);
+
+      return group.getIdentifier();
+  }
   @Transactional
   @CommandHandler
   @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.ACTIVATE_GROUP)
@@ -377,4 +421,9 @@ public class GroupAggregate {
     groupCommandEntity.setGroup(groupEntity);
     this.groupCommandRepository.save(groupCommandEntity);
   }
+
+    private GroupEntity findGroupEntityOrThrow(String identifier) {
+        return this.groupRepository.findByIdentifier(identifier)
+                .orElseThrow(() -> ServiceException.notFound("Group ''{0}'' not found", identifier));
+    }
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupRestController.java b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupRestController.java
index 0db02d0..269f66c 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/rest/GroupRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/rest/GroupRestController.java
@@ -34,6 +34,7 @@ import org.apache.fineract.cn.group.internal.command.SignOffMeetingCommand;
 import org.apache.fineract.cn.group.internal.command.UpdateAssignedEmployeeCommand;
 import org.apache.fineract.cn.group.internal.command.UpdateLeadersCommand;
 import org.apache.fineract.cn.group.internal.command.UpdateMembersCommand;
+import org.apache.fineract.cn.group.internal.command.UpdateGroupCommand;
 import org.apache.fineract.cn.group.internal.service.GroupDefinitionService;
 import org.apache.fineract.cn.group.internal.service.GroupService;
 import java.util.List;
@@ -139,6 +140,26 @@ public class GroupRestController {
 
   @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.GROUP)
   @RequestMapping(
+          value = "/{identifier}",
+          method = RequestMethod.PUT,
+          consumes = MediaType.ALL_VALUE,
+          produces = MediaType.APPLICATION_JSON_VALUE
+  )
+
+  public
+  @ResponseBody
+  ResponseEntity<Void> updateGroup(@PathVariable("identifier") final String identifier,
+                                      @RequestBody final Group group) {
+    this.groupService.findByIdentifier(identifier)
+            .orElseThrow(() -> ServiceException.notFound("Group {0} not found.", identifier));
+
+    this.commandGateway.process(new UpdateGroupCommand(group));
+
+    return ResponseEntity.accepted().build();
+  }
+
+  @Permittable(value= AcceptedTokenType.TENANT, groupId = PermittableGroupIds.GROUP)
+  @RequestMapping(
       value = "/{identifier}/commands",
       method = RequestMethod.POST,
       produces = MediaType.APPLICATION_JSON_VALUE,


[fineract-cn-group] 06/40: updating artifact ids to apache fineract from mifos io

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 3f42b4352d336dec95b28a98d8838bd07a72d2db
Author: Myrle Krantz <my...@apache.org>
AuthorDate: Mon Feb 26 17:57:13 2018 +0100

    updating artifact ids to apache fineract from mifos io
---
 api/build.gradle            |  2 +-
 build.gradle                |  2 +-
 component-test/build.gradle | 10 +++++-----
 service/build.gradle        | 14 +++++++-------
 shared.gradle               |  2 +-
 5 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/api/build.gradle b/api/build.gradle
index 5dc9656..dcc39a6 100644
--- a/api/build.gradle
+++ b/api/build.gradle
@@ -16,7 +16,7 @@ apply from: '../shared.gradle'
 dependencies {
     compile(
             [group: 'org.springframework.cloud', name: 'spring-cloud-starter-feign'],
-            [group: 'io.mifos.core', name: 'api', version: versions.frameworkapi],
+            [group: 'org.apache.fineract.cn', name: 'api', version: versions.frameworkapi],
             [group: 'org.hibernate', name: 'hibernate-validator', version: versions.validator]
     )
 }
diff --git a/build.gradle b/build.gradle
index b30bd55..b82a3b2 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,4 +1,4 @@
-group 'io.mifos'
+group 'org.apache.fineract.cn'
 
 task publishApiToMavenLocal {
     dependsOn gradle.includedBuild('api').task(':publishToMavenLocal')
diff --git a/component-test/build.gradle b/component-test/build.gradle
index b9a16bc..5ca391b 100644
--- a/component-test/build.gradle
+++ b/component-test/build.gradle
@@ -20,11 +20,11 @@ apply from: '../shared.gradle'
 
 dependencies {
     compile(
-            [group: 'io.mifos.group', name: 'api', version: project.version],
-            [group: 'io.mifos.group', name: 'service', version: project.version],
-            [group: 'io.mifos.core', name: 'api', version: versions.frameworkapi],
-            [group: 'io.mifos.core', name: 'test', version: versions.frameworktest],
-            [group: 'io.mifos.anubis', name: 'test', version: versions.frameworkanubis],
+            [group: 'org.apache.fineract.cn.group', name: 'api', version: project.version],
+            [group: 'org.apache.fineract.cn.group', name: 'service', version: project.version],
+            [group: 'org.apache.fineract.cn', name: 'api', version: versions.frameworkapi],
+            [group: 'org.apache.fineract.cn', name: 'test', version: versions.frameworktest],
+            [group: 'org.apache.fineract.cn.anubis', name: 'test', version: versions.frameworkanubis],
             [group: 'org.springframework.boot', name: 'spring-boot-starter-test']
     )
 }
diff --git a/service/build.gradle b/service/build.gradle
index 09e8a22..2d36413 100644
--- a/service/build.gradle
+++ b/service/build.gradle
@@ -30,14 +30,14 @@ dependencies {
             [group: 'org.springframework.cloud', name: 'spring-cloud-starter-config'],
             [group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka'],
             [group: 'org.springframework.boot', name: 'spring-boot-starter-jetty'],
-            [group: 'io.mifos.group', name: 'api', version: project.version],
-            [group: 'io.mifos.anubis', name: 'library', version: versions.frameworkanubis],
+            [group: 'org.apache.fineract.cn.group', name: 'api', version: project.version],
+            [group: 'org.apache.fineract.cn.anubis', name: 'library', version: versions.frameworkanubis],
             [group: 'com.google.code.gson', name: 'gson'],
-            [group: 'io.mifos.core', name: 'lang', version: versions.frameworklang],
-            [group: 'io.mifos.core', name: 'async', version: versions.frameworkasync],
-            [group: 'io.mifos.core', name: 'cassandra', version: versions.frameworkcassandra],
-            [group: 'io.mifos.core', name: 'mariadb', version: versions.frameworkmariadb],
-            [group: 'io.mifos.core', name: 'command', version: versions.frameworkcommand],
+            [group: 'org.apache.fineract.cn', name: 'lang', version: versions.frameworklang],
+            [group: 'org.apache.fineract.cn', name: 'async', version: versions.frameworkasync],
+            [group: 'org.apache.fineract.cn', name: 'cassandra', version: versions.frameworkcassandra],
+            [group: 'org.apache.fineract.cn', name: 'mariadb', version: versions.frameworkmariadb],
+            [group: 'org.apache.fineract.cn', name: 'command', version: versions.frameworkcommand],
             [group: 'org.hibernate', name: 'hibernate-validator', version: versions.validator]
     )
 }
diff --git a/shared.gradle b/shared.gradle
index 79a8238..32403fd 100644
--- a/shared.gradle
+++ b/shared.gradle
@@ -1,4 +1,4 @@
-group 'io.mifos.group'
+group 'org.apache.fineract.cn.group'
 version '0.1.0-BUILD-SNAPSHOT'
 
 ext.versions = [


[fineract-cn-group] 28/40: modifying updateGroup request in the groupAggregate.java file

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit a018cdd3e1480b505fb725e80748084288a748e8
Author: kengneruphine <ru...@gmail.com>
AuthorDate: Fri Jul 6 11:39:02 2018 +0100

    modifying updateGroup request in the groupAggregate.java file
---
 .../group/internal/command/handler/GroupAggregate.java   | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java b/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
index 804aa26..409aa66 100644
--- a/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
+++ b/service/src/main/java/org/apache/fineract/cn/group/internal/command/handler/GroupAggregate.java
@@ -191,21 +191,21 @@ public class GroupAggregate {
   @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_GROUP)
   public String updateGroup(final UpdateGroupCommand updateGroupCommand) {
       final Group group = updateGroupCommand.group();
-      final GroupDefinitionEntity groupDefinitionEntity =
-              this.groupDefinitionRepository.findByIdentifier(group.getGroupDefinitionIdentifier())
-                      .orElseThrow(
-                              () -> ServiceException.notFound("Group definition {0} not found.", group.getGroupDefinitionIdentifier())
-                      );
+      //final GroupDefinitionEntity groupDefinitionEntity =
+        //      this.groupDefinitionRepository.findByIdentifier(group.getGroupDefinitionIdentifier())
+          //            .orElseThrow(
+            //                  () -> ServiceException.notFound("Group definition {0} not found.", group.getGroupDefinitionIdentifier())
+              //        );
 
       final AddressEntity savedAddress = this.addressRepository.save(AddressMapper.map(group.getAddress()));
       final GroupEntity groupEntity = findGroupEntityOrThrow(group.getIdentifier());
 
-      groupEntity.setGroupDefinition(groupDefinitionEntity);
-      groupEntity.setIdentifier(group.getIdentifier());
+     // groupEntity.setGroupDefinition(groupDefinitionEntity);
+     // groupEntity.setIdentifier(group.getIdentifier());
       groupEntity.setName(group.getName());
       groupEntity.setOffice(group.getOffice());
       groupEntity.setWeekday(group.getWeekday());
-      groupEntity.setGroupStatus(group.getStatus());
+     // groupEntity.setGroupStatus(group.getStatus());
       //groupEntity.setAddressEntity(group.getAddress());
 
       if (group.getAssignedEmployee() != null) {


[fineract-cn-group] 13/40: Merge pull request #3 from myrle-krantz/develop

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit e1b2d437d8f47e664460c3405bd1f29070107825
Merge: b376a14 b166c81
Author: Myrle Krantz <my...@apache.org>
AuthorDate: Mon Apr 9 18:40:06 2018 +0200

    Merge pull request #3 from myrle-krantz/develop
    
    Adding rat checks.

 api/build.gradle               | 18 ++++++++++++++++++
 api/settings.gradle            | 17 +++++++++++++++++
 build.gradle                   | 24 ++++++++++++++++++++++++
 component-test/build.gradle    | 18 ++++++++++++++++++
 component-test/settings.gradle | 17 +++++++++++++++++
 service/build.gradle           | 18 ++++++++++++++++++
 service/settings.gradle        | 17 +++++++++++++++++
 settings.gradle                | 17 +++++++++++++++++
 shared.gradle                  | 30 ++++++++++++++++++++++++++++++
 9 files changed, 176 insertions(+)


[fineract-cn-group] 18/40: Merge pull request #4 from myrle-krantz/develop

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 85c7d63a7a9ab97c323909ac662992ca7339d04c
Merge: e1b2d43 e8ae298
Author: Myrle Krantz <my...@apache.org>
AuthorDate: Mon Apr 16 21:20:36 2018 +0200

    Merge pull request #4 from myrle-krantz/develop
    
    Updating package names.

 README.md                                          |  2 -
 .../fineract/cn}/group/api/v1/EventConstants.java  |  2 +-
 .../group/api/v1/client/GroupAlreadyExists.java    |  2 +-
 .../v1/client/GroupDefinitionAlreadyExists.java    |  2 +-
 .../api/v1/client/GroupDefinitionNotFound.java     |  2 +-
 .../api/v1/client/GroupDefinitionValidation.java   |  2 +-
 .../cn}/group/api/v1/client/GroupManager.java      | 29 ++++-----
 .../api/v1/client/GroupNotFoundException.java      |  2 +-
 .../api/v1/client/GroupValidationException.java    |  2 +-
 .../fineract/cn}/group/api/v1/domain/Address.java  |  2 +-
 .../api/v1/domain/AssignedEmployeeHolder.java      |  2 +-
 .../fineract/cn}/group/api/v1/domain/Attendee.java |  2 +-
 .../fineract/cn}/group/api/v1/domain/Cycle.java    |  2 +-
 .../fineract/cn}/group/api/v1/domain/Group.java    |  2 +-
 .../cn}/group/api/v1/domain/GroupCommand.java      |  2 +-
 .../cn}/group/api/v1/domain/GroupDefinition.java   |  2 +-
 .../cn}/group/api/v1/domain/GroupPage.java         |  2 +-
 .../fineract/cn}/group/api/v1/domain/Meeting.java  |  2 +-
 .../cn}/group/api/v1/domain/SignOffMeeting.java    |  2 +-
 .../apache/fineract/cn}/group/TestGroup.java       | 67 ++++++++++---------
 .../fineract/cn}/group/TestGroupDefinition.java    | 42 ++++++------
 .../listener/GroupDefinitionEventListener.java     |  8 +--
 .../cn}/group/listener/GroupEventListener.java     |  8 +--
 .../cn}/group/listener/MigrationEventListener.java |  8 +--
 .../cn}/group/util/GroupDefinitionGenerator.java   |  6 +-
 .../fineract/cn}/group/util/GroupGenerator.java    |  6 +-
 .../fineract/cn/group}/GroupApplication.java       |  2 +-
 .../fineract/cn/group}/GroupConfiguration.java     | 26 ++++----
 .../fineract/cn/group}/ServiceConstants.java       |  2 +-
 .../internal/command/ActivateGroupCommand.java     |  4 +-
 .../group}/internal/command/CloseGroupCommand.java |  4 +-
 .../internal/command/CreateGroupCommand.java       |  4 +-
 .../command/CreateGroupDefinitionCommand.java      |  4 +-
 .../internal/command/InitializeServiceCommand.java |  2 +-
 .../internal/command/ReopenGroupCommand.java       |  4 +-
 .../internal/command/SignOffMeetingCommand.java    |  4 +-
 .../command/UpdateAssignedEmployeeCommand.java     |  2 +-
 .../internal/command/UpdateLeadersCommand.java     |  2 +-
 .../internal/command/UpdateMembersCommand.java     |  2 +-
 .../internal/command/handler/GroupAggregate.java   | 76 ++++++++++++----------
 .../command/handler/MigrationAggregate.java        | 19 +++---
 .../cn/group}/internal/mapper/AddressMapper.java   |  6 +-
 .../cn/group}/internal/mapper/AttendeeMapper.java  |  6 +-
 .../group}/internal/mapper/GroupCommandMapper.java | 11 ++--
 .../internal/mapper/GroupDefinitionMapper.java     | 10 +--
 .../cn/group}/internal/mapper/GroupMapper.java     |  8 +--
 .../cn/group}/internal/mapper/MeetingMapper.java   |  8 +--
 .../group}/internal/repository/AddressEntity.java  |  2 +-
 .../internal/repository/AddressRepository.java     |  2 +-
 .../group}/internal/repository/AttendeeEntity.java |  2 +-
 .../internal/repository/AttendeeRepository.java    |  2 +-
 .../internal/repository/GroupCommandEntity.java    |  7 +-
 .../repository/GroupCommandRepository.java         |  2 +-
 .../internal/repository/GroupDefinitionEntity.java |  7 +-
 .../repository/GroupDefinitionRepository.java      |  2 +-
 .../cn/group}/internal/repository/GroupEntity.java |  7 +-
 .../internal/repository/GroupRepository.java       |  2 +-
 .../group}/internal/repository/MeetingEntity.java  | 11 ++--
 .../internal/repository/MeetingRepository.java     | 11 ++--
 .../internal/service/GroupDefinitionService.java   | 10 +--
 .../cn/group}/internal/service/GroupService.java   | 47 +++++++------
 .../group}/rest/GroupDefinitionRestController.java | 23 ++++---
 .../cn/group}/rest/GroupRestController.java        | 51 +++++++--------
 .../cn/group}/rest/MigrationRestController.java    | 12 ++--
 64 files changed, 307 insertions(+), 309 deletions(-)


[fineract-cn-group] 03/40: Merge pull request #1 from myrle-krantz/develop

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group.git

commit 815fb0c32c319c5684de336ba474a89d2a4ea702
Merge: fe3968e 6cc0359
Author: Myrle Krantz <my...@kuelap.io>
AuthorDate: Fri Mar 17 18:13:51 2017 +0100

    Merge pull request #1 from myrle-krantz/develop
    
    Changing name of GroupManager.

 HEADER                                             |  2 +-
 .../client/{GroupClient.java => GroupManager.java} |  2 +-
 build.gradle                                       |  7 +++
 .../src/main/java/io/mifos/group/TestGroup.java    | 50 +++++++++++-----------
 .../java/io/mifos/group/TestGroupDefinition.java   |  8 ++--
 shared.gradle                                      | 10 ++++-
 6 files changed, 46 insertions(+), 33 deletions(-)