PHOENIX-1791. Adding ability for Pherf Write Workloads to write to a 
multi-tenant view.


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/42476da8
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/42476da8
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/42476da8

Branch: refs/heads/4.5-HBase-0.98
Commit: 42476da8357f971995d2504acf421dfc7c22e3a9
Parents: 060a00c
Author: Jan <jferna...@salesforce.com>
Authored: Thu Aug 6 11:12:52 2015 -0700
Committer: James Taylor <jtay...@salesforce.com>
Committed: Tue Aug 11 18:36:52 2015 -0700

----------------------------------------------------------------------
 .../org/apache/phoenix/pherf/DataIngestIT.java  | 67 +++++++++++++++++---
 .../phoenix/pherf/configuration/Scenario.java   | 25 ++++++--
 .../pherf/configuration/XMLConfigParser.java    | 23 ++++---
 .../apache/phoenix/pherf/util/PhoenixUtil.java  | 30 +++++----
 .../phoenix/pherf/workload/WriteWorkload.java   | 49 +++++++++-----
 .../datamodel/test_schema_mt_table.sql          | 31 +++++++++
 .../resources/datamodel/test_schema_mt_view.sql |  1 +
 .../test/resources/scenario/test_scenario.xml   | 22 +++++++
 8 files changed, 198 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/42476da8/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/DataIngestIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/DataIngestIT.java 
b/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/DataIngestIT.java
index 1defbb1..297f882 100644
--- a/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/DataIngestIT.java
+++ b/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/DataIngestIT.java
@@ -22,6 +22,19 @@ import com.jcabi.jdbc.JdbcSession;
 import com.jcabi.jdbc.Outcome;
 
 import org.apache.phoenix.pherf.PherfConstants.GeneratePhoenixStats;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.phoenix.pherf.configuration.Column;
 import org.apache.phoenix.pherf.configuration.DataModel;
 import org.apache.phoenix.pherf.configuration.DataTypeMapping;
@@ -35,15 +48,8 @@ import org.apache.phoenix.pherf.workload.WriteWorkload;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import static org.junit.Assert.*;
+import com.jcabi.jdbc.JdbcSession;
+import com.jcabi.jdbc.Outcome;
 
 public class DataIngestIT extends ResultBaseTestIT {
 
@@ -146,4 +152,47 @@ public class DataIngestIT extends ResultBaseTestIT {
             fail("Failed to load data. An exception was thrown: " + 
e.getMessage());
         }
     }
