Merge pull request #12 from myrle-krantz/develop
First steps towards automatic, scheduled, calculation of interest.
diff --git a/component-test/src/main/java/io/mifos/portfolio/AbstractPortfolioTest.java b/component-test/src/main/java/io/mifos/portfolio/AbstractPortfolioTest.java
index a2eaf37..0758a33 100644
--- a/component-test/src/main/java/io/mifos/portfolio/AbstractPortfolioTest.java
+++ b/component-test/src/main/java/io/mifos/portfolio/AbstractPortfolioTest.java
@@ -30,8 +30,9 @@
import io.mifos.portfolio.api.v1.domain.Product;
import io.mifos.portfolio.api.v1.events.CaseEvent;
import io.mifos.portfolio.api.v1.events.EventConstants;
-import io.mifos.portfolio.service.PortfolioServiceConfiguration;
+import io.mifos.portfolio.service.config.PortfolioServiceConfiguration;
import io.mifos.portfolio.service.internal.util.AccountingAdapter;
+import io.mifos.portfolio.service.internal.util.RhythmAdapter;
import org.junit.*;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
@@ -41,6 +42,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Bean;
@@ -84,7 +86,8 @@
return LoggerFactory.getLogger("test-logger");
}
@Bean()
- public AccountingAdapter accountingAdapter(final LedgerManager ledgerManager)
+ public AccountingAdapter accountingAdapter(@SuppressWarnings("SpringJavaAutowiringInspection")
+ final LedgerManager ledgerManager)
{
final AccountingAdapter spy = Mockito.spy(new AccountingAdapter(ledgerManager));
doReturn(true).when(spy).accountAssignmentRepresentsRealAccount(any());
@@ -121,6 +124,10 @@
@Autowired
IndividualLending individualLending;
+ @SuppressWarnings("unused")
+ @MockBean
+ RhythmAdapter rhythmAdapter;
+
@Before
public void prepTest() {
userContext = this.tenantApplicationSecurityEnvironment.createAutoUserContext(TEST_USER);
diff --git a/service/build.gradle b/service/build.gradle
index e5a945a..f4f79d6 100644
--- a/service/build.gradle
+++ b/service/build.gradle
@@ -33,6 +33,7 @@
[group: 'org.springframework.boot', name: 'spring-boot-starter-jetty'],
[group: 'io.mifos.portfolio', name: 'api', version: project.version],
[group: 'io.mifos.rhythm', name: 'spi', version: versions.mifosrhythm],
+ [group: 'io.mifos.rhythm', name: 'api', version: versions.mifosrhythm],
[group: 'io.mifos.accounting', name: 'api', version: versions.frameworkaccounting],
[group: 'io.mifos.anubis', name: 'library', version: versions.frameworkanubis],
[group: 'com.google.code.gson', name: 'gson'],
diff --git a/service/src/main/java/io/mifos/portfolio/service/PortfolioApplication.java b/service/src/main/java/io/mifos/portfolio/service/PortfolioApplication.java
index 5c556e5..58e0209 100644
--- a/service/src/main/java/io/mifos/portfolio/service/PortfolioApplication.java
+++ b/service/src/main/java/io/mifos/portfolio/service/PortfolioApplication.java
@@ -15,6 +15,7 @@
*/
package io.mifos.portfolio.service;
+import io.mifos.portfolio.service.config.PortfolioServiceConfiguration;
import org.springframework.boot.SpringApplication;
public class PortfolioApplication {
diff --git a/service/src/main/java/io/mifos/portfolio/service/config/PortfolioProperties.java b/service/src/main/java/io/mifos/portfolio/service/config/PortfolioProperties.java
new file mode 100644
index 0000000..98936f6
--- /dev/null
+++ b/service/src/main/java/io/mifos/portfolio/service/config/PortfolioProperties.java
@@ -0,0 +1,44 @@
+/*
+ * 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.portfolio.service.config;
+
+import io.mifos.core.lang.validation.constraints.ValidIdentifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ * @author Myrle Krantz
+ */
+@SuppressWarnings("unused")
+@Component
+@ConfigurationProperties(prefix="portfolio")
+@Validated
+public class PortfolioProperties {
+ @ValidIdentifier
+ private String bookInterestAsUser;
+
+ public PortfolioProperties() {
+ }
+
+ public String getBookInterestAsUser() {
+ return bookInterestAsUser;
+ }
+
+ public void setBookInterestAsUser(String bookInterestAsUser) {
+ this.bookInterestAsUser = bookInterestAsUser;
+ }
+}
diff --git a/service/src/main/java/io/mifos/portfolio/service/PortfolioServiceConfiguration.java b/service/src/main/java/io/mifos/portfolio/service/config/PortfolioServiceConfiguration.java
similarity index 87%
rename from service/src/main/java/io/mifos/portfolio/service/PortfolioServiceConfiguration.java
rename to service/src/main/java/io/mifos/portfolio/service/config/PortfolioServiceConfiguration.java
index f9838b7..adcb3b3 100644
--- a/service/src/main/java/io/mifos/portfolio/service/PortfolioServiceConfiguration.java
+++ b/service/src/main/java/io/mifos/portfolio/service/config/PortfolioServiceConfiguration.java
@@ -13,17 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.portfolio.service;
+package io.mifos.portfolio.service.config;
import com.google.gson.Gson;
+import io.mifos.accounting.api.v1.client.LedgerManager;
import io.mifos.anubis.config.EnableAnubis;
-import io.mifos.individuallending.IndividualLendingConfiguration;
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.EnableApplicationName;
import io.mifos.core.lang.config.EnableServiceException;
import io.mifos.core.lang.config.EnableTenantContext;
import io.mifos.core.mariadb.config.EnableMariaDB;
+import io.mifos.individuallending.IndividualLendingConfiguration;
+import io.mifos.portfolio.service.ServiceConstants;
+import io.mifos.rhythm.api.v1.client.RhythmManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -52,10 +56,13 @@
@ComponentScan({
"io.mifos.portfolio.service.rest",
"io.mifos.portfolio.service.internal",
+ "io.mifos.portfolio.service.config",
})
@EnableJpaRepositories(basePackages = "io.mifos.portfolio.service.internal.repository")
@EntityScan(basePackages = "io.mifos.portfolio.service.internal.repository")
-@EnableFeignClients(basePackages = {"io.mifos.accounting.api.v1"})
+@EnableFeignClients(clients = {LedgerManager.class, RhythmManager.class})
+@RibbonClient(name = "portfolio-v1")
+@EnableApplicationName
@Import(IndividualLendingConfiguration.class)
public class PortfolioServiceConfiguration extends WebMvcConfigurerAdapter {
diff --git a/service/src/main/java/io/mifos/portfolio/service/internal/command/handler/BeatPublishCommandHandler.java b/service/src/main/java/io/mifos/portfolio/service/internal/command/handler/BeatPublishCommandHandler.java
index b4047f1..bfa9e56 100644
--- a/service/src/main/java/io/mifos/portfolio/service/internal/command/handler/BeatPublishCommandHandler.java
+++ b/service/src/main/java/io/mifos/portfolio/service/internal/command/handler/BeatPublishCommandHandler.java
@@ -1,3 +1,18 @@
+/*
+ * 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.portfolio.service.internal.command.handler;
import io.mifos.core.command.annotation.Aggregate;
diff --git a/service/src/main/java/io/mifos/portfolio/service/internal/command/handler/InitializeCommandHandler.java b/service/src/main/java/io/mifos/portfolio/service/internal/command/handler/InitializeCommandHandler.java
index 454b40f..ba049a5 100644
--- a/service/src/main/java/io/mifos/portfolio/service/internal/command/handler/InitializeCommandHandler.java
+++ b/service/src/main/java/io/mifos/portfolio/service/internal/command/handler/InitializeCommandHandler.java
@@ -22,6 +22,7 @@
import io.mifos.core.command.annotation.CommandHandler;
import io.mifos.core.command.annotation.EventEmitter;
import io.mifos.core.mariadb.domain.FlywayFactoryBean;
+import io.mifos.portfolio.service.internal.util.RhythmAdapter;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -37,15 +38,18 @@
private final Logger logger;
private final DataSource dataSource;
private final FlywayFactoryBean flywayFactoryBean;
+ private final RhythmAdapter rhythmAdapter;
@Autowired
public InitializeCommandHandler(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
- final DataSource dataSource,
- final FlywayFactoryBean flywayFactoryBean) {
+ final DataSource dataSource,
+ final FlywayFactoryBean flywayFactoryBean,
+ final RhythmAdapter rhythmAdapter) {
super();
this.logger = logger;
this.dataSource = dataSource;
this.flywayFactoryBean = flywayFactoryBean;
+ this.rhythmAdapter = rhythmAdapter;
}
@CommandHandler
@@ -53,6 +57,7 @@
public String initialize(final InitializeServiceCommand initializeServiceCommand) {
this.logger.debug("Start service migration.");
this.flywayFactoryBean.create(this.dataSource).migrate();
+ rhythmAdapter.request24Beats();
return EventConstants.INITIALIZE;
}
}
diff --git a/service/src/main/java/io/mifos/portfolio/service/internal/util/AccountingAdapter.java b/service/src/main/java/io/mifos/portfolio/service/internal/util/AccountingAdapter.java
index 4f2c59a..9d33487 100644
--- a/service/src/main/java/io/mifos/portfolio/service/internal/util/AccountingAdapter.java
+++ b/service/src/main/java/io/mifos/portfolio/service/internal/util/AccountingAdapter.java
@@ -18,8 +18,6 @@
import io.mifos.accounting.api.v1.client.AccountNotFoundException;
import io.mifos.accounting.api.v1.client.LedgerManager;
import io.mifos.accounting.api.v1.client.LedgerNotFoundException;
-import io.mifos.accounting.api.v1.domain.Account;
-import io.mifos.accounting.api.v1.domain.Ledger;
import io.mifos.portfolio.api.v1.domain.AccountAssignment;
import io.mifos.portfolio.api.v1.domain.ChargeDefinition;
import org.springframework.beans.factory.annotation.Autowired;
@@ -42,7 +40,7 @@
private final LedgerManager ledgerManager;
@Autowired
- public AccountingAdapter(final LedgerManager ledgerManager) {
+ public AccountingAdapter(@SuppressWarnings("SpringJavaAutowiringInspection") final LedgerManager ledgerManager) {
this.ledgerManager = ledgerManager;
}
@@ -72,7 +70,7 @@
public boolean accountAssignmentRepresentsRealAccount(final AccountAssignment accountAssignment) {
if (accountAssignment.getAccountIdentifier() != null) {
try {
- final Account account = ledgerManager.findAccount(accountAssignment.getAccountIdentifier());
+ ledgerManager.findAccount(accountAssignment.getAccountIdentifier());
return true;
}
catch (final AccountNotFoundException e){
@@ -81,7 +79,7 @@
}
else if (accountAssignment.getLedgerIdentifier() != null) {
try {
- final Ledger ledger = ledgerManager.findLedger(accountAssignment.getLedgerIdentifier());
+ ledgerManager.findLedger(accountAssignment.getLedgerIdentifier());
return true;
}
catch (final LedgerNotFoundException e){
diff --git a/service/src/main/java/io/mifos/portfolio/service/internal/util/RhythmAdapter.java b/service/src/main/java/io/mifos/portfolio/service/internal/util/RhythmAdapter.java
new file mode 100644
index 0000000..0d9716f
--- /dev/null
+++ b/service/src/main/java/io/mifos/portfolio/service/internal/util/RhythmAdapter.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.portfolio.service.internal.util;
+
+import io.mifos.core.lang.ApplicationName;
+import io.mifos.portfolio.service.ServiceConstants;
+import io.mifos.rhythm.api.v1.client.RhythmManager;
+import io.mifos.rhythm.api.v1.domain.Beat;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+
+import java.util.stream.Stream;
+
+/**
+ * @author Myrle Krantz
+ */
+@Component
+public class RhythmAdapter {
+ final private RhythmManager rhythmManager;
+ final private ApplicationName applicationName;
+ final private Logger logger;
+ @Autowired
+ public RhythmAdapter(@SuppressWarnings("SpringJavaAutowiringInspection") final RhythmManager rhythmManager,
+ final ApplicationName applicationName,
+ final @Qualifier(ServiceConstants.LOGGER_NAME)Logger logger) {
+ this.rhythmManager = rhythmManager;
+ this.applicationName = applicationName;
+ this.logger = logger;
+ }
+
+ public void request24Beats() {
+ Stream.iterate(0, x -> x+1).limit(24)
+ .map(RhythmAdapter::defineBeat)
+ .forEach(this::createBeat);
+ }
+
+ private static Beat defineBeat(final int alignmentHour) {
+ final Beat beat = new Beat();
+ beat.setAlignmentHour(alignmentHour);
+ beat.setIdentifier("alignment" + alignmentHour);
+ return beat;
+ }
+
+ private void createBeat(final Beat beat) {
+ try {
+ rhythmManager.createBeat(applicationName.toString(), beat);
+ }
+ catch (final Exception e) {
+ logger.error("Creating interest calculation beat {} failed with exception e.", beat, e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/service/src/main/resources/application.yml b/service/src/main/resources/application.yml
index d50619f..a15f8b7 100644
--- a/service/src/main/resources/application.yml
+++ b/service/src/main/resources/application.yml
@@ -80,4 +80,7 @@
system:
publicKey:
exponent: 65537
- modulus: 21188023007955682867939457181271038457216099278949187456460742046123672432355777599460689470319454021384777684967830053993002724303461144745107517305075315187397862430851722919529943465029389248042840364475999768651348557757734298942211509744303551097953258597691851996692366468761965138767429272032120029271744611798874201312092155969603381492096789028306859853929900848124928201000469425135976322303229632628092728624143573273277870884919055453251617011673264035045823652246768583219018126865521694880333238485410601803458379987829318615730229086183405850999386270584135805252231189505197494383178133769189765423639
\ No newline at end of file
+ modulus: 21188023007955682867939457181271038457216099278949187456460742046123672432355777599460689470319454021384777684967830053993002724303461144745107517305075315187397862430851722919529943465029389248042840364475999768651348557757734298942211509744303551097953258597691851996692366468761965138767429272032120029271744611798874201312092155969603381492096789028306859853929900848124928201000469425135976322303229632628092728624143573273277870884919055453251617011673264035045823652246768583219018126865521694880333238485410601803458379987829318615730229086183405850999386270584135805252231189505197494383178133769189765423639
+
+portfolio:
+ bookInterestAsUser: interest_user
\ No newline at end of file