You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ds...@apache.org on 2017/11/02 00:24:58 UTC

[geode] branch feature/GEODE-3781 updated: added valueClassName config property

This is an automated email from the ASF dual-hosted git repository.

dschneider pushed a commit to branch feature/GEODE-3781
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/feature/GEODE-3781 by this push:
     new 5ef3139  added valueClassName config property
5ef3139 is described below

commit 5ef31399a85161b3e6163e54e9e1942ba009d215
Author: Darrel Schneider <ds...@pivotal.io>
AuthorDate: Wed Nov 1 17:24:36 2017 -0700

    added valueClassName config property
---
 .../jdbc/internal/JDBCConfiguration.java           | 62 +++++++++++++++++++++-
 .../connectors/jdbc/internal/JDBCManager.java      | 11 ++--
 .../jdbc/internal/JDBCConfigurationUnitTest.java   | 44 ++++++++++++++-
 .../jdbc/internal/JDBCManagerUnitTest.java         | 49 ++++++++++++++---
 4 files changed, 149 insertions(+), 17 deletions(-)

diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JDBCConfiguration.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JDBCConfiguration.java
index 55fa3bd..cd2c75c 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JDBCConfiguration.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JDBCConfiguration.java
@@ -17,18 +17,26 @@ package org.apache.geode.connectors.jdbc.internal;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.function.IntPredicate;
 
 public class JDBCConfiguration {
   private static final String URL = "url";
   private static final String USER = "user";
   private static final String PASSWORD = "password";
+  /**
+   * syntax: comma separated list of classSpecs. classSpec: optional regionName followed by
+   * className
+   */
+  private static final String VALUE_CLASS_NAME = "valueClassName";
 
   private static final List<String> knownProperties =
-      Collections.unmodifiableList(Arrays.asList(URL, USER, PASSWORD));
+      Collections.unmodifiableList(Arrays.asList(URL, USER, PASSWORD, VALUE_CLASS_NAME));
 
   private static final List<String> requiredProperties =
       Collections.unmodifiableList(Arrays.asList(URL));
@@ -36,6 +44,8 @@ public class JDBCConfiguration {
   private final String url;
   private final String user;
   private final String password;
+  private final String valueClassName;
+  private final Map<String, String> regionToClassMap;
 
   public JDBCConfiguration(Properties configProps) {
     validateKnownProperties(configProps);
@@ -43,6 +53,46 @@ public class JDBCConfiguration {
     this.url = configProps.getProperty(URL);
     this.user = configProps.getProperty(USER);
     this.password = configProps.getProperty(PASSWORD);
+    String valueClassNameProp = configProps.getProperty(VALUE_CLASS_NAME);
+    this.valueClassName = computeValueClassName(valueClassNameProp);
+    this.regionToClassMap = computeRegionToClassMap(valueClassNameProp);
+  }
+
+  private static Map<String, String> computeRegionToClassMap(String valueClassNameProp) {
+    if (valueClassNameProp == null) {
+      return null;
+    }
+    Map<String, String> result = new HashMap<>();
+    List<String> items = Arrays.asList(valueClassNameProp.split("\\s*,\\s*"));
+    for (String item : items) {
+      int idx = item.indexOf(':');
+      if (idx == -1) {
+        continue;
+      }
+      String regionName = item.substring(0, idx);
+      String className = item.substring(idx + 1);
+      result.put(regionName, className);
+    }
+    return result;
+  }
+
+  private static String computeValueClassName(String valueClassNameProp) {
+    if (valueClassNameProp == null) {
+      return null;
+    }
+    String result = null;
+    List<String> items = Arrays.asList(valueClassNameProp.split("\\s*,\\s*"));
+    for (String item : items) {
+      if (item.indexOf(':') != -1) {
+        continue;
+      }
+      if (result != null) {
+        throw new IllegalArgumentException(
+            VALUE_CLASS_NAME + " can have at most one item that does not have a ':' in it.");
+      }
+      result = item;
+    }
+    return result;
   }
 
   private void validateKnownProperties(Properties configProps) {
@@ -74,4 +124,14 @@ public class JDBCConfiguration {
     return this.password;
   }
 
+  public String getValueClassName(String regionName) {
+    if (this.regionToClassMap == null) {
+      return this.valueClassName;
+    }
+    String result = this.regionToClassMap.get(regionName);
+    if (result == null) {
+      result = this.valueClassName;
+    }
+    return result;
+  }
 }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JDBCManager.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JDBCManager.java
index 8c1397a..377b794 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JDBCManager.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JDBCManager.java
@@ -74,10 +74,10 @@ public class JDBCManager {
         ResultSet rs = pstmt.executeQuery();
         if (rs.next()) {
           InternalCache cache = (InternalCache) region.getRegionService();
-          String objectClassName = getObjectClassName(tableName);
+          String valueClassName = getValueClassName(region.getName());
           PdxInstanceFactory factory;
-          if (objectClassName != null) {
-            factory = cache.createPdxInstanceFactory(objectClassName);
+          if (valueClassName != null) {
+            factory = cache.createPdxInstanceFactory(valueClassName);
           } else {
             factory = cache.createPdxInstanceFactory("no class", false);
           }
@@ -110,9 +110,8 @@ public class JDBCManager {
     }
   }
 
-  private String getObjectClassName(String tableName) {
-    // TODO NYI
-    return null;
+  private String getValueClassName(String regionName) {
+    return this.config.getValueClassName(regionName);
   }
 
   public void write(Region region, Operation operation, Object key, PdxInstance value) {
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JDBCConfigurationUnitTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JDBCConfigurationUnitTest.java
index 28835a3..3973489 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JDBCConfigurationUnitTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JDBCConfigurationUnitTest.java
@@ -14,10 +14,13 @@
  */
 package org.apache.geode.connectors.jdbc.internal;
 
+import static com.googlecode.catchexception.CatchException.catchException;
+import static com.googlecode.catchexception.CatchException.caughtException;
 import static org.assertj.core.api.Assertions.*;
 
 import java.util.Properties;
 
+import org.apache.geode.cache.Operation;
 import org.apache.geode.connectors.jdbc.internal.JDBCConfiguration;
 import org.apache.geode.test.junit.categories.UnitTest;
 import org.junit.*;
@@ -61,7 +64,7 @@ public class JDBCConfigurationUnitTest {
     Properties props = new Properties();
     props.setProperty("url", "");
     JDBCConfiguration config = new JDBCConfiguration(props);
-    assertThat(config.getUser()).isEqualTo(null);
+    assertThat(config.getUser()).isNull();
   }
 
   @Test
@@ -69,7 +72,7 @@ public class JDBCConfigurationUnitTest {
     Properties props = new Properties();
     props.setProperty("url", "");
     JDBCConfiguration config = new JDBCConfiguration(props);
-    assertThat(config.getPassword()).isEqualTo(null);
+    assertThat(config.getPassword()).isNull();
   }
 
   @Test
@@ -89,4 +92,41 @@ public class JDBCConfigurationUnitTest {
     JDBCConfiguration config = new JDBCConfiguration(props);
     assertThat(config.getPassword()).isEqualTo("myPassword");
   }
+
+  @Test
+  public void testDefaultValueClassName() {
+    Properties props = new Properties();
+    props.setProperty("url", "");
+    JDBCConfiguration config = new JDBCConfiguration(props);
+    assertThat(config.getValueClassName("foo")).isNull();
+  }
+
+  @Test
+  public void testValueClassName() {
+    Properties props = new Properties();
+    props.setProperty("url", "");
+    props.setProperty("valueClassName", "myPackage.myDomainClass");
+    JDBCConfiguration config = new JDBCConfiguration(props);
+    assertThat(config.getValueClassName("foo")).isEqualTo("myPackage.myDomainClass");
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void verifyThatTwoClassNamesWithNoRegionNameThrows() {
+    Properties props = new Properties();
+    props.setProperty("url", "");
+    props.setProperty("valueClassName", "myClass1, myClass2");
+    new JDBCConfiguration(props);
+  }
+
+  @Test
+  public void testValueClassNameWithRegionNames() {
+    Properties props = new Properties();
+    props.setProperty("url", "");
+    props.setProperty("valueClassName", "reg1:cn1   , reg2:pack2.cn2,myPackage.myDomainClass");
+    JDBCConfiguration config = new JDBCConfiguration(props);
+    assertThat(config.getValueClassName("foo")).isEqualTo("myPackage.myDomainClass");
+    assertThat(config.getValueClassName("reg1")).isEqualTo("cn1");
+    assertThat(config.getValueClassName("reg2")).isEqualTo("pack2.cn2");
+  }
+
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JDBCManagerUnitTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JDBCManagerUnitTest.java
index 88c8abe..a18088d 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JDBCManagerUnitTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JDBCManagerUnitTest.java
@@ -164,7 +164,7 @@ public class JDBCManagerUnitTest {
   @After
   public void tearDown() throws Exception {}
 
-  private void createManager(String url) throws SQLException {
+  private void createManager(String url, String valueClassName) throws SQLException {
     ResultSet rsKeys = mock(ResultSet.class);
     when(rsKeys.next()).thenReturn(true, false);
     when(rsKeys.getString("COLUMN_NAME")).thenReturn(ID_COLUMN_NAME);
@@ -173,30 +173,34 @@ public class JDBCManagerUnitTest {
     when(rs.next()).thenReturn(true, false);
     when(rs.getString("TABLE_NAME")).thenReturn(regionName.toUpperCase());
 
-    this.mgr = new TestableJDBCManagerWithResultSets(createConfiguration(url), rs, rsKeys, null);
+    this.mgr = new TestableJDBCManagerWithResultSets(createConfiguration(url, valueClassName), rs,
+        rsKeys, null);
   }
 
   private void createDefaultManager() throws SQLException {
-    createManager("fakeURL");
+    createManager("fakeURL", null);
   }
 
   private void createUpsertManager() {
-    this.mgr = new TestableUpsertJDBCManager(createConfiguration("fakeURL"));
+    this.mgr = new TestableUpsertJDBCManager(createConfiguration("fakeURL", null));
   }
 
   private void createUpsertManager(int upsertReturn) {
-    this.mgr = new TestableUpsertJDBCManager(createConfiguration("fakeURL"), upsertReturn);
+    this.mgr = new TestableUpsertJDBCManager(createConfiguration("fakeURL", null), upsertReturn);
   }
 
   private void createManager(ResultSet tableNames, ResultSet primaryKeys,
       ResultSet queryResultSet) {
-    this.mgr = new TestableJDBCManagerWithResultSets(createConfiguration("fakeURL"), tableNames,
-        primaryKeys, queryResultSet);
+    this.mgr = new TestableJDBCManagerWithResultSets(createConfiguration("fakeURL", null),
+        tableNames, primaryKeys, queryResultSet);
   }
 
-  private JDBCConfiguration createConfiguration(String url) {
+  private JDBCConfiguration createConfiguration(String url, String valueClassName) {
     Properties props = new Properties();
     props.setProperty("url", url);
+    if (valueClassName != null) {
+      props.setProperty("valueClassName", valueClassName);
+    }
     return new JDBCConfiguration(props);
   }
 
@@ -540,4 +544,33 @@ public class JDBCManagerUnitTest {
     assertThat(fieldNameCaptor.getAllValues()).isEqualTo(Arrays.asList("name", "age"));
     assertThat(fieldValueCaptor.getAllValues()).isEqualTo(Arrays.asList("Emp1", 21));
   }
+
+  @Test
+  public void verifyReadWithValueClassName() throws SQLException {
+    createManager("myUrl", regionName + ":myValueClass");
+    GemFireCacheImpl cache = Fakes.cache();
+    PdxInstanceFactory factory = mock(PdxInstanceFactory.class);
+    PdxInstance pi = mock(PdxInstance.class);
+    when(factory.create()).thenReturn(pi);
+    when(cache.createPdxInstanceFactory("myValueClass")).thenReturn(factory);
+
+    Region region = Fakes.region(regionName, cache);
+    Object key = "1";
+    PdxInstance value = this.mgr.read(region, key);
+    ArgumentCaptor<String> sqlCaptor = ArgumentCaptor.forClass(String.class);
+    verify(this.connection).prepareStatement(sqlCaptor.capture());
+    assertThat(sqlCaptor.getValue())
+        .isEqualTo("SELECT * FROM " + regionName + " WHERE " + ID_COLUMN_NAME + " = ?");
+    ArgumentCaptor<Object> objectCaptor = ArgumentCaptor.forClass(Object.class);
+    verify(this.preparedStatement, times(1)).setObject(anyInt(), objectCaptor.capture());
+    List<Object> allObjects = objectCaptor.getAllValues();
+    assertThat(allObjects.get(0)).isEqualTo("1");
+    assertThat(value).isSameAs(pi);
+    ArgumentCaptor<String> fieldNameCaptor = ArgumentCaptor.forClass(String.class);
+    ArgumentCaptor<Object> fieldValueCaptor = ArgumentCaptor.forClass(Object.class);
+    verify(factory, times(2)).writeField(fieldNameCaptor.capture(), fieldValueCaptor.capture(),
+        any());
+    assertThat(fieldNameCaptor.getAllValues()).isEqualTo(Arrays.asList("name", "age"));
+    assertThat(fieldValueCaptor.getAllValues()).isEqualTo(Arrays.asList("Emp1", 21));
+  }
 }

-- 
To stop receiving notification emails like this one, please contact
['"commits@geode.apache.org" <co...@geode.apache.org>'].