MIFOSX-1552 Spring Boot + MariaDB4j, read
http://blog2.vorburger.ch/2014/09/mifos-executable-war-with-mariadb4j.html Signed-off-by: Michael Vorburger <mike@vorburger.ch>
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.common;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.jayway.restassured.RestAssured;
|
||||
import com.jayway.restassured.builder.RequestSpecBuilder;
|
||||
import com.jayway.restassured.builder.ResponseSpecBuilder;
|
||||
import com.jayway.restassured.http.ContentType;
|
||||
import com.jayway.restassured.specification.RequestSpecification;
|
||||
import com.jayway.restassured.specification.ResponseSpecification;
|
||||
|
||||
/**
|
||||
* REST integration tests helper. Intended to encapsulate the current
|
||||
* RestAssured-based implementation as private. May be REST integration tests
|
||||
* should instead be written using e.g. Spring's TestRestTemplate or Square's
|
||||
* Retrofit (already used in the Mifos X Android client).
|
||||
*/
|
||||
public class RestAssuredFixture {
|
||||
|
||||
private final int httpPort;
|
||||
|
||||
private ResponseSpecification responseSpec;
|
||||
private RequestSpecification requestSpec;
|
||||
|
||||
public RestAssuredFixture(int httpPort) {
|
||||
super();
|
||||
this.httpPort = httpPort;
|
||||
Utils.initializeRESTAssured();
|
||||
RestAssured.port = httpPort;
|
||||
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||
this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
||||
}
|
||||
|
||||
public <T> T httpGet(String apiPath, String jsonAttributeToGetBack) {
|
||||
return Utils.performServerGet(this.requestSpec, this.responseSpec, getApiPath(apiPath), jsonAttributeToGetBack);
|
||||
}
|
||||
|
||||
public <T> T httpGet(String apiPath) {
|
||||
return httpGet(apiPath, "");
|
||||
}
|
||||
|
||||
private String getApiPath(String apiPath) {
|
||||
Preconditions.checkArgument(apiPath.startsWith("/"), "trailingApiUrl must start with slash: " + apiPath);
|
||||
return "/mifosng-provider/api/v1" + apiPath + "?tenantIdentifier=default";
|
||||
}
|
||||
|
||||
protected String getApiUrl(String apiPath) {
|
||||
return "http://localhost:" + httpPort + getApiPath(apiPath);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,29 +24,35 @@ import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Util for RestAssured tests. This class here in src/test is copy/pasted :(
|
||||
* from and identical to the one in src/integrationTest; please keep it in sync.
|
||||
* The cunning plan is that, now that we have Spring Boot + MariaDB4j, eventually
|
||||
* do completely away with src/integrationTest and have only src/test.. can you help? ;)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class Utils {
|
||||
|
||||
private static final String LOGIN_URL = "/mifosng-provider/api/v1/authentication?username=mifos&password=password&tenantIdentifier=default";
|
||||
public static final String TENANT_IDENTIFIER = "tenantIdentifier=default";
|
||||
|
||||
private static final String LOGIN_URL = "/mifosng-provider/api/v1/authentication?username=mifos&password=password&" + TENANT_IDENTIFIER;
|
||||
|
||||
public static void initializeRESTAssured() {
|
||||
RestAssured.baseURI ="https://localhost";
|
||||
RestAssured.baseURI = "https://localhost";
|
||||
RestAssured.port = 8443;
|
||||
RestAssured.keystore("../keystore.jks", "openmf");
|
||||
RestAssured.keystore("src/main/resources/keystore.jks", "openmf");
|
||||
}
|
||||
|
||||
public static String loginIntoServerAndGetBase64EncodedAuthenticationKey() {
|
||||
try {
|
||||
System.out.println("-----------------------------------LOGIN-----------------------------------------");
|
||||
String json = RestAssured.post(LOGIN_URL).asString();
|
||||
final String json = RestAssured.post(LOGIN_URL).asString();
|
||||
assertThat("Failed to login into mifosx platform", StringUtils.isBlank(json), is(false));
|
||||
return JsonPath.with(json).get("base64EncodedAuthenticationKey");
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
if (e instanceof HttpHostConnectException) {
|
||||
HttpHostConnectException hh = (HttpHostConnectException) e;
|
||||
fail("Failed to connect to mifosx platform:"+hh.getMessage());
|
||||
final HttpHostConnectException hh = (HttpHostConnectException) e;
|
||||
fail("Failed to connect to mifosx platform:" + hh.getMessage());
|
||||
}
|
||||
|
||||
throw new RuntimeException(e);
|
||||
@@ -55,44 +61,60 @@ public class Utils {
|
||||
|
||||
public static <T> T performServerGet(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||
final String getURL, final String jsonAttributeToGetBack) {
|
||||
String json = given().spec(requestSpec)
|
||||
.expect().spec(responseSpec).log().ifError()
|
||||
.when().get(getURL).andReturn().asString();
|
||||
final String json = given().spec(requestSpec).expect().spec(responseSpec).log().ifError().when().get(getURL).andReturn().asString();
|
||||
return (T) from(json).get(jsonAttributeToGetBack);
|
||||
}
|
||||
|
||||
public static <T> T performServerPost(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||
final String postURL, final String jsonBodyToSend, final String jsonAttributeToGetBack) {
|
||||
String json = given().spec(requestSpec).body(jsonBodyToSend)
|
||||
.expect().spec(responseSpec).log().ifError()
|
||||
.when().post(postURL)
|
||||
final String json = given().spec(requestSpec).body(jsonBodyToSend).expect().spec(responseSpec).log().ifError().when().post(postURL)
|
||||
.andReturn().asString();
|
||||
if (jsonAttributeToGetBack == null) { return (T) json; }
|
||||
return (T) from(json).get(jsonAttributeToGetBack);
|
||||
}
|
||||
|
||||
public static <T> T performServerPut(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||
final String putURL, final String jsonBodyToSend, final String jsonAttributeToGetBack) {
|
||||
final String json = given().spec(requestSpec).body(jsonBodyToSend).expect().spec(responseSpec).log().ifError().when().put(putURL)
|
||||
.andReturn().asString();
|
||||
return (T) from(json).get(jsonAttributeToGetBack);
|
||||
}
|
||||
|
||||
public static <T> T performServerDelete(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||
final String deleteURL, final String jsonAttributeToGetBack) {
|
||||
final String json = given().spec(requestSpec).expect().spec(responseSpec).log().ifError().when().delete(deleteURL).andReturn()
|
||||
.asString();
|
||||
return (T) from(json).get(jsonAttributeToGetBack);
|
||||
}
|
||||
|
||||
public static String convertDateToURLFormat(String dateToBeConvert){
|
||||
SimpleDateFormat oldFormat = new SimpleDateFormat("dd MMMMMM yyyy");
|
||||
SimpleDateFormat newFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
String reformattedStr="";
|
||||
public static String convertDateToURLFormat(final String dateToBeConvert) {
|
||||
final SimpleDateFormat oldFormat = new SimpleDateFormat("dd MMMMMM yyyy");
|
||||
final SimpleDateFormat newFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
String reformattedStr = "";
|
||||
try {
|
||||
reformattedStr = newFormat.format(oldFormat.parse(dateToBeConvert));
|
||||
} catch (ParseException e) {
|
||||
} catch (final ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return reformattedStr;
|
||||
}
|
||||
|
||||
public static String randomStringGenerator(final String prefix, final int len, final String sourceSetString) {
|
||||
int lengthOfSource = sourceSetString.length();
|
||||
Random rnd = new Random();
|
||||
StringBuilder sb = new StringBuilder(len);
|
||||
for (int i = 0; i < len; i++)
|
||||
final int lengthOfSource = sourceSetString.length();
|
||||
final Random rnd = new Random();
|
||||
final StringBuilder sb = new StringBuilder(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
sb.append((sourceSetString).charAt(rnd.nextInt(lengthOfSource)));
|
||||
}
|
||||
return (prefix + (sb.toString()));
|
||||
}
|
||||
|
||||
public static String randomStringGenerator(final String prefix, final int len) {
|
||||
return randomStringGenerator(prefix, len, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
}
|
||||
|
||||
public static String randomNameGenerator(final String prefix, final int lenOfRandomSuffix) {
|
||||
return randomStringGenerator(prefix, lenOfRandomSuffix);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+7
@@ -14,6 +14,13 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
* This integration test ensure that the "production" Spring XML configuration
|
||||
* files (appContext.xml & Co.) are valid. It does not need any database for
|
||||
* that.
|
||||
*
|
||||
* Note: For a simple test like this, contrary to
|
||||
* AbstractSpringBootWithMariaDB4jIntegrationTest, there is no need to use
|
||||
* Boot's SpringApplicationConfiguration here, instead the simpler classic Sring
|
||||
* core ContextConfiguration is sufficient (as long as the
|
||||
* TestsWithoutDatabaseAndNoJobsConfiguration used extends
|
||||
* AbstractApplicationConfiguration).
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = TestsWithoutDatabaseAndNoJobsConfiguration.class)
|
||||
|
||||
+4
-10
@@ -7,13 +7,11 @@ package org.mifosplatform.infrastructure.configuration.spring;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.boot.AbstractApplicationConfiguration;
|
||||
import org.mifosplatform.infrastructure.core.service.TenantDatabaseUpgradeService;
|
||||
import org.mifosplatform.infrastructure.jobs.service.JobRegisterService;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
|
||||
/**
|
||||
* Spring @Configuration which does not require a running database. It also does
|
||||
@@ -21,10 +19,7 @@ import org.springframework.context.annotation.ImportResource;
|
||||
* background jobs. For some integration tests, this may be perfectly sufficient
|
||||
* (and faster to run such tests).
|
||||
*/
|
||||
@Configuration
|
||||
// We do NOT want the testContext.xml here, but the real one!
|
||||
@ImportResource("classpath*:META-INF/spring/appContext.xml")
|
||||
public class TestsWithoutDatabaseAndNoJobsConfiguration {
|
||||
public class TestsWithoutDatabaseAndNoJobsConfiguration extends AbstractApplicationConfiguration {
|
||||
|
||||
/**
|
||||
* Override TenantDatabaseUpgradeService binding, because the real one has a @PostConstruct
|
||||
@@ -32,8 +27,7 @@ public class TestsWithoutDatabaseAndNoJobsConfiguration {
|
||||
*/
|
||||
@Bean
|
||||
public TenantDatabaseUpgradeService tenantDatabaseUpgradeService() {
|
||||
return new TenantDatabaseUpgradeService(null) {
|
||||
|
||||
return new TenantDatabaseUpgradeService(null, null, null) {
|
||||
@Override
|
||||
public void upgradeAllTenants() {
|
||||
// NOOP
|
||||
@@ -60,4 +54,4 @@ public class TestsWithoutDatabaseAndNoJobsConfiguration {
|
||||
DataSource mockDataSource = Mockito.mock(DataSource.class, Mockito.RETURNS_MOCKS);
|
||||
return mockDataSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.core.boot.tests;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mifosplatform.ServerWithMariaDB4jApplication;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = ServerWithMariaDB4jApplication.Configuration.class)
|
||||
@WebAppConfiguration
|
||||
@IntegrationTest({ "server.port=0", "management.port=0", "mariaDB4j.port=0", "mariaDB4j.dataDir=null" })
|
||||
public abstract class AbstractSpringBootWithMariaDB4jIntegrationTest {
|
||||
|
||||
// do NOT put any helper methods here!
|
||||
// it's much better to use composition instead of inheritance
|
||||
// so write a test util ("fixture") and use it as a field in your test
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.core.boot.tests;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mifosplatform.infrastructure.core.boot.EmbeddedTomcatWithSSLConfiguration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
public class EmbeddedTomcatWithSSLConfigurationTest {
|
||||
|
||||
@Test
|
||||
public void testGetFileWithFileResource() throws IOException {
|
||||
// Test class probably isn't in a JAR
|
||||
checkClassResource(getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFileWithClasspathResource() throws IOException {
|
||||
// Spring Resource class probably is in a JAR
|
||||
File f1 = checkClassResource(Resource.class);
|
||||
f1.delete();
|
||||
checkClassResource(Resource.class);
|
||||
}
|
||||
|
||||
protected File checkClassResource(Class<?> clazz) throws IOException {
|
||||
String testClasspathResourcePath = clazz.getCanonicalName().replace('.', '/') + ".class";
|
||||
Resource r = new ClassPathResource(testClasspathResourcePath);
|
||||
File f = new EmbeddedTomcatWithSSLConfiguration().getFile(r);
|
||||
assertTrue(f.exists());
|
||||
f = new EmbeddedTomcatWithSSLConfiguration().getFile(r);
|
||||
assertTrue(f.exists());
|
||||
return f;
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.core.boot.tests;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mifosplatform.ServerApplication;
|
||||
import org.mifosplatform.common.RestAssuredFixture;
|
||||
|
||||
/**
|
||||
* This is an integration test for the Spring Boot launch stuff.
|
||||
*
|
||||
* @see ServerApplication
|
||||
*/
|
||||
public class SpringBootServerLoginTest extends AbstractSpringBootWithMariaDB4jIntegrationTest {
|
||||
|
||||
protected RestAssuredFixture util;
|
||||
|
||||
@Test
|
||||
public void hasMifosPlatformStarted() {
|
||||
util = new RestAssuredFixture(8443);
|
||||
List<Map<String, String>> response = util.httpGet("/users");
|
||||
assertThat(response.get(0).get("username"), is("mifos"));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user