First commit
authorGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 2 Oct 2016 18:29:30 +0000 (20:29 +0200)
committerGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 2 Oct 2016 18:29:30 +0000 (20:29 +0200)
15 files changed:
pom.xml [new file with mode: 0644]
src/main/java/com/prueba/core/context/ApplicationContext.java [new file with mode: 0644]
src/main/java/com/prueba/core/context/integration/database/DataBaseAccess.java [new file with mode: 0644]
src/main/java/com/prueba/core/context/integration/database/impl/DataBaseAccessImpl.java [new file with mode: 0644]
src/main/java/com/prueba/core/context/integration/datasource/DoDataSource.java [new file with mode: 0644]
src/main/java/com/prueba/core/context/integration/datasource/impl/DoDataSourceContext.java [new file with mode: 0644]
src/main/java/com/prueba/core/context/integration/liquibase/impl/LiquibaseContext.java [new file with mode: 0644]
src/main/java/com/prueba/core/web/application/context/ApplicationWebContext.java [new file with mode: 0644]
src/main/resources/liquibase/changeLogs.xml [new file with mode: 0644]
src/main/resources/liquibase/ddlChangelog.xml [new file with mode: 0644]
src/main/resources/liquibase/dml.sql [new file with mode: 0644]
src/main/resources/liquibase/dmlChangelog.xml [new file with mode: 0644]
src/main/resources/log4j2.xml [new file with mode: 0644]
src/test/java/com/prueba/core/context/ApplicationContextIntegrationTest.java [new file with mode: 0644]
src/test/java/com/prueba/core/context/integration/liquibase/impl/LiquibaseContextIntegrationTest.java [new file with mode: 0644]

