From f87d055724b29993670c8eb2104e8c8f3378b73c Mon Sep 17 00:00:00 2001 From: Gustavo Martin Morcuende Date: Sun, 2 Oct 2016 20:29:30 +0200 Subject: [PATCH] First commit --- pom.xml | 311 +++++++++++++++++++++ .../prueba/core/context/ApplicationContext.java | 9 + .../integration/database/DataBaseAccess.java | 20 ++ .../database/impl/DataBaseAccessImpl.java | 59 ++++ .../integration/datasource/DoDataSource.java | 13 + .../datasource/impl/DoDataSourceContext.java | 66 +++++ .../liquibase/impl/LiquibaseContext.java | 69 +++++ .../application/context/ApplicationWebContext.java | 29 ++ src/main/resources/liquibase/changeLogs.xml | 16 ++ src/main/resources/liquibase/ddlChangelog.xml | 118 ++++++++ src/main/resources/liquibase/dml.sql | 32 +++ src/main/resources/liquibase/dmlChangelog.xml | 16 ++ src/main/resources/log4j2.xml | 37 +++ .../context/ApplicationContextIntegrationTest.java | 22 ++ .../impl/LiquibaseContextIntegrationTest.java | 64 +++++ 15 files changed, 881 insertions(+) create mode 100644 pom.xml create mode 100644 src/main/java/com/prueba/core/context/ApplicationContext.java create mode 100644 src/main/java/com/prueba/core/context/integration/database/DataBaseAccess.java create mode 100644 src/main/java/com/prueba/core/context/integration/database/impl/DataBaseAccessImpl.java create mode 100644 src/main/java/com/prueba/core/context/integration/datasource/DoDataSource.java create mode 100644 src/main/java/com/prueba/core/context/integration/datasource/impl/DoDataSourceContext.java create mode 100644 src/main/java/com/prueba/core/context/integration/liquibase/impl/LiquibaseContext.java create mode 100644 src/main/java/com/prueba/core/web/application/context/ApplicationWebContext.java create mode 100644 src/main/resources/liquibase/changeLogs.xml create mode 100644 src/main/resources/liquibase/ddlChangelog.xml create mode 100644 src/main/resources/liquibase/dml.sql create mode 100644 src/main/resources/liquibase/dmlChangelog.xml create mode 100644 src/main/resources/log4j2.xml create mode 100644 src/test/java/com/prueba/core/context/ApplicationContextIntegrationTest.java create mode 100644 src/test/java/com/prueba/core/context/integration/liquibase/impl/LiquibaseContextIntegrationTest.java diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9b2aed5 --- /dev/null +++ b/pom.xml @@ -0,0 +1,311 @@ + + 4.0.0 + com.prueba + http-services + 1.0-SNAPSHOT + HTTP SERVICES + https://gumartinm.name/ + HTTP SERVICES + + Gustavo Martin Morcuende + https://gumartinm.name/ + + + scm:git:https://git.gumartinm.name/Prueba + https://git.gumartinm.name/Prueba + + + + UTF-8 + UTF-8 + 2.10.4 + 3.0.1 + + + ${project.basedir}/target/jacoco-it.exec + ${project.basedir}/target/jacoco.exec + + false + true + + + + + development + + development + Desarrollo local + + + true + + + + integration + + integration + Integration + false + + + + production + + production + Production + false + + + + + + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.6.1 + + + + org.apache.logging.log4j + log4j-core + 2.6.1 + + + + org.slf4j + jcl-over-slf4j + 1.7.21 + + + + + + com.fasterxml.jackson.core + jackson-databind + 2.8.3 + + + + + org.liquibase + liquibase-core + 3.5.2 + + + com.h2database + h2 + 1.4.192 + + + + + com.mchange + c3p0 + 0.9.5.2 + + + + + junit + junit + 4.12 + test + + + org.mockito + mockito-core + 2.0.43-beta + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.1 + + ${project.build.sourceEncoding} + + + + + org.jacoco + jacoco-maven-plugin + 0.7.7.201606060606 + + + + pre-unit-test + + prepare-agent + + + + ${jacoco.ut.execution.data.file} + + surefireArgLine + + + + + post-unit-test + test + + report + + + + ${jacoco.ut.execution.data.file} + + ${project.reporting.outputDirectory}/jacoco-ut + + + + + pre-integration-test + pre-integration-test + + prepare-agent + + + + ${jacoco.it.execution.data.file} + + failsafeArgLine + + + + + post-integration-test + post-integration-test + + report + + + + ${jacoco.it.execution.data.file} + + ${project.reporting.outputDirectory}/jacoco-it + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.jacoco + jacoco-maven-plugin + [0.5,) + + + prepare-agent + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + + org.apache.maven.surefire + surefire-junit47 + 2.19.1 + + + + + -Dfile.encoding=${project.build.sourceEncoding} + ${surefireArgLine} + + ${skip.unit.tests} + + + **/*IT.java + **/*IntegrationTest.java + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.19.1 + + + + integration-test + verify + + + + ${failsafeArgLine} + + + ${skip.integration.tests} + + **/*IT.java + **/*IntegrationTest.java + + + + + + + + + + diff --git a/src/main/java/com/prueba/core/context/ApplicationContext.java b/src/main/java/com/prueba/core/context/ApplicationContext.java new file mode 100644 index 0000000..3d5b8ff --- /dev/null +++ b/src/main/java/com/prueba/core/context/ApplicationContext.java @@ -0,0 +1,9 @@ +package com.prueba.core.context; + +import javax.sql.DataSource; + +public interface ApplicationContext { + + DataSource getDataSource(); + +} diff --git a/src/main/java/com/prueba/core/context/integration/database/DataBaseAccess.java b/src/main/java/com/prueba/core/context/integration/database/DataBaseAccess.java new file mode 100644 index 0000000..4a47d0d --- /dev/null +++ b/src/main/java/com/prueba/core/context/integration/database/DataBaseAccess.java @@ -0,0 +1,20 @@ +package com.prueba.core.context.integration.database; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; +import java.util.Map; + +public interface DataBaseAccess { + + public interface ExecuteStatement { + TResult executeStatement(final Statement statement) throws SQLException; + } + + public interface ExecuteResultSet { + List> executeResultSet(final TResult resultSet) throws SQLException; + } + + List> executeQuery(final String query, final ExecuteResultSet executeResultSet); +} diff --git a/src/main/java/com/prueba/core/context/integration/database/impl/DataBaseAccessImpl.java b/src/main/java/com/prueba/core/context/integration/database/impl/DataBaseAccessImpl.java new file mode 100644 index 0000000..ca335a1 --- /dev/null +++ b/src/main/java/com/prueba/core/context/integration/database/impl/DataBaseAccessImpl.java @@ -0,0 +1,59 @@ +package com.prueba.core.context.integration.database.impl; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; +import java.util.Map; + +import javax.sql.DataSource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.prueba.core.context.integration.database.DataBaseAccess; +import com.prueba.core.context.integration.datasource.impl.DoDataSourceContext; + +public class DataBaseAccessImpl implements DataBaseAccess { + private static final Logger LOGGER = LoggerFactory.getLogger(DataBaseAccessImpl.class); + + @Override + public List> executeQuery(String query, ExecuteResultSet executeResultSet) { + List> result = null; + try { + result = this.executeQueryThrowable(query, executeResultSet); + } catch (SQLException exception) { + LOGGER.error("Query error: ", exception); + } + + return result; + } + + protected List> executeQueryThrowable(String query, ExecuteResultSet executeResultSet) throws SQLException { + final DataSource dataSource = DoDataSourceContext.getInstance().getDataSource(); + try { + final Connection connection = dataSource.getConnection(); + + return this.doExecuteQuery( + connection, + statement -> statement.executeQuery(query), + executeResultSet + ); + } finally { + dataSource.getConnection().close(); + } + } + + protected List> doExecuteQuery (final Connection connection, + final ExecuteStatement executeStatement, + final ExecuteResultSet executeResultSet) throws SQLException { + + try (final Statement statement = connection.createStatement(); + final ResultSet answer = executeStatement.executeStatement(statement)) { + return executeResultSet.executeResultSet(answer); + } + + } + +} diff --git a/src/main/java/com/prueba/core/context/integration/datasource/DoDataSource.java b/src/main/java/com/prueba/core/context/integration/datasource/DoDataSource.java new file mode 100644 index 0000000..7b8373d --- /dev/null +++ b/src/main/java/com/prueba/core/context/integration/datasource/DoDataSource.java @@ -0,0 +1,13 @@ +package com.prueba.core.context.integration.datasource; + +import javax.sql.DataSource; + +public interface DoDataSource { + + /** + * Returns DataSource + * + * @return the created DataSource object + */ + DataSource getDataSource(); +} diff --git a/src/main/java/com/prueba/core/context/integration/datasource/impl/DoDataSourceContext.java b/src/main/java/com/prueba/core/context/integration/datasource/impl/DoDataSourceContext.java new file mode 100644 index 0000000..bb7779d --- /dev/null +++ b/src/main/java/com/prueba/core/context/integration/datasource/impl/DoDataSourceContext.java @@ -0,0 +1,66 @@ +package com.prueba.core.context.integration.datasource.impl; + +import java.beans.PropertyVetoException; + +import javax.sql.DataSource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.mchange.v2.c3p0.ComboPooledDataSource; +import com.prueba.core.context.integration.datasource.DoDataSource; + +public class DoDataSourceContext implements DoDataSource { + private static final Logger LOGGER = LoggerFactory.getLogger(DoDataSourceContext.class); + private static final String DRIVER_CLASS = "org.h2.Driver"; + private static final String JDBC_URL = "jdbc:h2:mem:PRUEBA;INIT=create schema if not exists PRUEBA\\;SET SCHEMA PRUEBA;MODE=DB2;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"; + private static final String USERNAME = "sa"; + private static final String PASSWORD = ""; + + private final ComboPooledDataSource pool; + + private DoDataSourceContext(ComboPooledDataSource pool) { + this.pool = pool; + } + + private static class DoDataSourceContextHolder { + private static final DoDataSourceContext INSTANCE = new DoDataSourceContext(new ComboPooledDataSource()); + } + + public static DoDataSource getInstance() { + return DoDataSourceContextHolder.INSTANCE; + } + + @Override + public DataSource getDataSource() { + + DataSource dataSource = null; + try { + dataSource = doDataSourceThrowable(); + } catch (PropertyVetoException exception) { + LOGGER.error("DataSource init error", exception); + + throw new IllegalStateException("DataSource init error", exception); + } + + return dataSource; + } + + private DataSource doDataSourceThrowable() throws PropertyVetoException { + pool.setUser(USERNAME); + pool.setPassword(PASSWORD); + pool.setDriverClass(DRIVER_CLASS); + pool.setJdbcUrl(JDBC_URL); + pool.setInitialPoolSize(5); + pool.setMaxPoolSize(35); + pool.setMinPoolSize(10); + pool.setAcquireIncrement(1); + pool.setAcquireRetryAttempts(5); + pool.setAcquireRetryDelay(1000); + pool.setAutomaticTestTable("con_test"); + pool.setCheckoutTimeout(5000); + + return pool; + } + +} diff --git a/src/main/java/com/prueba/core/context/integration/liquibase/impl/LiquibaseContext.java b/src/main/java/com/prueba/core/context/integration/liquibase/impl/LiquibaseContext.java new file mode 100644 index 0000000..6b87b26 --- /dev/null +++ b/src/main/java/com/prueba/core/context/integration/liquibase/impl/LiquibaseContext.java @@ -0,0 +1,69 @@ +package com.prueba.core.context.integration.liquibase.impl; + +import java.sql.Connection; +import java.sql.SQLException; + +import javax.sql.DataSource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import liquibase.Contexts; +import liquibase.LabelExpression; +import liquibase.Liquibase; +import liquibase.database.Database; +import liquibase.database.DatabaseFactory; +import liquibase.database.jvm.JdbcConnection; +import liquibase.exception.DatabaseException; +import liquibase.exception.LiquibaseException; +import liquibase.resource.ClassLoaderResourceAccessor; +import liquibase.resource.CompositeResourceAccessor; +import liquibase.resource.FileSystemResourceAccessor; +import liquibase.resource.ResourceAccessor; + +public class LiquibaseContext { + private static final Logger LOGGER = LoggerFactory.getLogger(LiquibaseContext.class); + private static final String CHANGE_LOG_FILE = "liquibase/changeLogs.xml"; + private static final String CONTEXTS = null; + private static final String LABELS = null; + private static final String DEFAULT_SCHEMA = "PRUEBA"; + + private final DataSource dataSource; + + public LiquibaseContext(DataSource dataSource) { + this.dataSource = dataSource; + } + + public void init() { + try { + this.initThrowable(); + } catch (SQLException | LiquibaseException exception) { + LOGGER.error("Liquibase init error: ", exception); + + throw new IllegalStateException("Liquibase init error", exception); + } + } + + protected void initThrowable() throws SQLException, DatabaseException, LiquibaseException { + final Connection connection = this.dataSource.getConnection(); + Database database = null; + try { + final Thread currentThread = Thread.currentThread(); + final ClassLoader contextClassLoader = currentThread.getContextClassLoader(); + final ResourceAccessor threadClFO = new ClassLoaderResourceAccessor(contextClassLoader); + final ResourceAccessor clFO = new ClassLoaderResourceAccessor(); + final ResourceAccessor fsFO = new FileSystemResourceAccessor(); + + database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection)); + database.setDefaultSchemaName(DEFAULT_SCHEMA); + + final Liquibase liquibase = new Liquibase(CHANGE_LOG_FILE, new CompositeResourceAccessor(clFO, fsFO, threadClFO), database); + liquibase.update(new Contexts(CONTEXTS), new LabelExpression(LABELS)); + } finally { + if (database != null) { + database.close(); + } + } + + } +} diff --git a/src/main/java/com/prueba/core/web/application/context/ApplicationWebContext.java b/src/main/java/com/prueba/core/web/application/context/ApplicationWebContext.java new file mode 100644 index 0000000..9d2c7fe --- /dev/null +++ b/src/main/java/com/prueba/core/web/application/context/ApplicationWebContext.java @@ -0,0 +1,29 @@ +package com.prueba.core.web.application.context; + +import javax.sql.DataSource; + +import com.prueba.core.context.ApplicationContext; +import com.prueba.core.context.integration.datasource.impl.DoDataSourceContext; + + +public class ApplicationWebContext implements ApplicationContext { + private final DataSource dataSource; + + private ApplicationWebContext() { + this.dataSource = DoDataSourceContext.getInstance().getDataSource(); + } + + private static class ApplicationWebContextHolder { + private static final ApplicationContext INSTANCE = new ApplicationWebContext(); + } + + public static ApplicationContext getInstance() { + return ApplicationWebContextHolder.INSTANCE; + } + + @Override + public DataSource getDataSource() { + return this.dataSource; + } + +} diff --git a/src/main/resources/liquibase/changeLogs.xml b/src/main/resources/liquibase/changeLogs.xml new file mode 100644 index 0000000..a393fc5 --- /dev/null +++ b/src/main/resources/liquibase/changeLogs.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/src/main/resources/liquibase/ddlChangelog.xml b/src/main/resources/liquibase/ddlChangelog.xml new file mode 100644 index 0000000..d647999 --- /dev/null +++ b/src/main/resources/liquibase/ddlChangelog.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/liquibase/dml.sql b/src/main/resources/liquibase/dml.sql new file mode 100644 index 0000000..abbb353 --- /dev/null +++ b/src/main/resources/liquibase/dml.sql @@ -0,0 +1,32 @@ +-- roles de aplicación +INSERT INTO APPLICATION_ROLE (CODE,DESCRIPTION) values +('ROLE_APP_PAGE_1', 'App page 1 access'), +('ROLE_APP_PAGE_2', 'App page 2 access'), +('ROLE_APP_PAGE_3', 'App page 3 access'), +('ROLE_APP_ADMIN', 'App Admin access'); + + +INSERT INTO APPLICATION_RESOURCE (URL_PATTERN, HTTP_METHOD) values +('/app/page_1.html', 'GET'), +('/app/page_2.html', 'GET'), +('/app/page_3.html', 'GET'), +('/app/{username}', 'GET'), +('/app/{username}', 'PUT'), +('/app/{username}', 'POST'); + + +INSERT INTO APPLICATION_RESOURCE_APPLICATION_ROLE (APPLICATION_RESOURCE_URL_PATTERN, APPLICATION_RESOURCE_HTTP_METHOD, APPLICATION_ROLE_CODE) values +('/app/page_1.html', 'GET', 'ROLE_APP_PAGE_1'), +('/app/page_2.html', 'GET', 'ROLE_APP_PAGE_2'), +('/app/page_3.html', 'GET', 'ROLE_APP_PAGE_3'), +('/app/{username}', 'GET', 'ROLE_APP_PAGE_1'), +('/app/{username}', 'GET', 'ROLE_APP_PAGE_2'), +('/app/{username}', 'GET', 'ROLE_APP_PAGE_3'), +('/app/{username}', 'GET', 'ROLE_APP_ADMIN'), +('/app/{username}', 'PUT', 'ROLE_APP_ADMIN'), +('/app/{username}', 'POST', 'ROLE_APP_ADMIN'); + + +INSERT INTO ACCOUNT (CODE, NAME, SURNAME, PASSWORD, APPLICATION_ROLE_CODE) values +('GUMARTIN', 'Gustavo', 'Martin Morcuende', 'lame', 'ROLE_APP_ADMIN'); + diff --git a/src/main/resources/liquibase/dmlChangelog.xml b/src/main/resources/liquibase/dmlChangelog.xml new file mode 100644 index 0000000..a47d06d --- /dev/null +++ b/src/main/resources/liquibase/dmlChangelog.xml @@ -0,0 +1,16 @@ + + + + + + diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml new file mode 100644 index 0000000..2cf5f88 --- /dev/null +++ b/src/main/resources/log4j2.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/java/com/prueba/core/context/ApplicationContextIntegrationTest.java b/src/test/java/com/prueba/core/context/ApplicationContextIntegrationTest.java new file mode 100644 index 0000000..5b1e09a --- /dev/null +++ b/src/test/java/com/prueba/core/context/ApplicationContextIntegrationTest.java @@ -0,0 +1,22 @@ +package com.prueba.core.context; + +import static org.junit.Assert.assertNotNull; + +import javax.sql.DataSource; + +import org.junit.Test; + +import com.prueba.core.web.application.context.ApplicationWebContext; + +public class ApplicationContextIntegrationTest { + + @Test + public void whenGetDataSourceThenReturnCreatedDataSource() { + final ApplicationContext context = ApplicationWebContext.getInstance(); + + final DataSource dataSource = context.getDataSource(); + + assertNotNull(dataSource); + } + +} diff --git a/src/test/java/com/prueba/core/context/integration/liquibase/impl/LiquibaseContextIntegrationTest.java b/src/test/java/com/prueba/core/context/integration/liquibase/impl/LiquibaseContextIntegrationTest.java new file mode 100644 index 0000000..06a3cd6 --- /dev/null +++ b/src/test/java/com/prueba/core/context/integration/liquibase/impl/LiquibaseContextIntegrationTest.java @@ -0,0 +1,64 @@ +package com.prueba.core.context.integration.liquibase.impl; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.sql.DataSource; + +import org.junit.Test; + +import com.prueba.core.context.integration.database.DataBaseAccess; +import com.prueba.core.context.integration.database.impl.DataBaseAccessImpl; +import com.prueba.core.context.integration.datasource.impl.DoDataSourceContext; + +public class LiquibaseContextIntegrationTest { + private static final String CODE = "CODE"; + private static final String NAME = "NAME"; + private static final String SURNAME = "SURNAME"; + private static final String PASSWORD = "PASSWORD"; + private static final String APP_ROLE_CODE = "APPLICATION_ROLE_CODE"; + + @Test + public void whenLoadLiquibaseContextThenReturnSuccessFulQuery() { + final DataSource dataSource = DoDataSourceContext.getInstance().getDataSource(); + final LiquibaseContext liquibaseContext = new LiquibaseContext(dataSource); + liquibaseContext.init(); + + final DataBaseAccess dataBaseAccess = new DataBaseAccessImpl(); + final List> dataResult = dataBaseAccess.executeQuery("SELECT * FROM ACCOUNT", + answer -> + { + final List> result = new ArrayList<>(); + while (answer.next()) { + final Map row = new HashMap<>(); + row.put(CODE, answer.getString(CODE)); + row.put(NAME, answer.getString(NAME)); + row.put(SURNAME, answer.getString(SURNAME)); + row.put(PASSWORD, answer.getString(PASSWORD)); + row.put(APP_ROLE_CODE, answer.getString(APP_ROLE_CODE)); + result.add(row); + } + + return result; + }); + + final String expectedCode = "GUMARTIN"; + final String expectedName = "Gustavo"; + final String expectedSurname = "Martin Morcuende"; + final String expectedPassword = "lame"; + final String expectedAppRoleCode = "ROLE_APP_ADMIN"; + + final Map row = dataResult.get(0); + assertNotNull(row); + assertEquals(expectedCode, row.get(CODE)); + assertEquals(expectedName, row.get(NAME)); + assertEquals(expectedSurname, row.get(SURNAME)); + assertEquals(expectedPassword, row.get(PASSWORD)); + assertEquals(expectedAppRoleCode, row.get(APP_ROLE_CODE)); + } + +} -- 2.1.4