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:
Michael Vorburger
2014-09-22 04:04:15 +02:00
parent 0d8bd285dc
commit 4b0658a685
248 changed files with 1830 additions and 969 deletions
@@ -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);
}
}
@@ -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)
@@ -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;
}
}
}
@@ -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
}
@@ -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;
}
}
@@ -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"));
}
}