You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by jc...@apache.org on 2019/02/28 01:57:38 UTC

[geode] branch feature/GEODE-6459 updated: wip

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

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


The following commit(s) were added to refs/heads/feature/GEODE-6459 by this push:
     new 413fd2e  wip
413fd2e is described below

commit 413fd2ea4ae77c4ca83b6378846a6dd84fc0df85
Author: Jianxia Chen <jc...@pivotal.io>
AuthorDate: Wed Feb 27 17:57:16 2019 -0800

    wip
    
    Co-authored-by: Darrel Schneider <ds...@pivotal.io>
    Co-authored-by: Jianxia Chen <jc...@pivotal.io>
---
 .../cli/CreateMappingCommandDUnitTest.java         |  49 +++++++++-
 .../jdbc/internal/cli/CreateMappingCommand.java    |  33 ++++---
 .../CreateMappingPreconditionCheckFunction.java    | 107 +++++++++++++++++++--
 .../internal/cli/CreateMappingCommandTest.java     |  65 +++++++------
 ...CreateMappingPreconditionCheckFunctionTest.java |  10 +-
 5 files changed, 211 insertions(+), 53 deletions(-)

diff --git a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java
index 93d2aaf..1d7ef00 100644
--- a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java
+++ b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java
@@ -28,6 +28,7 @@ import static org.apache.geode.connectors.util.internal.MappingConstants.TABLE_N
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.sql.Connection;
@@ -66,7 +67,9 @@ import org.apache.geode.pdx.FieldType;
 import org.apache.geode.pdx.PdxReader;
 import org.apache.geode.pdx.PdxSerializable;
 import org.apache.geode.pdx.PdxWriter;
+import org.apache.geode.test.compiler.CompiledSourceCode;
 import org.apache.geode.test.compiler.JarBuilder;
+import org.apache.geode.test.compiler.JavaCompiler;
 import org.apache.geode.test.dunit.IgnoredException;
 import org.apache.geode.test.dunit.rules.ClusterStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
@@ -563,6 +566,20 @@ public class CreateMappingCommandDUnitTest {
     return outputJar;
   }
 