+
+
+    @Test
+    /**
+     * Validates that Pherf can write data to a Multi-Tenant View in addition 
to 
+     * standard Phoenix tables.
+     */
+    public void testMultiTenantViewWriteWorkload() throws Exception {
+        // Arrange
+        Scenario scenario = parser.getScenarioByName("testMTWriteScenario");
+        WorkloadExecutor executor = new WorkloadExecutor();
+        executor.add(new WriteWorkload(util, parser, scenario, 
GeneratePhoenixStats.NO));
+        
+        // Act
+        try {
+            // Wait for data to load up.
+            executor.get();
+            executor.shutdown();
+        } catch (Exception e) {
+            fail("Failed to load data. An exception was thrown: " + 
e.getMessage());
+        }
+
+        assertExpectedNumberOfRecordsWritten(scenario);
+    }
+
+    private void assertExpectedNumberOfRecordsWritten(Scenario scenario) 
throws Exception,
+            SQLException {
+        Connection connection = util.getConnection(scenario.getTenantId());
+        String sql = "select count(*) from " + scenario.getTableName();
+        Integer count = new JdbcSession(connection).sql(sql).select(new 
Outcome<Integer>() {
+            @Override public Integer handle(ResultSet resultSet, Statement 
statement)
+                    throws SQLException {
+                while (resultSet.next()) {
+                    return resultSet.getInt(1);
+                }
+                return null;
+            }
+        });
+        assertNotNull("Could not retrieve count. " + count);
+        assertEquals("Expected 100 rows to have been inserted",
+                scenario.getRowCount(), count.intValue());
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/42476da8/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/Scenario.java
----------------------------------------------------------------------
diff --git 
a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/Scenario.java
 
b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/Scenario.java
index 7de96cc..6c949d8 100644
--- 
a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/Scenario.java
+++ 
b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/Scenario.java
@@ -18,15 +18,16 @@
 
 package org.apache.phoenix.pherf.configuration;
 
-import org.apache.commons.lang.builder.HashCodeBuilder;
-import org.apache.phoenix.pherf.util.PhoenixUtil;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.phoenix.pherf.util.PhoenixUtil;
 
 @XmlRootElement(namespace = "org.apache.phoenix.pherf.configuration.DataModel")
 public class Scenario {
@@ -37,6 +38,7 @@ public class Scenario {
     private List<QuerySet> querySet = new ArrayList<>();
     private WriteParams writeParams;
     private String name;
+    private String tenantId;
 
     public Scenario() {
         writeParams = new WriteParams();
@@ -162,6 +164,19 @@ public class Scenario {
     public void setName(String name) {
         this.name = name;
     }
+    
+    /**
+     * Tenant Id used by connection of this query
+     * @return
+     */
+    @XmlAttribute
+    public String getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(String tenantId) {
+        this.tenantId = tenantId;
+    }
 
     public WriteParams getWriteParams() {
         return writeParams;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/42476da8/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/XMLConfigParser.java
----------------------------------------------------------------------
diff --git 
a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/XMLConfigParser.java
 
b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/XMLConfigParser.java
index 393fa7e..93dc94c 100644
--- 
a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/XMLConfigParser.java
+++ 
b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/XMLConfigParser.java
@@ -18,16 +18,6 @@
 
 package org.apache.phoenix.pherf.configuration;
 
-import org.apache.phoenix.pherf.PherfConstants;
-import org.apache.phoenix.pherf.exception.FileLoaderException;
-import org.apache.phoenix.pherf.util.ResourceList;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
 import java.io.OutputStream;
 import java.nio.file.Path;
 import java.util.ArrayList;
@@ -35,6 +25,17 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.phoenix.pherf.PherfConstants;
+import org.apache.phoenix.pherf.exception.FileLoaderException;
+import org.apache.phoenix.pherf.util.ResourceList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 public class XMLConfigParser {
 
     private static final Logger logger = 
LoggerFactory.getLogger(XMLConfigParser.class);
@@ -134,6 +135,8 @@ public class XMLConfigParser {
         if (fullTableName.contains(".")) {
             ret = fullTableName.substring(fullTableName.indexOf(".") + 1, 
fullTableName.length());
         }
+        // Remove any quotes that may be needed for multi-tenant tables
+        ret = ret.replaceAll("\"", "");
         return ret;
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/42476da8/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/util/PhoenixUtil.java
----------------------------------------------------------------------
diff --git 
a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/util/PhoenixUtil.java 
b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/util/PhoenixUtil.java
index 5b223b1..19b6bd2 100644
--- a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/util/PhoenixUtil.java
+++ b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/util/PhoenixUtil.java
@@ -18,21 +18,29 @@
 
 package org.apache.phoenix.pherf.util;
 
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SCHEM;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
 import org.apache.phoenix.pherf.PherfConstants;
 import org.apache.phoenix.pherf.configuration.Column;
 import org.apache.phoenix.pherf.configuration.DataTypeMapping;
-
-import java.sql.*;
-import java.util.*;
-
 import org.apache.phoenix.pherf.configuration.Query;
 import org.apache.phoenix.pherf.configuration.QuerySet;
+import org.apache.phoenix.pherf.configuration.Scenario;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SCHEM;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME;
-
 // TODO This class needs to be cleanup up a bit. I just wanted to get an 
initial placeholder in.
 public class PhoenixUtil {
        private static final Logger logger = 
LoggerFactory.getLogger(PhoenixUtil.class);
@@ -80,11 +88,11 @@ public class PhoenixUtil {
         return DriverManager.getConnection(url, props);
     }
 
-    public boolean executeStatement(String sql) throws Exception {
+    public boolean executeStatement(String sql, Scenario scenario) throws 
Exception {
         Connection connection = null;
         boolean result = false;
         try {
-            connection = getConnection();
+            connection = getConnection(scenario.getTenantId());
             result = executeStatement(sql, connection);
         } finally {
             if (connection != null) {
@@ -262,8 +270,8 @@ public class PhoenixUtil {
      * @param tableName
      * @throws Exception
      */
-    public void updatePhoenixStats(String tableName) throws Exception {
+    public void updatePhoenixStats(String tableName, Scenario scenario) throws 
Exception {
         logger.info("Updating stats for " + tableName);
-        executeStatement("UPDATE STATISTICS " + tableName);
+        executeStatement("UPDATE STATISTICS " + tableName, scenario);
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/42476da8/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/WriteWorkload.java
----------------------------------------------------------------------
diff --git 
a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/WriteWorkload.java
 
b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/WriteWorkload.java
index b6686c6..d0b99af 100644
--- 
a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/WriteWorkload.java
+++ 
b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/WriteWorkload.java
@@ -18,6 +18,21 @@
 
 package org.apache.phoenix.pherf.workload;
 
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
 import org.apache.phoenix.pherf.PherfConstants;
 import org.apache.phoenix.pherf.PherfConstants.GeneratePhoenixStats;
 import org.apache.phoenix.pherf.configuration.Column;
@@ -35,17 +50,6 @@ import org.apache.phoenix.pherf.util.RowCalculator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.math.BigDecimal;
-import java.sql.*;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-
 public class WriteWorkload implements Workload {
     private static final Logger logger = 
LoggerFactory.getLogger(WriteWorkload.class);
     private final PhoenixUtil pUtil;
@@ -163,15 +167,18 @@ public class WriteWorkload implements Workload {
         List<Future> writeBatches = getBatches(dataLoadThreadTime, scenario);
 
         waitForBatches(dataLoadTimeSummary, scenario, start, writeBatches);
-        
+
         // Update Phoenix Statistics
         if (this.generateStatistics == GeneratePhoenixStats.YES) {
                logger.info("Updating Phoenix table statistics...");
-               pUtil.updatePhoenixStats(scenario.getTableName());
+               pUtil.updatePhoenixStats(scenario.getTableName(), scenario);
                logger.info("Stats update done!");
         } else {
                logger.info("Phoenix table stats update not requested.");
         }
+
+        // always update stats for Phoenix base tables
+        updatePhoenixStats(scenario.getTableName(), scenario);
     }
 
     private List<Future> getBatches(DataLoadThreadTime dataLoadThreadTime, 
Scenario scenario)
@@ -185,7 +192,7 @@ public class WriteWorkload implements Workload {
             List<Column>
                     phxMetaCols =
                     pUtil.getColumnsFromPhoenix(scenario.getSchemaName(),
-                            scenario.getTableNameWithoutSchemaName(), 
pUtil.getConnection());
+                            scenario.getTableNameWithoutSchemaName(), 
pUtil.getConnection(scenario.getTenantId()));
             int threadRowCount = rowCalculator.getNext();
             logger.info(
                     "Kick off thread (#" + i + ")for upsert with (" + 
threadRowCount + ") rows.");
@@ -221,6 +228,18 @@ public class WriteWorkload implements Workload {
                 .add(scenario.getTableName(), sumRows, (int) 
(System.currentTimeMillis() - start));
     }
 
+    /**
+     * TODO Move this method to PhoenixUtil
+     * Update Phoenix table stats
+     *
+     * @param tableName
+     * @throws Exception
+     */
+    public void updatePhoenixStats(String tableName, Scenario scenario) throws 
Exception {
+        logger.info("Updating stats for " + tableName);
+        pUtil.executeStatement("UPDATE STATISTICS " + tableName, scenario);
+    }
+
     public Future<Info> upsertData(final Scenario scenario, final List<Column> 
columns,
             final String tableName, final int rowCount,
             final DataLoadThreadTime dataLoadThreadTime) {
@@ -231,7 +250,7 @@ public class WriteWorkload implements Workload {
                 SimpleDateFormat simpleDateFormat = new 
SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                 Connection connection = null;
                 try {
-                    connection = pUtil.getConnection();
+                    connection = pUtil.getConnection(scenario.getTenantId());
                     long logStartTime = System.currentTimeMillis();
                     long
                             maxDuration =

http://git-wip-us.apache.org/repos/asf/phoenix/blob/42476da8/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_table.sql
----------------------------------------------------------------------
diff --git 
a/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_table.sql 
b/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_table.sql
new file mode 100644
index 0000000..b6791bf
--- /dev/null
+++ b/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_table.sql
@@ -0,0 +1,31 @@
+/*
+  -- Licensed to the Apache Software Foundation (ASF) under one
+  -- or more contributor license agreements.  See the NOTICE file
+  -- distributed with this work for additional information
+  -- regarding copyright ownership.  The ASF licenses this file
+  -- to you under the Apache License, Version 2.0 (the
+  -- "License"); you may not use this file except in compliance
+  -- with the License.  You may obtain a copy of the License at
+  --
+  -- http://www.apache.org/licenses/LICENSE-2.0
+  --
+  -- Unless required by applicable law or agreed to in writing, software
+  -- distributed under the License is distributed on an "AS IS" BASIS,
+  -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  -- See the License for the specific language governing permissions and
+  -- limitations under the License.
+*/
+CREATE TABLE IF NOT EXISTS PHERF.TEST_MULTI_TENANT_TABLE (
+    TENANT_ID CHAR(15) NOT NULL,
+    IDENTIFIER CHAR(3) NOT NULL,
+    ID CHAR(15) NOT NULL,
+    CREATED_DATE DATE,
+    FIELD VARCHAR,
+    SOME_INT INTEGER
+    CONSTRAINT PK PRIMARY KEY
+    (
+        TENANT_ID,
+        IDENTIFIER,
+        ID
+    )
+) VERSIONS=1,MULTI_TENANT=true

http://git-wip-us.apache.org/repos/asf/phoenix/blob/42476da8/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_view.sql
----------------------------------------------------------------------
diff --git a/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_view.sql 
b/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_view.sql
new file mode 100644
index 0000000..5f5d7ec
--- /dev/null
+++ b/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_view.sql
@@ -0,0 +1 @@
+CREATE VIEW IF NOT EXISTS PHERF.TEST_VIEW (field1 VARCHAR, field2 VARCHAR) AS 
SELECT * FROM PHERF.TEST_MULTI_TENANT_TABLE
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/42476da8/phoenix-pherf/src/test/resources/scenario/test_scenario.xml
----------------------------------------------------------------------
diff --git a/phoenix-pherf/src/test/resources/scenario/test_scenario.xml 
b/phoenix-pherf/src/test/resources/scenario/test_scenario.xml
index fddf022..b5fe564 100644
--- a/phoenix-pherf/src/test/resources/scenario/test_scenario.xml
+++ b/phoenix-pherf/src/test/resources/scenario/test_scenario.xml
@@ -127,6 +127,25 @@
             <name>NEWVAL_STRING</name>
             <prefix>TSTPRFX</prefix>
         </column>
+        <column>
+            <type>CHAR</type>
+            <length>3</length>
+            <userDefined>true</userDefined>
+            <dataSequence>LIST</dataSequence>
+            <name>IDENTIFIER</name>
+            <valuelist>
+                <!-- Distributes according to specified values. These must 
total 100 -->
+                <datavalue distribution="60">
+                    <value>ABC</value>
+                </datavalue>
+                <datavalue distribution="20">
+                    <value>XYZ</value>
+                </datavalue>
+                <datavalue distribution="20">
+                    <value>LMN</value>
+                </datavalue>
+            </valuelist>            
+        </column>        
     </datamapping>
     <scenarios>
         <scenario tableName="PHERF.TEST_TABLE" rowCount="100" 
name="testScenarioRW">
@@ -201,5 +220,8 @@
                 <query id="q4" statement="select sum(SOME_INT) from 
PHERF.TEST_TABLE"/>
             </querySet>
         </scenario>
+        <!-- Test writing to a Multi-tenant View -->
+        <scenario tableName="PHERF.TEST_VIEW" tenantId="abcdefghijklmno" 
rowCount="100" name="testMTWriteScenario">
+        </scenario>
     </scenarios>
 </datamodel>
\ No newline at end of file

Reply via email to