dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #20242
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 9162: Initial work on new data analytics engine
------------------------------------------------------------
revno: 9162
committer: Lars Helge Øverland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Mon 2012-12-03 22:04:39 +0100
message:
Initial work on new data analytics engine
added:
dhis-2/dhis-services/dhis-service-analytics/
dhis-2/dhis-services/dhis-service-analytics/pom.xml
dhis-2/dhis-services/dhis-service-analytics/src/
dhis-2/dhis-services/dhis-service-analytics/src/main/
dhis-2/dhis-services/dhis-service-analytics/src/main/java/
dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/
dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/
dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/
dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/
dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsManager.java
dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsService.java
dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsTableManager.java
dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsTableService.java
dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/
dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java
dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/JdbcAnalyticsManager.java
dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/
dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/DefaultAnalyticsTableService.java
dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/JdbcAnalyticsTableManager.java
dhis-2/dhis-services/dhis-service-analytics/src/main/resources/
dhis-2/dhis-services/dhis-service-analytics/src/main/resources/META-INF/
dhis-2/dhis-services/dhis-service-analytics/src/main/resources/META-INF/dhis/
dhis-2/dhis-services/dhis-service-analytics/src/main/resources/META-INF/dhis/beans.xml
modified:
dhis-2/dhis-services/pom.xml
dhis-2/pom.xml
--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk
Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== added directory 'dhis-2/dhis-services/dhis-service-analytics'
=== added file 'dhis-2/dhis-services/dhis-service-analytics/pom.xml'
--- dhis-2/dhis-services/dhis-service-analytics/pom.xml 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/pom.xml 2012-12-03 21:04:39 +0000
@@ -0,0 +1,65 @@
+<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>
+
+ <parent>
+ <groupId>org.hisp.dhis</groupId>
+ <artifactId>dhis-services</artifactId>
+ <version>2.11-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>dhis-service-analytics</artifactId>
+ <packaging>jar</packaging>
+ <name>DHIS Analytics</name>
+
+ <dependencies>
+
+ <!-- DHIS -->
+
+ <dependency>
+ <groupId>org.hisp.dhis</groupId>
+ <artifactId>dhis-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hisp.dhis</groupId>
+ <artifactId>dhis-service-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hisp.dhis</groupId>
+ <artifactId>dhis-service-administration</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hisp.dhis</groupId>
+ <artifactId>dhis-support-system</artifactId>
+ </dependency>
+
+ <!-- Other -->
+
+ <dependency>
+ <groupId>jep</groupId>
+ <artifactId>jep</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.amplecode</groupId>
+ <artifactId>quick</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.whalin</groupId>
+ <artifactId>Memcached-Java-Client</artifactId>
+ <version>3.0.1</version>
+ </dependency>
+
+ </dependencies>
+ <properties>
+ <rootDir>../../</rootDir>
+ </properties>
+</project>
=== added directory 'dhis-2/dhis-services/dhis-service-analytics/src'
=== added directory 'dhis-2/dhis-services/dhis-service-analytics/src/main'
=== added directory 'dhis-2/dhis-services/dhis-service-analytics/src/main/java'
=== added directory 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org'
=== added directory 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp'
=== added directory 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis'
=== added directory 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics'
=== added file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsManager.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsManager.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsManager.java 2012-12-03 21:04:39 +0000
@@ -0,0 +1,40 @@
+package org.hisp.dhis.analytics;
+
+/*
+ * Copyright (c) 2004-2012, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Future;
+
+import org.hisp.dhis.aggregation.AggregatedDataValue;
+
+public interface AnalyticsManager
+{
+ Future<List<AggregatedDataValue>> getAggregatedDataValueTotals( Collection<AggregatedDataValue> values, Collection<Integer> dataElementIds,
+ Collection<String> periodIds, Collection<Integer> organisationUnitIds );
+}
=== added file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsService.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsService.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsService.java 2012-12-03 21:04:39 +0000
@@ -0,0 +1,39 @@
+package org.hisp.dhis.analytics;
+
+/*
+ * Copyright (c) 2004-2012, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.Collection;
+import java.util.List;
+
+import org.hisp.dhis.aggregation.AggregatedDataValue;
+
+public interface AnalyticsService
+{
+ List<AggregatedDataValue> getAggregatedDataValueTotals( Collection<Integer> dataElementIds,
+ Collection<String> periodIds, Collection<Integer> organisationUnitIds ) throws Exception;
+}
=== added file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsTableManager.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsTableManager.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsTableManager.java 2012-12-03 21:04:39 +0000
@@ -0,0 +1,54 @@
+package org.hisp.dhis.analytics;
+
+/*
+ * Copyright (c) 2004-2012, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.List;
+import java.util.concurrent.Future;
+
+public interface AnalyticsTableManager
+{
+ void dropTable();
+
+ void createTable();
+
+ void populateTable();
+
+ Future<?> createIndexesAsync( List<String> columns );
+
+ /**
+ * Returns a list of string arrays in where the first index holds the database
+ * column name, the second index holds the database column type and the third
+ * column holds a table alias.
+ */
+ List<String[]> getDimensionColumns();
+
+ /**
+ * Returns a list of database column names.
+ */
+ List<String> getDimensionColumnNames();
+}
=== added file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsTableService.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsTableService.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsTableService.java 2012-12-03 21:04:39 +0000
@@ -0,0 +1,35 @@
+package org.hisp.dhis.analytics;
+
+/*
+ * Copyright (c) 2004-2012, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.concurrent.Future;
+
+public interface AnalyticsTableService
+{
+ Future<?> update();
+}
=== added directory 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data'
=== added file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java 2012-12-03 21:04:39 +0000
@@ -0,0 +1,73 @@
+package org.hisp.dhis.analytics.data;
+
+/*
+ * Copyright (c) 2004-2012, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Future;
+
+import org.hisp.dhis.aggregation.AggregatedDataValue;
+import org.hisp.dhis.analytics.AnalyticsManager;
+import org.hisp.dhis.analytics.AnalyticsService;
+import org.hisp.dhis.system.util.PaginatedList;
+import org.hisp.dhis.system.util.Timer;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultAnalyticsService
+ implements AnalyticsService
+{
+ @Autowired
+ private AnalyticsManager analyticsManager;
+
+ public List<AggregatedDataValue> getAggregatedDataValueTotals( Collection<Integer> dataElementIds,
+ Collection<String> periodIds, Collection<Integer> organisationUnitIds ) throws Exception
+ {
+ Timer t = new Timer().start();
+
+ List<List<Integer>> dePages = new PaginatedList<Integer>( dataElementIds ).setNumberOfPages( 4 ).getPages();
+
+ List<Future<List<AggregatedDataValue>>> futures = new ArrayList<Future<List<AggregatedDataValue>>>();
+
+ List<AggregatedDataValue> values = new ArrayList<AggregatedDataValue>();
+
+ for ( List<Integer> dePage : dePages )
+ {
+ futures.add( analyticsManager.getAggregatedDataValueTotals( values, dePage, periodIds, organisationUnitIds ) );
+ }
+
+ for ( Future<List<AggregatedDataValue>> future : futures )
+ {
+ values.addAll( future.get() );
+ }
+
+ t.getTime( "Got aggregated values" );
+
+ return values;
+ }
+}
=== added file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/JdbcAnalyticsManager.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/JdbcAnalyticsManager.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/JdbcAnalyticsManager.java 2012-12-03 21:04:39 +0000
@@ -0,0 +1,102 @@
+package org.hisp.dhis.analytics.data;
+
+/*
+ * Copyright (c) 2004-2012, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import static org.hisp.dhis.system.util.TextUtils.getCommaDelimitedString;
+import static org.hisp.dhis.system.util.TextUtils.getQuotedCommaDelimitedString;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Future;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hisp.dhis.aggregation.AggregatedDataValue;
+import org.hisp.dhis.analytics.AnalyticsManager;
+import org.hisp.dhis.expression.ExpressionService;
+import org.hisp.dhis.organisationunit.OrganisationUnitService;
+import org.hisp.dhis.period.PeriodService;
+import org.hisp.dhis.period.PeriodType;
+import org.hisp.dhis.system.objectmapper.AggregatedDataValueRowMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.AsyncResult;
+
+/**
+ * This class is responsible for producing aggregated data values. It reads data
+ * from the analytics table. Organisation units provided as arguments must be on
+ * the same level in the hierarchy.
+ *
+ * @author Lars Helge Overland
+ */
+public class JdbcAnalyticsManager
+ implements AnalyticsManager
+{
+ private static final Log log = LogFactory.getLog( JdbcAnalyticsManager.class );
+
+ @Autowired
+ private JdbcTemplate jdbcTemplate;
+
+ @Autowired
+ private OrganisationUnitService organisationUnitService;
+
+ @Autowired
+ private PeriodService periodService;
+
+ @Autowired
+ private ExpressionService expressionService;
+
+ // -------------------------------------------------------------------------
+ // Implementation
+ // -------------------------------------------------------------------------
+
+ //TODO period aggregation for multiple period types
+ //TODO hierarchy aggregation for org units at multiple levels
+ //TODO indicator aggregation
+
+ @Async
+ public Future<List<AggregatedDataValue>> getAggregatedDataValueTotals( Collection<AggregatedDataValue> values, Collection<Integer> dataElementIds,
+ Collection<String> periodIds, Collection<Integer> organisationUnitIds )
+ {
+ int level = organisationUnitService.getLevelOfOrganisationUnit( organisationUnitIds.iterator().next() );
+ String periodType = PeriodType.getPeriodTypeFromIsoString( periodIds.iterator().next() ).getName().toLowerCase();
+
+ final String sql =
+ "SELECT dataelementid, 0 as categoryoptioncomboid, periodid, idlevel" + level + " as organisationunitid, SUM(value) as value " +
+ "FROM analytics " +
+ "WHERE dataelementid IN ( " + getCommaDelimitedString( dataElementIds ) + " ) " +
+ "AND " + periodType + " IN ( " + getQuotedCommaDelimitedString( periodIds ) + " ) " +
+ "AND idlevel" + level + " IN ( " + getCommaDelimitedString( organisationUnitIds ) + " ) " +
+ "GROUP BY dataelementid, periodid, idlevel" + level;
+
+ log.info( sql );
+
+ return new AsyncResult<List<AggregatedDataValue>>( jdbcTemplate.query( sql, new AggregatedDataValueRowMapper() ) );
+ }
+}
=== added directory 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table'
=== added file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/DefaultAnalyticsTableService.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/DefaultAnalyticsTableService.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/DefaultAnalyticsTableService.java 2012-12-03 21:04:39 +0000
@@ -0,0 +1,97 @@
+package org.hisp.dhis.analytics.table;
+
+/*
+ * Copyright (c) 2004-2012, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hisp.dhis.analytics.AnalyticsTableManager;
+import org.hisp.dhis.analytics.AnalyticsTableService;
+import org.hisp.dhis.system.util.ConcurrentUtils;
+import org.hisp.dhis.system.util.PaginatedList;
+import org.hisp.dhis.system.util.SystemUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+
+public class DefaultAnalyticsTableService
+ implements AnalyticsTableService
+{
+ private static final Log log = LogFactory.getLog( DefaultAnalyticsTableService.class );
+
+ @Autowired
+ private AnalyticsTableManager tableManager;
+
+ // -------------------------------------------------------------------------
+ // Implementation
+ // -------------------------------------------------------------------------
+
+ //TODO generateOrganisationUnitStructures
+ //TODO generateOrganisationUnitGroupSetTable
+ //TODO generatePeriodStructure
+
+ @Async
+ public Future<?> update()
+ {
+ log.info( "Starting update..." );
+
+ tableManager.dropTable();
+ tableManager.createTable();
+ tableManager.populateTable();
+
+ createIndexes();
+
+ log.info( "Update done" );
+
+ return null;
+ }
+
+ // -------------------------------------------------------------------------
+ // Supportive methods
+ // -------------------------------------------------------------------------
+
+ private void createIndexes()
+ {
+ int pages = Math.max( ( SystemUtils.getCpuCores() - 1 ), 1 );
+
+ log.info( "No of pages: " + pages );
+
+ List<Future<?>> futures = new ArrayList<Future<?>>();
+
+ List<List<String>> columnPages = new PaginatedList<String>( tableManager.getDimensionColumnNames() ).setNumberOfPages( pages ).getPages();
+
+ for ( List<String> columnPage : columnPages )
+ {
+ futures.add( tableManager.createIndexesAsync( columnPage ) );
+ }
+
+ ConcurrentUtils.waitForCompletion( futures );
+ }
+}
=== added file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/JdbcAnalyticsTableManager.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/JdbcAnalyticsTableManager.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/JdbcAnalyticsTableManager.java 2012-12-03 21:04:39 +0000
@@ -0,0 +1,244 @@
+package org.hisp.dhis.analytics.table;
+
+/*
+ * Copyright (c) 2004-2012, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Future;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hisp.dhis.analytics.AnalyticsTableManager;
+import org.hisp.dhis.organisationunit.OrganisationUnitGroupService;
+import org.hisp.dhis.organisationunit.OrganisationUnitGroupSet;
+import org.hisp.dhis.organisationunit.OrganisationUnitLevel;
+import org.hisp.dhis.organisationunit.OrganisationUnitService;
+import org.hisp.dhis.period.PeriodType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.BadSqlGrammarException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.scheduling.annotation.Async;
+
+/**
+ * This class manages the analytics table. The analytics table is a denormalized
+ * table designed for analysis which contains raw data values. It has columns for
+ * each organisation unit group set and organisation unit level. Also, columns
+ * for dataelementid, periodid, organisationunitid, categoryoptioncomboid, value.
+ *
+ * The data records in this table are not aggregated. Typically, queries will
+ * aggregate in organisation unit hierarchy dimension, in the period/time dimension,
+ * and the category dimensions, as well as org unit group set dimensions.
+ *
+ * @author Lars Helge Overland
+ */
+public class JdbcAnalyticsTableManager
+ implements AnalyticsTableManager
+{
+ private static final Log log = LogFactory.getLog( JdbcAnalyticsTableManager.class );
+
+ public static final String PREFIX_ORGUNITGROUPSET = "ougs_";
+ public static final String PREFIX_ORGUNITLEVEL = "idlevel";
+ public static final String PREFIX_INDEX = "index_";
+ public static final String TABLE_NAME = "analytics";
+
+ @Autowired
+ private OrganisationUnitService organisationUnitService;
+
+ @Autowired
+ private OrganisationUnitGroupService organisationUnitGroupService;
+
+ @Autowired
+ private JdbcTemplate jdbcTemplate;
+
+ // -------------------------------------------------------------------------
+ // Implementation
+ // -------------------------------------------------------------------------
+
+ //TODO all data types
+ //TODO create temp table then swap
+ //TODO shard on data year
+ //TODO average aggregation operator data, pre-aggregate in time dimension, not in org unit dimension
+
+ public void dropTable()
+ {
+ final String sql = "drop table " + TABLE_NAME;
+
+ executeSilently( sql );
+
+ log.info( "Dropped table: " + TABLE_NAME );
+ }
+
+ public void createTable()
+ {
+ String sql = "create table " + TABLE_NAME + " (";
+
+ for ( String[] col : getDimensionColumns() )
+ {
+ sql += col[0] + " " + col[1] + ",";
+ }
+
+ sql += "value double precision)";
+
+ log.info( "Create SQL: " + sql );
+
+ executeSilently( sql );
+
+ log.info( "Created table: " + TABLE_NAME );
+ }
+
+ @Async
+ public Future<?> createIndexesAsync( List<String> columns )
+ {
+ for ( String column : columns )
+ {
+ final String sql = "create index " + PREFIX_INDEX +
+ column + " on " + TABLE_NAME + " (" + column + ")";
+
+ executeSilently( sql );
+
+ log.info( "Created index on column: " + column );
+ }
+
+ log.info( "Indexes created" );
+
+ return null;
+ }
+
+ public void populateTable()
+ {
+ String insert = "insert into analytics (";
+
+ for ( String[] col : getDimensionColumns() )
+ {
+ insert += col[0] + ",";
+ }
+
+ insert += "value) ";
+
+ String select = "select ";
+
+ for ( String[] col : getDimensionColumns() )
+ {
+ select += col[2] + col[0] + ",";
+ }
+
+ select = select.replace( "organisationunitid", "sourceid" ); // Legacy fix
+
+ select +=
+ "cast(dv.value as double precision) " +
+ "from datavalue dv " +
+ "left join _organisationunitgroupsetstructure ougs on dv.sourceid=ougs.organisationunitid " +
+ "left join _orgunitstructure ous on dv.sourceid=ous.organisationunitid " +
+ "left join _period_no_disaggregation_structure ps on dv.periodid=ps.periodid " +
+ "left join dataelement de on dv.dataelementid=de.dataelementid " +
+ "left join period pe on dv.periodid=pe.periodid " +
+ "where de.valuetype='int' and pe.startdate >= '2011-10-01'";
+
+ final String sql = insert + select;
+
+ log.info( "Populate SQL: "+ sql );
+
+ jdbcTemplate.execute( sql );
+
+ log.info( "Populated analytics table" );
+ }
+
+ public List<String[]> getDimensionColumns()
+ {
+ List<String[]> columns = new ArrayList<String[]>();
+
+ Collection<OrganisationUnitGroupSet> orgUnitGroupSets =
+ organisationUnitGroupService.getCompulsoryOrganisationUnitGroupSets();
+
+ Collection<OrganisationUnitLevel> levels =
+ organisationUnitService.getOrganisationUnitLevels();
+
+ for ( OrganisationUnitGroupSet groupSet : orgUnitGroupSets )
+ {
+ String[] col = { PREFIX_ORGUNITGROUPSET + groupSet.getUid(), "integer", "ougs." };
+ columns.add( col );
+ }
+
+ for ( OrganisationUnitLevel level : levels )
+ {
+ String[] col = { PREFIX_ORGUNITLEVEL + level.getLevel(), "integer", "ous." };
+ columns.add( col );
+ }
+
+ for ( PeriodType periodType : PeriodType.getAvailablePeriodTypes().subList( 0, 7 ) )
+ {
+ String[] col = { periodType.getName().toLowerCase(), "character varying(10)", "ps." };
+ columns.add( col );
+ }
+
+ String[] de = { "dataelementid", "integer not null", "dv." };
+ String[] pe = { "periodid", "integer not null", "dv." };
+ String[] ou = { "organisationunitid", "integer not null", "dv." };
+ String[] co = { "categoryoptioncomboid", "integer not null", "dv." };
+
+ columns.addAll( Arrays.asList( de, pe, ou, co ) );
+
+ return columns;
+ }
+
+ public List<String> getDimensionColumnNames()
+ {
+ List<String[]> columns = getDimensionColumns();
+
+ List<String> columnNames = new ArrayList<String>();
+
+ for ( String[] column : columns )
+ {
+ columnNames.add( column[0] );
+ }
+
+ return columnNames;
+ }
+
+ // -------------------------------------------------------------------------
+ // Supportive methods
+ // -------------------------------------------------------------------------
+
+ /**
+ * Executes a SQL statement. Ignores existing tables/indexes when attempting
+ * to create new.
+ */
+ private void executeSilently( String sql )
+ {
+ try
+ {
+ jdbcTemplate.execute( sql );
+ }
+ catch ( BadSqlGrammarException ex )
+ {
+ log.warn( ex.getMessage() );
+ }
+ }
+}
=== added directory 'dhis-2/dhis-services/dhis-service-analytics/src/main/resources'
=== added directory 'dhis-2/dhis-services/dhis-service-analytics/src/main/resources/META-INF'
=== added directory 'dhis-2/dhis-services/dhis-service-analytics/src/main/resources/META-INF/dhis'
=== added file 'dhis-2/dhis-services/dhis-service-analytics/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/resources/META-INF/dhis/beans.xml 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/resources/META-INF/dhis/beans.xml 2012-12-03 21:04:39 +0000
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:aop="http://www.springframework.org/schema/aop" xmlns:sec="http://www.springframework.org/schema/security"
+ xsi:schemaLocation="
+http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
+http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
+http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
+
+ <bean id="org.hisp.dhis.analytics.AnalyticsTableManager" class="org.hisp.dhis.analytics.table.JdbcAnalyticsTableManager" />
+
+ <bean id="org.hisp.dhis.analytics.AnalyticsTableService" class="org.hisp.dhis.analytics.table.DefaultAnalyticsTableService" />
+
+ <bean id="org.hisp.dhis.analytics.AnalyticsManager" class="org.hisp.dhis.analytics.data.JdbcAnalyticsManager" />
+
+ <bean id="org.hisp.dhis.analytics.AnalyticsService" class="org.hisp.dhis.analytics.data.DefaultAnalyticsService" />
+
+</beans>
=== modified file 'dhis-2/dhis-services/pom.xml'
--- dhis-2/dhis-services/pom.xml 2012-11-20 13:38:49 +0000
+++ dhis-2/dhis-services/pom.xml 2012-12-03 21:04:39 +0000
@@ -22,6 +22,7 @@
<module>dhis-service-reporting</module>
<module>dhis-service-mapgeneration</module>
<module>dhis-service-aggregationengine-default</module>
+ <module>dhis-service-analytics</module>
<module>dhis-service-sms</module>
<module>dhis-service-patient</module>
<module>dhis-service-mobile</module>
=== modified file 'dhis-2/pom.xml'
--- dhis-2/pom.xml 2012-11-29 16:21:29 +0000
+++ dhis-2/pom.xml 2012-12-03 21:04:39 +0000
@@ -285,6 +285,11 @@
</dependency>
<dependency>
<groupId>org.hisp.dhis</groupId>
+ <artifactId>dhis-service-analytics</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hisp.dhis</groupId>
<artifactId>dhis-support-jdbc</artifactId>
<version>${project.version}</version>
</dependency>