+  private File createClassFile() throws IOException {
+    final JavaCompiler javaCompiler = new JavaCompiler();
+    File source = loadTestResource(
+        "/org/apache/geode/internal/ResourcePDX.java");
+    List<CompiledSourceCode> compiledSourceCodes = javaCompiler.compile(source);
+    String className = compiledSourceCodes.get(0).className;
+    String fileName = className.substring(className.lastIndexOf(".") + 1) + ".class";
+    File file = new File(temporaryFolder.getRoot(), fileName);
+    FileOutputStream fileOutputStream = new FileOutputStream(file);
+    fileOutputStream.write(compiledSourceCodes.get(0).compiledBytecode);
+    fileOutputStream.close();
+    return file;
+  }
+
   @Test
   public void createMappingWithoutExistingPdxNameFails() {
     String region1Name = "region1";
@@ -610,7 +627,7 @@ public class CreateMappingCommandDUnitTest {
   }
 
   @Test
-  public void createMappingWithPdxClassFile() throws IOException, URISyntaxException {
+  public void createMappingWithPdxClassFileSetToAJarFile() throws IOException, URISyntaxException {
     String region1Name = "region1";
     setupReplicate(region1Name);
     File jarFile = createJar();
@@ -638,6 +655,36 @@ public class CreateMappingCommandDUnitTest {
     });
   }
 
+  @Test
+  public void createMappingWithPdxClassFileSetToAClassFile()
+      throws IOException, URISyntaxException {
+    String region1Name = "region1";
+    setupReplicate(region1Name);
+    File classFile = createClassFile();
+
+    CommandStringBuilder csb = new CommandStringBuilder(CREATE_MAPPING);
+    csb.addOption(REGION_NAME, region1Name);
+    csb.addOption(DATA_SOURCE_NAME, "connection");
+    csb.addOption(TABLE_NAME, "employeeRegion");
+    csb.addOption(PDX_NAME, "org.apache.geode.internal.ResourcePDX");
+    csb.addOption(ID_NAME, "id");
+    csb.addOption(SCHEMA_NAME, "mySchema");
+    csb.addOption(PDX_CLASS_FILE, classFile);
+
+    gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess();
+
+    server1.invoke(() -> {
+      RegionMapping mapping = getRegionMappingFromService(region1Name);
+      assertValidResourcePDXMappingOnServer(mapping, region1Name, false, false, "employeeRegion");
+    });
+
+    locator.invoke(() -> {
+      RegionMapping regionMapping = getRegionMappingFromClusterConfig(region1Name, null);
+      assertValidResourcePDXMappingOnLocator(regionMapping, region1Name, null, false, false,
+          "employeeRegion");
+    });
+  }
+
   private static void assertValidEmployeeMapping(RegionMapping mapping, String tableName) {
     assertThat(mapping.getDataSourceName()).isEqualTo("connection");
     assertThat(mapping.getTableName()).isEqualTo(tableName);
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java
index f17022a..492efb0 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java
@@ -14,13 +14,10 @@
  */
 package org.apache.geode.connectors.jdbc.internal.cli;
 
-import static org.apache.commons.io.FileUtils.ONE_MB;
 
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
@@ -29,7 +26,6 @@ import com.healthmarketscience.rmiio.RemoteInputStream;
 import com.healthmarketscience.rmiio.SimpleRemoteInputStream;
 import com.healthmarketscience.rmiio.exporter.RemoteStreamExporter;
 import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
 import org.springframework.shell.core.annotation.CliCommand;
@@ -58,7 +54,6 @@ import org.apache.geode.management.cli.SingleGfshCommand;
 import org.apache.geode.management.internal.ManagementAgent;
 import org.apache.geode.management.internal.SystemManagementService;
 import org.apache.geode.management.internal.cli.AbstractCliAroundInterceptor;
-import org.apache.geode.management.internal.cli.CliUtil;
 import org.apache.geode.management.internal.cli.GfshParseResult;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.management.internal.cli.i18n.CliStrings;
@@ -104,7 +99,7 @@ public class CreateMappingCommand extends SingleGfshCommand {
       "The names of the server groups on which this mapping should be created.";
   private static final String CREATE_MAPPING__PDX_CLASS_FILE = MappingConstants.PDX_CLASS_FILE;
   private static final String CREATE_MAPPING__PDX_CLASS_FILE__HELP =
-      "The file that contains the PDX class. It can be a jar or class file. By default, the PDX class must be on the server's classpath or gfsh deployed.";
+      "The file that contains the PDX class. It must be a file with the \".jar\" or \".class\" extension. By default, the PDX class must be on the server's classpath or gfsh deployed.";
 
   @CliCommand(value = CREATE_MAPPING, help = CREATE_MAPPING__HELP)
   @CliMetaData(
@@ -133,20 +128,23 @@ public class CreateMappingCommand extends SingleGfshCommand {
           help = CREATE_MAPPING__SCHEMA_NAME__HELP) String schema,
       @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
           optionContext = ConverterHint.MEMBERGROUP,
-          help = CREATE_MAPPING__GROUPS_NAME__HELP) String[] groups) throws IOException {
+          help = CREATE_MAPPING__GROUPS_NAME__HELP) String[] groups)
+      throws IOException {
     if (regionName.startsWith("/")) {
       regionName = regionName.substring(1);
     }
 
-    System.out.println("DDDDDD" + pdxClassFile);
     String tempPdxClassFilePath = null;
+    String remoteInputStreamName = null;
+    RemoteInputStream remoteInputStream = null;
     if (pdxClassFile != null) {
       List<String> pdxClassFilePaths = CommandExecutionContext.getFilePathFromShell();
       if (pdxClassFilePaths.size() != 1) {
-        throw new IllegalStateException("Expected only one element in the list returned by getFilePathFromShell, but it returned: " + pdxClassFilePaths);
+        throw new IllegalStateException(
+            "Expected only one element in the list returned by getFilePathFromShell, but it returned: "
+                + pdxClassFilePaths);
       }
       tempPdxClassFilePath = pdxClassFilePaths.get(0);
-      System.out.println("DDDDDD" + pdxClassFilePaths);
     }
 
     Set<DistributedMember> targetMembers = findMembers(groups, null);
@@ -173,11 +171,15 @@ public class CreateMappingCommand extends SingleGfshCommand {
     }
     ManagementAgent agent = ((SystemManagementService) getManagementService()).getManagementAgent();
     RemoteStreamExporter exporter = agent.getRemoteStreamExporter();
-    String remoteInputStreamName = FilenameUtils.getName(tempPdxClassFilePath);
-    RemoteInputStream remoteInputStream = exporter.export(new SimpleRemoteInputStream(new FileInputStream(tempPdxClassFilePath)));
+    if (pdxClassFile != null) {
+      remoteInputStreamName = FilenameUtils.getName(tempPdxClassFilePath);
+      remoteInputStream =
+          exporter.export(new SimpleRemoteInputStream(new FileInputStream(tempPdxClassFilePath)));
+    }
 
     CliFunctionResult preconditionCheckResult =
-        executeFunctionAndGetFunctionResult(new CreateMappingPreconditionCheckFunction(), new Object[] {mapping, remoteInputStreamName, remoteInputStream},
+        executeFunctionAndGetFunctionResult(new CreateMappingPreconditionCheckFunction(),
+            new Object[] {mapping, remoteInputStreamName, remoteInputStream},
             targetMembers.iterator().next());
     try {
       remoteInputStream.close(true);
@@ -384,6 +386,11 @@ public class CreateMappingCommand extends SingleGfshCommand {
       if (!pdxClassFile.exists()) {
         return ResultBuilder.createUserErrorResult(pdxClassFile + " not found.");
       }
+      String fileExtension = FilenameUtils.getExtension(pdxClassFileName);
+      if (!fileExtension.equalsIgnoreCase("jar") && !fileExtension.equalsIgnoreCase("class")) {
+        return ResultBuilder
+            .createUserErrorResult(pdxClassFile + " must end with \".jar\" or \".class\".");
+      }
       fileResult.addFile(pdxClassFile);
 
       return fileResult;
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingPreconditionCheckFunction.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingPreconditionCheckFunction.java
index 40f04d1..08fdacf 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingPreconditionCheckFunction.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingPreconditionCheckFunction.java
@@ -14,9 +14,18 @@
  */
 package org.apache.geode.connectors.jdbc.internal.cli;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.sql.Connection;
 import java.sql.JDBCType;
 import java.sql.SQLException;
@@ -26,6 +35,12 @@ import java.util.Set;
 
 import javax.sql.DataSource;
 
+import com.healthmarketscience.rmiio.RemoteInputStream;
+import com.healthmarketscience.rmiio.RemoteInputStreamClient;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+
 import org.apache.geode.SerializationException;
 import org.apache.geode.annotations.Experimental;
 import org.apache.geode.cache.execute.FunctionContext;
@@ -39,6 +54,7 @@ import org.apache.geode.internal.ClassPathLoader;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.jndi.JNDIInvoker;
 import org.apache.geode.management.cli.CliFunction;
+import org.apache.geode.management.internal.beans.FileUploader;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.pdx.PdxWriter;
 import org.apache.geode.pdx.ReflectionBasedAutoSerializer;
@@ -49,13 +65,14 @@ import org.apache.geode.pdx.internal.PdxWriterImpl;
 import org.apache.geode.pdx.internal.TypeRegistry;
 
 @Experimental
-public class CreateMappingPreconditionCheckFunction extends CliFunction<RegionMapping> {
+public class CreateMappingPreconditionCheckFunction extends CliFunction<Object[]> {
 
   private transient DataSourceFactory dataSourceFactory;
   private transient ClassFactory classFactory;
   private transient ReflectionBasedAutoSerializerFactory reflectionBasedAutoSerializerFactory;
   private transient PdxWriterFactory pdxWriterFactory;
   private transient TableMetaDataManager tableMetaDataManager;
+  private transient File topLevelDir;
 
   CreateMappingPreconditionCheckFunction(DataSourceFactory factory, ClassFactory classFactory,
       ReflectionBasedAutoSerializerFactory reflectionBasedAutoSerializerFactory,
@@ -88,9 +105,11 @@ public class CreateMappingPreconditionCheckFunction extends CliFunction<RegionMa
   }
 
   @Override
-  public CliFunctionResult executeFunction(FunctionContext<RegionMapping> context)
-      throws Exception {
-    RegionMapping regionMapping = context.getArguments();
+  public CliFunctionResult executeFunction(FunctionContext<Object[]> context) {
+    Object[] args = context.getArguments();
+    RegionMapping regionMapping = (RegionMapping) args[0];
+    String remoteInputStreamName = (String) args[1];
+    RemoteInputStream remoteInputStream = (RemoteInputStream) args[2];
     String dataSourceName = regionMapping.getDataSourceName();
     DataSource dataSource = dataSourceFactory.getDataSource(dataSourceName);
     if (dataSource == null) {
@@ -100,7 +119,8 @@ public class CreateMappingPreconditionCheckFunction extends CliFunction<RegionMa
     }
     InternalCache cache = (InternalCache) context.getCache();
     TypeRegistry typeRegistry = cache.getPdxRegistry();
-    PdxType pdxType = getPdxTypeForClass(cache, typeRegistry, regionMapping.getPdxName());
+    PdxType pdxType = getPdxTypeForClass(cache, typeRegistry, regionMapping.getPdxName(),
+        remoteInputStreamName, remoteInputStream);
     try (Connection connection = dataSource.getConnection()) {
       TableMetaDataView tableMetaData =
           tableMetaDataManager.getTableMetaDataView(connection, regionMapping);
@@ -168,8 +188,8 @@ public class CreateMappingPreconditionCheckFunction extends CliFunction<RegionMa
   }
 
   private PdxType getPdxTypeForClass(InternalCache cache, TypeRegistry typeRegistry,
-      String className) {
-    Class<?> clazz = loadPdxClass(className);
+      String className, String remoteInputStreamName, RemoteInputStream remoteInputStream) {
+    Class<?> clazz = loadPdxClass(className, remoteInputStreamName, remoteInputStream);
     PdxType result = typeRegistry.getExistingTypeForClass(clazz);
     if (result != null) {
       return result;
@@ -220,15 +240,50 @@ public class CreateMappingPreconditionCheckFunction extends CliFunction<RegionMa
     }
   }
 
-  private Class<?> loadPdxClass(String className) {
+  private Class<?> loadPdxClass(String className, String remoteInputStreamName,
+      RemoteInputStream remoteInputStream) {
     try {
-      return this.classFactory.loadClass(className);
+      if (remoteInputStream != null) {
+        File file =
+            copyRemoteInputStreamToTempFile(className, remoteInputStreamName, remoteInputStream);
+        try {
+          return URLClassLoader.newInstance(new URL[] {createURL(file)}).loadClass(className);
+        } finally {
+          try {
+            FileUtils.deleteDirectory(this.topLevelDir);
+          } catch (IOException ioe) {
+            // ignore
+          }
+        }
+      } else {
+        return this.classFactory.loadClass(className);
+      }
     } catch (ClassNotFoundException ex) {
       throw new JdbcConnectorException(
           "The pdx class \"" + className + "\" could not be loaded because: " + ex);
     }
   }
 
+  private URL createURL(File file) {
+    URL url;
+    try {
+      if (isJar(file.getName())) {
+        url = file.toURI().toURL();
+      } else {
+        url = this.topLevelDir.toURI().toURL();
+      }
+    } catch (MalformedURLException e) {
+      throw new JdbcConnectorException(
+          "The pdx class file \"" + file + "\" could not be converted to a URL, because: " + e);
+    }
+    return url;
+  }
+
+  private boolean isJar(String fileName) {
+    String fileExtension = FilenameUtils.getExtension(fileName);
+    return fileExtension.equalsIgnoreCase("jar");
+  }
+
   public interface ClassFactory {
     public Class loadClass(String className) throws ClassNotFoundException;
   }
@@ -238,4 +293,38 @@ public class CreateMappingPreconditionCheckFunction extends CliFunction<RegionMa
   public interface PdxWriterFactory {
     public PdxWriter create(TypeRegistry typeRegistry, Object object);
   }
+
+  private File copyRemoteInputStreamToTempFile(String className, String remoteInputStreamName,
+      RemoteInputStream remoteInputStream) {
+    try {
+      Path tempDir = FileUploader.createSecuredTempDirectory("pdx-class-dir-");
+      this.topLevelDir = tempDir.toFile();
+      if (!isJar(remoteInputStreamName)) {
+        File packageDir = new File(this.topLevelDir, className.replace(".", "/")).getParentFile();
+        packageDir.mkdirs();
+        tempDir = packageDir.toPath();
+      }
+
+      Path tempPdxClassFile = Paths.get(tempDir.toString(), remoteInputStreamName);
+      FileOutputStream fos = new FileOutputStream(tempPdxClassFile.toString());
+
+      InputStream input = RemoteInputStreamClient.wrap(remoteInputStream);
+
+      IOUtils.copyLarge(input, fos);
+
+      fos.close();
+      input.close();
+
+      return tempPdxClassFile.toFile();
+    } catch (IOException iox) {
+      try {
+        remoteInputStream.close(true);
+      } catch (IOException ex) {
+        // Ignored
+      }
+      throw new JdbcConnectorException(
+          "The pdx class file \"" + remoteInputStreamName
+              + "\" could not be copied to a temporary file, because: " + iox);
+    }
+  }
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java
index 3ce3fa2..79214b3 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
@@ -61,6 +62,7 @@ public class CreateMappingCommandTest {
   private String dataSourceName;
   private String tableName;
   private String pdxClass;
+  private String pdxClassFile;
   private String group1Name;
   private String group2Name;
   private Set<InternalDistributedMember> members;
@@ -82,6 +84,7 @@ public class CreateMappingCommandTest {
     dataSourceName = "connection";
     tableName = "testTable";
     pdxClass = "myPdxClass";
+    pdxClassFile = "myPdxClassFile";
     group1Name = "group1";
     group2Name = "group2";
     cache = mock(InternalCache.class);
@@ -143,7 +146,7 @@ public class CreateMappingCommandTest {
   }
 
   @Test
-  public void createsMappingReturnsStatusOKWhenFunctionResultSuccess() {
+  public void createsMappingReturnsStatusOKWhenFunctionResultSuccess() throws IOException {
     setupRequiredPreconditions();
     results.add(successFunctionResult);
     String ids = "ids";
@@ -151,7 +154,7 @@ public class CreateMappingCommandTest {
     String schema = "schema";
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, dataSourceName,
-        tableName, pdxClass, false, ids, catalog, schema, null);
+        tableName, pdxClass, pdxClassFile, false, ids, catalog, schema, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.OK);
     Object[] results = (Object[]) result.getConfigObject();
@@ -169,7 +172,8 @@ public class CreateMappingCommandTest {
   }
 
   @Test
-  public void createsMappingReturnsStatusOKWhenFunctionResultSuccessWithGroups() {
+  public void createsMappingReturnsStatusOKWhenFunctionResultSuccessWithGroups()
+      throws IOException {
     setupRequiredPreconditionsForGroup();
     results.add(successFunctionResult);
     String ids = "ids";
@@ -178,7 +182,7 @@ public class CreateMappingCommandTest {
     String[] groups = {group1Name, group2Name};
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, dataSourceName,
-        tableName, pdxClass, false, ids, catalog, schema, groups);
+        tableName, pdxClass, pdxClassFile, false, ids, catalog, schema, groups);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.OK);
     Object[] results = (Object[]) result.getConfigObject();
@@ -197,7 +201,7 @@ public class CreateMappingCommandTest {
   }
 
   @Test
-  public void createsMappingReturnsCorrectFieldMappings() {
+  public void createsMappingReturnsCorrectFieldMappings() throws IOException {
     setupRequiredPreconditions();
     results.add(successFunctionResult);
     String ids = "ids";
@@ -207,7 +211,7 @@ public class CreateMappingCommandTest {
     this.fieldMappings.add(new FieldMapping("pdx2", "pdx2type", "jdbc2", "jdbc2type", false));
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, dataSourceName,
-        tableName, pdxClass, false, ids, catalog, schema, null);
+        tableName, pdxClass, pdxClassFile, false, ids, catalog, schema, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.OK);
     Object[] results = (Object[]) result.getConfigObject();
@@ -216,7 +220,7 @@ public class CreateMappingCommandTest {
   }
 
   @Test
-  public void createsMappingReturnsRegionMappingWithComputedIds() {
+  public void createsMappingReturnsRegionMappingWithComputedIds() throws IOException {
     setupRequiredPreconditions();
     results.add(successFunctionResult);
     String ids = "does not matter";
@@ -226,7 +230,7 @@ public class CreateMappingCommandTest {
     preconditionOutput[0] = computedIds;
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, dataSourceName,
-        tableName, pdxClass, false, ids, catalog, schema, null);
+        tableName, pdxClass, pdxClassFile, false, ids, catalog, schema, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.OK);
     Object[] results = (Object[]) result.getConfigObject();
@@ -235,7 +239,7 @@ public class CreateMappingCommandTest {
   }
 
   @Test
-  public void createsMappingReturnsErrorIfPreconditionCheckErrors() {
+  public void createsMappingReturnsErrorIfPreconditionCheckErrors() throws IOException {
     setupRequiredPreconditions();
     results.add(successFunctionResult);
     String ids = "ids";
@@ -245,19 +249,19 @@ public class CreateMappingCommandTest {
     when(preconditionCheckResults.getStatusMessage()).thenReturn("precondition check failed");
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, dataSourceName,
-        tableName, pdxClass, false, ids, catalog, schema, null);
+        tableName, pdxClass, pdxClassFile, false, ids, catalog, schema, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
     assertThat(result.toString()).contains("precondition check failed");
   }
 
   @Test
-  public void createsMappingWithRegionPathCreatesMappingWithSlashRemoved() {
+  public void createsMappingWithRegionPathCreatesMappingWithSlashRemoved() throws IOException {
     setupRequiredPreconditions();
     results.add(successFunctionResult);
 
     ResultModel result = createRegionMappingCommand.createMapping("/" + regionName, dataSourceName,
-        tableName, pdxClass, false, null, null, null, null);
+        tableName, pdxClass, pdxClassFile, false, null, null, null, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.OK);
     Object[] results = (Object[]) result.getConfigObject();
@@ -267,30 +271,31 @@ public class CreateMappingCommandTest {
   }
 
   @Test
-  public void createsMappingReturnsStatusERRORWhenFunctionResultIsEmpty() {
+  public void createsMappingReturnsStatusERRORWhenFunctionResultIsEmpty() throws IOException {
     setupRequiredPreconditions();
     results.clear();
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, dataSourceName,
-        tableName, pdxClass, false, null, null, null, null);
+        tableName, pdxClass, pdxClassFile, false, null, null, null, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
   }
 
   @Test
-  public void createsMappingReturnsStatusERRORWhenClusterConfigIsDisabled() {
+  public void createsMappingReturnsStatusERRORWhenClusterConfigIsDisabled() throws IOException {
     results.add(successFunctionResult);
     doReturn(null).when(createRegionMappingCommand).getConfigurationPersistenceService();
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, dataSourceName,
-        tableName, pdxClass, false, null, null, null, null);
+        tableName, pdxClass, pdxClassFile, false, null, null, null, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
     assertThat(result.toString()).contains("Cluster Configuration must be enabled.");
   }
 
   @Test
-  public void createsMappingReturnsStatusERRORWhenClusterConfigDoesNotContainRegion() {
+  public void createsMappingReturnsStatusERRORWhenClusterConfigDoesNotContainRegion()
+      throws IOException {
     results.add(successFunctionResult);
     ConfigurationPersistenceService configurationPersistenceService =
         mock(ConfigurationPersistenceService.class);
@@ -301,7 +306,7 @@ public class CreateMappingCommandTest {
     when(cacheConfig.getRegions()).thenReturn(Collections.emptyList());
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, dataSourceName,
-        tableName, pdxClass, false, null, null, null, null);
+        tableName, pdxClass, pdxClassFile, false, null, null, null, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
     assertThat(result.toString())
@@ -309,7 +314,7 @@ public class CreateMappingCommandTest {
   }
 
   @Test
-  public void createsMappingReturnsStatusERRORWhenRegionMappingExists() {
+  public void createsMappingReturnsStatusERRORWhenRegionMappingExists() throws IOException {
     results.add(successFunctionResult);
     ConfigurationPersistenceService configurationPersistenceService =
         mock(ConfigurationPersistenceService.class);
@@ -331,14 +336,15 @@ public class CreateMappingCommandTest {
     when(matchingRegion.getCustomRegionElements()).thenReturn(customList);
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, dataSourceName,
-        tableName, pdxClass, false, null, null, null, null);
+        tableName, pdxClass, pdxClassFile, false, null, null, null, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
     assertThat(result.toString()).contains("A JDBC mapping for " + regionName + " already exists.");
   }
 
   @Test
-  public void createsMappingReturnsStatusERRORWhenClusterConfigRegionHasLoader() {
+  public void createsMappingReturnsStatusERRORWhenClusterConfigRegionHasLoader()
+      throws IOException {
     results.add(successFunctionResult);
     ConfigurationPersistenceService configurationPersistenceService =
         mock(ConfigurationPersistenceService.class);
@@ -356,7 +362,7 @@ public class CreateMappingCommandTest {
     when(matchingRegion.getRegionAttributes()).thenReturn(loaderAttribute);
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, dataSourceName,
-        tableName, pdxClass, false, null, null, null, null);
+        tableName, pdxClass, pdxClassFile, false, null, null, null, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
     assertThat(result.toString()).contains("The existing region " + regionName
@@ -364,7 +370,8 @@ public class CreateMappingCommandTest {
   }
 
   @Test
-  public void createMappingWithSynchronousReturnsStatusERRORWhenClusterConfigRegionHasWriter() {
+  public void createMappingWithSynchronousReturnsStatusERRORWhenClusterConfigRegionHasWriter()
+      throws IOException {
     results.add(successFunctionResult);
     ConfigurationPersistenceService configurationPersistenceService =
         mock(ConfigurationPersistenceService.class);
@@ -382,7 +389,7 @@ public class CreateMappingCommandTest {
     when(matchingRegion.getRegionAttributes()).thenReturn(writerAttribute);
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, dataSourceName,
-        tableName, pdxClass, true, null, null, null, null);
+        tableName, pdxClass, pdxClassFile, true, null, null, null, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
     assertThat(result.toString()).contains("The existing region " + regionName
@@ -390,7 +397,8 @@ public class CreateMappingCommandTest {
   }
 
   @Test
-  public void createMappingWithSynchronousReturnsStatusOKWhenAsycnEventQueueAlreadyExists() {
+  public void createMappingWithSynchronousReturnsStatusOKWhenAsycnEventQueueAlreadyExists()
+      throws IOException {
     results.add(successFunctionResult);
     ConfigurationPersistenceService configurationPersistenceService =
         mock(ConfigurationPersistenceService.class);
@@ -412,14 +420,15 @@ public class CreateMappingCommandTest {
     when(cacheConfig.getAsyncEventQueues()).thenReturn(asyncEventQueues);
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, dataSourceName,
-        tableName, pdxClass, true, null, null, null, null);
+        tableName, pdxClass, pdxClassFile, true, null, null, null, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.OK);
   }
 
 
   @Test
-  public void createsMappingReturnsStatusERRORWhenAsycnEventQueueAlreadyExists() {
+  public void createsMappingReturnsStatusERRORWhenAsycnEventQueueAlreadyExists()
+      throws IOException {
     results.add(successFunctionResult);
     ConfigurationPersistenceService configurationPersistenceService =
         mock(ConfigurationPersistenceService.class);
@@ -441,7 +450,7 @@ public class CreateMappingCommandTest {
     when(cacheConfig.getAsyncEventQueues()).thenReturn(asyncEventQueues);
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, dataSourceName,
-        tableName, pdxClass, false, null, null, null, null);
+        tableName, pdxClass, pdxClassFile, false, null, null, null, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
     assertThat(result.toString())
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingPreconditionCheckFunctionTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingPreconditionCheckFunctionTest.java
index c3fd216..ebf6095 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingPreconditionCheckFunctionTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingPreconditionCheckFunctionTest.java
@@ -36,6 +36,7 @@ import java.util.Set;
 
 import javax.sql.DataSource;
 
+import com.healthmarketscience.rmiio.RemoteInputStream;
 import org.apache.commons.lang3.SerializationUtils;
 import org.junit.Before;
 import org.junit.Test;
@@ -69,7 +70,7 @@ public class CreateMappingPreconditionCheckFunctionTest {
   private static final String MEMBER_NAME = "testMemberName";
 
   private RegionMapping regionMapping;
-  private FunctionContext<RegionMapping> context;
+  private FunctionContext<Object[]> context;
   private ResultSender<Object> resultSender;
   private InternalCache cache;
   private TypeRegistry typeRegistry;
@@ -79,6 +80,8 @@ public class CreateMappingPreconditionCheckFunctionTest {
   private TableMetaDataView tableMetaDataView;
   private DataSource dataSource;
   private PdxType pdxType = mock(PdxType.class);
+  private String remoteInputStreamName;
+  private RemoteInputStream remoteInputStream;
 
   private CreateMappingPreconditionCheckFunction function;
 
@@ -98,6 +101,9 @@ public class CreateMappingPreconditionCheckFunctionTest {
     typeRegistry = mock(TypeRegistry.class);
     when(cache.getPdxRegistry()).thenReturn(typeRegistry);
     regionMapping = mock(RegionMapping.class);
+    remoteInputStreamName = "remoteInputStreamName";
+    remoteInputStream = mock(RemoteInputStream.class);
+    Object[] args = new Object[] {regionMapping, remoteInputStreamName, remoteInputStream};
 
     when(regionMapping.getRegionName()).thenReturn(REGION_NAME);
     when(regionMapping.getPdxName()).thenReturn(PDX_CLASS_NAME);
@@ -105,7 +111,7 @@ public class CreateMappingPreconditionCheckFunctionTest {
 
     when(context.getResultSender()).thenReturn(resultSender);
     when(context.getCache()).thenReturn(cache);
-    when(context.getArguments()).thenReturn(regionMapping);
+    when(context.getArguments()).thenReturn(args);
     when(context.getMemberName()).thenReturn(MEMBER_NAME);
 
     dataSourceFactory = mock(DataSourceFactory.class);