diff --git a/pom.xml b/pom.xml
new file mode 100644 (file)
index 0000000..9b2aed5
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,311 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>com.prueba</groupId>
+    <artifactId>http-services</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <name>HTTP SERVICES</name>
+    <url>https://gumartinm.name/</url>
+    <description>HTTP SERVICES</description>
+    <organization>
+        <name>Gustavo Martin Morcuende</name>
+        <url>https://gumartinm.name/</url>
+    </organization>
+    <scm>
+        <developerConnection>scm:git:https://git.gumartinm.name/Prueba</developerConnection>
+        <url>https://git.gumartinm.name/Prueba</url>
+    </scm>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <maven.javadoc.version>2.10.4</maven.javadoc.version>
+        <maven.source.version>3.0.1</maven.source.version>
+
+        <!-- Be careful these two paths must match the ones configured in SONARQUBE JaCoCo plugin -->
+        <jacoco.it.execution.data.file>${project.basedir}/target/jacoco-it.exec</jacoco.it.execution.data.file>
+        <jacoco.ut.execution.data.file>${project.basedir}/target/jacoco.exec</jacoco.ut.execution.data.file>
+
+        <skip.unit.tests>false</skip.unit.tests>
+        <skip.integration.tests>true</skip.integration.tests>
+    </properties>
+
+    <profiles>
+        <profile>
+            <id>development</id>
+            <properties>
+                <environment.profile>development</environment.profile>
+                <environment.name>Desarrollo local</environment.name>
+            </properties>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+        </profile>
+        <profile>
+            <id>integration</id>
+            <properties>
+                <environment.profile>integration</environment.profile>
+                <environment.name>Integration</environment.name>
+                <skip.integration.tests>false</skip.integration.tests>
+            </properties>
+        </profile>
+        <profile>
+            <id>production</id>
+            <properties>
+                <environment.profile>production</environment.profile>
+                <environment.name>Production</environment.name>
+                <skip.integration.tests>false</skip.integration.tests>
+            </properties>
+        </profile>
+    </profiles>
+
+    <dependencies>
+        <!--
+            1/3 Required dependency for log4j 2 with slf4j: binding between log4j 
+            2 and slf4j
+        -->
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+            <version>2.6.1</version>
+        </dependency>
+        <!--
+            2/3 Required dependency for log4j 2 with slf4j: log4j 2 maven plugin 
+            (it is the log4j 2 implementation)
+        -->
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <version>2.6.1</version>
+        </dependency>
+        <!--
+            3/3 Required dependency for getting rid of commons logging. This is 
+            the BRIDGE (no binding) between Jakarta Commons Logging (used by Spring) 
+            and whatever I am using for logging (in this case I am using log4j 2) See: 
+            http://www.slf4j.org/legacy.html We need exclusions in every dependency using 
+            Jakarta Commons Logging (see Spring dependencies below) 
+        -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <version>1.7.21</version>
+        </dependency>
+
+
+        <!--
+            Jackson JSON Processor, required by spring-webmvc. See messageConverters
+            in rest-config.xml
+        -->
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.8.3</version>
+        </dependency>
+
+        <!-- Loading data base in run time -->
+        <dependency>
+            <groupId>org.liquibase</groupId>
+            <artifactId>liquibase-core</artifactId>
+            <version>3.5.2</version>
+        </dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <version>1.4.192</version>
+        </dependency>
+        
+        <!-- Database pool -->
+        <dependency>
+            <groupId>com.mchange</groupId>
+            <artifactId>c3p0</artifactId>
+            <version>0.9.5.2</version>
+        </dependency>
+
+        <!-- Unitary and integration tests -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>2.0.43-beta</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.5.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <version>3.0.1</version>
+                <configuration>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <version>0.7.7.201606060606</version>
+                <executions>
+                    <!-- Prepares the property pointing to the JaCoCo runtime agent which 
+                        is passed as VM argument when Maven the Surefire plugin is executed. -->
+                    <execution>
+                        <id>pre-unit-test</id>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                        <configuration>
+                            <!-- Sets the path to the file which contains the execution data. -->
+                            <destFile>${jacoco.ut.execution.data.file}</destFile>
+                            <!-- Sets the name of the property containing the settings for JaCoCo 
+                                runtime agent. -->
+                            <propertyName>surefireArgLine</propertyName>
+                        </configuration>
+                    </execution>
+                    <!-- Ensures that the code coverage report for unit tests is created 
+                        after unit tests have been run. -->
+                    <execution>
+                        <id>post-unit-test</id>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>report</goal>
+                        </goals>
+                        <configuration>
+                            <!-- Sets the path to the file which contains the execution data. -->
+                            <dataFile>${jacoco.ut.execution.data.file}</dataFile>
+                            <!-- Sets the output directory for the code coverage report. -->
+                            <outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
+                        </configuration>
+                    </execution>
+                    <!-- Prepares the property pointing to the JaCoCo runtime agent which 
+                        is passed as VM argument when Maven the Failsafe plugin is executed. -->
+                    <execution>
+                        <id>pre-integration-test</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                        <configuration>
+                            <!-- Sets the path to the file which contains the execution data. -->
+                            <destFile>${jacoco.it.execution.data.file}</destFile>
+                            <!-- Sets the name of the property containing the settings for JaCoCo 
+                                runtime agent. -->
+                            <propertyName>failsafeArgLine</propertyName>
+                        </configuration>
+                    </execution>
+                    <!-- Ensures that the code coverage report for integration tests after 
+                        integration tests have been run. -->
+                    <execution>
+                        <id>post-integration-test</id>
+                        <phase>post-integration-test</phase>
+                        <goals>
+                            <goal>report</goal>
+                        </goals>
+                        <configuration>
+                            <!-- Sets the path to the file which contains the execution data. -->
+                            <dataFile>${jacoco.it.execution.data.file}</dataFile>
+                            <!-- Sets the output directory for the code coverage report. -->
+                            <outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.eclipse.m2e</groupId>
+                <artifactId>lifecycle-mapping</artifactId>
+                <version>1.0.0</version>
+                <configuration>
+                    <lifecycleMappingMetadata>
+                        <pluginExecutions>
+                            <pluginExecution>
+                                <pluginExecutionFilter>
+                                    <groupId>org.jacoco</groupId>
+                                    <artifactId>jacoco-maven-plugin</artifactId>
+                                    <versionRange>[0.5,)
+                                    </versionRange>
+                                    <goals>
+                                        <goal>prepare-agent</goal>
+                                    </goals>
+                                </pluginExecutionFilter>
+                                <action>
+                                    <!-- m2e doesn't know what to do with jacoco, let's ignore it or 
+                                        annoying error markers appear see http://wiki.eclipse.org/M2E_plugin_execution_not_covered -->
+                                    <ignore />
+                                </action>
+                            </pluginExecution>
+                        </pluginExecutions>
+                    </lifecycleMappingMetadata>
+                </configuration>
+            </plugin>
+
+            <!-- Used for unit tests -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>2.19.1</version>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.apache.maven.surefire</groupId>
+                        <artifactId>surefire-junit47</artifactId>
+                        <version>2.19.1</version>
+                    </dependency>
+                </dependencies>
+                <configuration>
+                    <!-- Sets the VM argument line used when unit tests are run. -->
+                    <argLine>-Dfile.encoding=${project.build.sourceEncoding}
+                        ${surefireArgLine}</argLine>
+                    <!-- Skips unit tests if the value of skip.unit.tests property is true -->
+                    <skipTests>${skip.unit.tests}</skipTests>
+                    <!-- Excludes integration tests when unit tests are run. -->
+                    <excludes>
+                        <exclude>**/*IT.java</exclude>
+                        <exclude>**/*IntegrationTest.java</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+            <!-- Used for integration tests -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-failsafe-plugin</artifactId>
+                <version>2.19.1</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>integration-test</goal>
+                            <goal>verify</goal>
+                        </goals>
+                        <configuration>
+                            <!-- Sets the VM argument line used when integration tests are run. -->
+                            <argLine>${failsafeArgLine}</argLine>
+
+                            <!-- Skips integration tests if the value of skip.integration.tests 
+                                property is true -->
+                            <skipTests>${skip.integration.tests}</skipTests>
+                            <includes>
+                                <include>**/*IT.java</include>
+                                <include>**/*IntegrationTest.java</include>
+                            </includes>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+
+    </build>
+
+</project>
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 (file)
index 0000000..3d5b8ff
--- /dev/null
@@ -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 (file)
index 0000000..4a47d0d
--- /dev/null
@@ -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> {
+        TResult executeStatement(final Statement statement) throws SQLException;
+    }
+
+    public interface ExecuteResultSet<TResult> {
+        List<Map<String, String>> executeResultSet(final TResult resultSet) throws SQLException;
+    }
+    
+    List<Map<String, String>> executeQuery(final String query, final ExecuteResultSet<ResultSet> 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 (file)
index 0000000..ca335a1
--- /dev/null
@@ -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<Map<String, String>> executeQuery(String query, ExecuteResultSet<ResultSet> executeResultSet) {
+               List<Map<String, String>> result = null;
+               try {
+                       result = this.executeQueryThrowable(query, executeResultSet);
+               } catch (SQLException exception) {
+                       LOGGER.error("Query error: ", exception);
+               }
+               
+               return result;
+       }
+       
+       protected List<Map<String, String>> executeQueryThrowable(String query, ExecuteResultSet<ResultSet> 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<Map<String, String>> doExecuteQuery (final Connection connection,
+            final ExecuteStatement<ResultSet> executeStatement,
+            final ExecuteResultSet<ResultSet> 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 (file)
index 0000000..7b8373d
--- /dev/null
@@ -0,0 +1,13 @@
+package com.prueba.core.context.integration.datasource;
+
+import javax.sql.DataSource;
+
+public interface DoDataSource {
+
+       /**
+        * Returns <code>DataSource</code>
+        * 
+        * @return the created <code>DataSource</code> 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 (file)
index 0000000..bb7779d
--- /dev/null
@@ -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 (file)
index 0000000..6b87b26
--- /dev/null
@@ -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 (file)
index 0000000..9d2c7fe
--- /dev/null
@@ -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 (file)
index 0000000..a393fc5
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog
+        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
+        http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
+
+    <!-- DDL -->
+    <include file="liquibase/ddlChangelog.xml" />
+
+       <!-- DML -->
+    <changeSet author="gustavo dmlt" id="66">
+            <sqlFile path="liquibase/dml.sql" stripComments="true"/>
+    </changeSet>
+
+</databaseChangeLog>
diff --git a/src/main/resources/liquibase/ddlChangelog.xml b/src/main/resources/liquibase/ddlChangelog.xml
new file mode 100644 (file)
index 0000000..d647999
--- /dev/null
@@ -0,0 +1,118 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
+
+    <changeSet author="jorgepacheco (generated)" id="1452868316935-3">
+        <createTable remarks="Tabla de Identidades (Usuarios)" schemaName="PRUEBA" tableName="ACCOUNT">
+            <column name="CODE" remarks="User code" type="VARCHAR(50)">
+                <constraints nullable="false"/>
+            </column>
+            <column name="NAME" remarks="User name" type="VARCHAR(255)"/>
+            <column name="SURNAME" remarks="User surname" type="VARCHAR(255)"/>
+            <column name="PASSWORD" remarks="User password" type="VARCHAR(50)"/>
+            <column name="APPLICATION_ROLE_CODE" remarks="Rol" type="VARCHAR(50)"/>
+        </createTable>
+    </changeSet>
+
+    <changeSet author="gustavo (generated)" id="1469119656864-1">
+        <createTable remarks="Recursos" schemaName="PRUEBA" tableName="APPLICATION_RESOURCE">
+            <column name="URL_PATTERN" remarks="Patrón url securizada" type="VARCHAR(255)">
+                <constraints nullable="false"/>
+            </column>
+            <column name="HTTP_METHOD" remarks="Método http securizado (GET, POST, PUT, DELETE)" type="VARCHAR(6)">
+                <constraints nullable="false"/>
+            </column>
+        </createTable>
+    </changeSet>
+        <changeSet author="gustavo (generated)" id="1469119656864-2">
+        <createTable remarks="Recursos con rol" schemaName="PRUEBA" tableName="APPLICATION_RESOURCE_APPLICATION_ROLE">
+            <column name="APPLICATION_RESOURCE_URL_PATTERN" remarks="Patrón url securizada" type="VARCHAR(255)">
+                <constraints nullable="false"/>
+            </column>
+            <column name="APPLICATION_ROLE_CODE" remarks="Rol de aplicación" type="VARCHAR(50)">
+                <constraints nullable="false"/>
+            </column>
+            <column name="APPLICATION_RESOURCE_HTTP_METHOD" remarks="Método http securizado (GET, POST, PUT, DELETE)" type="VARCHAR(6)">
+                <constraints nullable="false"/>
+            </column>
+        </createTable>
+    </changeSet>
+    <changeSet author="gustavo (generated)" id="1469119656864-3">
+        <createTable remarks="Roles" schemaName="PRUEBA" tableName="APPLICATION_ROLE">
+            <column name="CODE" remarks="Código del rol de aplicación" type="VARCHAR(50)">
+                <constraints nullable="false"/>
+            </column>
+            <column name="DESCRIPTION" remarks="Descripción del Rol de Aplicación" type="VARCHAR(50)"/>
+        </createTable>
+    </changeSet>
+    
+    
+    <changeSet author="jorgepacheco (generated)" id="1452868316935-23">
+        <addPrimaryKey columnNames="CODE" constraintName="ACCOUNT_PK" schemaName="PRUEBA" tableName="ACCOUNT"/>
+    </changeSet>
+    <changeSet author="jorgepacheco (generated)" id="1452868316935-42">
+        <createIndex indexName="ACCOUNT_IND_01" schemaName="PRUEBA" tableName="ACCOUNT">
+            <column name="APPLICATION_ROLE_CODE"/>
+        </createIndex>
+    </changeSet>
+    <changeSet author="jorgepacheco (generated)" id="1452868316935-69">
+        <addForeignKeyConstraint
+        baseColumnNames="APPLICATION_ROLE_CODE" baseTableName="ACCOUNT" baseTableSchemaName="PRUEBA"
+        constraintName="ACCOUNT_FK_01" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
+        referencedColumnNames="CODE" referencedTableName="APPLICATION_ROLE"/>
+    </changeSet>
+    
+    
+    
+    <changeSet author="gustavo (generated)" id="1469119656864-4">
+        <addPrimaryKey columnNames="CODE" constraintName="APPLICATION_ROLE_PK" schemaName="PRUEBA" tableName="APPLICATION_ROLE"/>
+    </changeSet>
+    <changeSet author="gustavo (generated)" id="1469119656864-5">
+        <addUniqueConstraint columnNames="CODE" constraintName="APPLICATION_ROLE_UNQ_01" schemaName="PRUEBA" tableName="APPLICATION_ROLE"/>
+    </changeSet>
+    <changeSet author="gustavo (generated)" id="1469119656864-6">
+        <createIndex indexName="APPLICATION_ROLE_UNQ_01" schemaName="PRUEBA" tableName="APPLICATION_ROLE" unique="true">
+            <column name="CODE"/>
+        </createIndex>
+    </changeSet>
+    
+    
+    <changeSet author="gustavo (generated)" id="1469119656864-9">
+        <addPrimaryKey
+        columnNames="APPLICATION_RESOURCE_URL_PATTERN, APPLICATION_ROLE_CODE, APPLICATION_RESOURCE_HTTP_METHOD"
+        constraintName="APPLICATION_RESOURCE_APPLICATION_ROLE_PK" schemaName="PRUEBA" tableName="APPLICATION_RESOURCE_APPLICATION_ROLE"/>
+    </changeSet>
+    <changeSet author="gustavo (generated)" id="1469119656864-11">
+        <createIndex indexName="APPLICATION_RESOURCE_APPLICATION_ROLE_IND_01" schemaName="PRUEBA" tableName="APPLICATION_RESOURCE_APPLICATION_ROLE">
+            <column name="APPLICATION_RESOURCE_URL_PATTERN"/>
+            <column name="APPLICATION_RESOURCE_HTTP_METHOD"/>
+        </createIndex>
+    </changeSet>
+    <changeSet author="gustavo (generated)" id="1469119656864-12">
+        <createIndex indexName="APPLICATION_RESOURCE_APPLICATION_ROLE_IND_02" schemaName="PRUEBA" tableName="APPLICATION_RESOURCE_APPLICATION_ROLE">
+            <column name="APPLICATION_ROLE_CODE"/>
+        </createIndex>
+    </changeSet>
+    
+    
+    <changeSet author="gustavo (generated)" id="1469119656864-14">
+        <addForeignKeyConstraint
+        baseColumnNames="APPLICATION_ROLE_CODE" baseTableName="APPLICATION_RESOURCE_APPLICATION_ROLE" baseTableSchemaName="PRUEBA"
+        constraintName="APPLICATION_RESOURCE_APPLICATION_ROLE_FK_02" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION"
+        onUpdate="NO ACTION" referencedColumnNames="CODE" referencedTableName="APPLICATION_ROLE"/>
+    </changeSet>
+    <changeSet author="gustavo (generated)" id="1469119656864-13">
+        <addForeignKeyConstraint
+        baseColumnNames="APPLICATION_RESOURCE_URL_PATTERN, APPLICATION_RESOURCE_HTTP_METHOD" baseTableName="APPLICATION_RESOURCE_APPLICATION_ROLE"
+        baseTableSchemaName="PRUEBA" constraintName="APPLICATION_RESOURCE_APPLICATION_ROLE_FK_01" deferrable="false" initiallyDeferred="false"
+        onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="URL_PATTERN,HTTP_METHOD" referencedTableName="APPLICATION_RESOURCE"/>
+    </changeSet>  
+    
+    
+    <changeSet author="gustavo (generated)" id="1469119656864-10">
+        <addPrimaryKey
+        columnNames="URL_PATTERN, HTTP_METHOD" constraintName="APPLICATION_RESOURCE_PK" schemaName="PRUEBA"
+        tableName="APPLICATION_RESOURCE"/>
+    </changeSet>
+
+    
+</databaseChangeLog>
diff --git a/src/main/resources/liquibase/dml.sql b/src/main/resources/liquibase/dml.sql
new file mode 100644 (file)
index 0000000..abbb353
--- /dev/null
@@ -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 (file)
index 0000000..a47d06d
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
+    <changeSet author="gustavo (generated)" id="1468267830107-1">
+       <!--  
+        <insert tableName="AD">
+            <column name="ID" valueNumeric="1"/>
+            <column name="COMPANY_ID" valueNumeric="2"/>
+            <column name="COMPANY_CATEG_ID" valueNumeric="200"/>
+            <column name="AD_GPS"/>
+            <column name="AD_mobile_image" value="bild.jpg"/>
+            <column name="CREATED_AT" valueDate="2014-12-17 23:27:36.0"/>
+            <column name="UPDATED_AT" valueDate="2014-12-17 23:27:36.0"/>
+        </insert>
+        -->
+    </changeSet>
+</databaseChangeLog>
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
new file mode 100644 (file)
index 0000000..2cf5f88
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- 
+       status: The level of internal Log4j events that should be logged to the console.
+       Valid values for this attribute are "trace", "debug", "info", "warn", "error" and "fatal".
+       
+       monitorInterval: The minimum amount of time, in seconds, that must elapse before the file configuration is checked for changes.
+       
+       
+       see https://logging.apache.org/log4j/2.x/manual/configuration.html
+ -->
+<Configuration status="error" strict="true" monitorInterval="30"
+                name="XMLConfigTest" packages="org.apache.logging.log4j.test">
+                
+       <!--
+               ALL > TRACE > DEBUG > INFO > WARN > ERROR > OFF
+               
+               ERROR by default.
+       -->
+                
+    <Appenders>
+        <Appender type="Console" name="STDOUT">
+            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
+        </Appender>
+    </Appenders>
+    <Loggers>
+    
+
+       <!-- 
+               Anything else will be using INFO logging level.
+       -->        
+    <Root level="INFO">
+       <AppenderRef ref="STDOUT"/>
+    </Root>
+        
+    </Loggers>
+</Configuration>
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 (file)
index 0000000..5b1e09a
--- /dev/null
@@ -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 (file)
index 0000000..06a3cd6
--- /dev/null
@@ -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<Map<String, String>> dataResult = dataBaseAccess.executeQuery("SELECT * FROM ACCOUNT",
+                               answer ->
+               {
+                       final List<Map<String, String>> result = new ArrayList<>();
+                       while (answer.next()) {
+                               final Map<String, String> 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<String, String> 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));
+       }
+
+}