CreateMappingPreconditionCheckFunction extends CliFunction<Object[]> { @Override 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 = getDataSource(dataSourceName); if (dataSource == null) { throw new JdbcConnectorException("JDBC data-source named \"" + dataSourceName + "\" not found. Create it with gfsh 'create data-source --pooled --name=" + dataSourceName + "'."); } InternalCache cache = (InternalCache) context.getCache(); TypeRegistry typeRegistry = cache.getPdxRegistry(); PdxType pdxType = getPdxTypeForClass(cache, typeRegistry, regionMapping.getPdxName(), remoteInputStreamName, remoteInputStream); try (Connection connection = dataSource.getConnection()) { TableMetaDataView tableMetaData = getTableMetaDataManager().getTableMetaDataView(connection, regionMapping); Object[] output = new Object[2]; ArrayList<FieldMapping> fieldMappings = new ArrayList<>(); output[1] = fieldMappings; Set<String> columnNames = tableMetaData.getColumnNames(); if (columnNames.size() != pdxType.getFieldCount()) { throw new JdbcConnectorException( "The table and pdx class must have the same number of columns/fields. But the table has " + columnNames.size() + " columns and the pdx class has " + pdxType.getFieldCount() + " fields."); } List<PdxField> pdxFields = pdxType.getFields(); for (String jdbcName : columnNames) { boolean isNullable = tableMetaData.isColumnNullable(jdbcName); JDBCType jdbcType = tableMetaData.getColumnDataType(jdbcName); FieldMapping fieldMapping = createFieldMapping(jdbcName, jdbcType.getName(), isNullable, pdxFields); fieldMappings.add(fieldMapping); } if (regionMapping.getIds() == null || regionMapping.getIds().isEmpty()) { List<String> keyColumnNames = tableMetaData.getKeyColumnNames(); output[0] = String.join(",", keyColumnNames); } String member = context.getMemberName(); return new CliFunctionResult(member, output); } catch (SQLException e) { throw JdbcConnectorException.createException(e); } }  @Override CliFunctionResult executeFunction(FunctionContext<Object[]> context);  }
@Test public void executeFunctionThrowsIfDataSourceGetConnectionThrows() throws SQLException { String reason = "connection failed"; when(dataSource.getConnection()).thenThrow(new SQLException(reason)); Throwable throwable = catchThrowable(() -> function.executeFunction(context)); assertThat(throwable).isInstanceOf(JdbcConnectorException.class).hasMessageContaining(reason); }
@Test public void executeFunctionReturnsNoFieldMappingsIfNoColumns() { Set<String> columnNames = Collections.emptySet(); when(tableMetaDataView.getColumnNames()).thenReturn(columnNames); CliFunctionResult result = function.executeFunction(context); assertThat(result.isSuccessful()).isTrue(); ArrayList<FieldMapping> fieldsMappings = getFieldMappings(result); assertThat(fieldsMappings).isEmpty(); }
@Test public void executeFunctionReturnsFieldMappingsThatMatchTableMetaData() { Set<String> columnNames = new LinkedHashSet<>(Arrays.asList("col1", "col2")); when(tableMetaDataView.getColumnNames()).thenReturn(columnNames); when(tableMetaDataView.isColumnNullable("col1")).thenReturn(false); when(tableMetaDataView.getColumnDataType("col1")).thenReturn(JDBCType.DATE); when(tableMetaDataView.isColumnNullable("col2")).thenReturn(true); when(tableMetaDataView.getColumnDataType("col2")).thenReturn(JDBCType.DATE); when(pdxType.getFieldCount()).thenReturn(2); PdxField field1 = mock(PdxField.class); when(field1.getFieldName()).thenReturn("col1"); when(field1.getFieldType()).thenReturn(FieldType.DATE); PdxField field2 = mock(PdxField.class); when(field2.getFieldName()).thenReturn("col2"); when(field2.getFieldType()).thenReturn(FieldType.DATE); List<PdxField> pdxFields = Arrays.asList(field1, field2); when(pdxType.getFields()).thenReturn(pdxFields); CliFunctionResult result = function.executeFunction(context); assertThat(result.isSuccessful()).isTrue(); ArrayList<FieldMapping> fieldsMappings = getFieldMappings(result); assertThat(fieldsMappings).hasSize(2); assertThat(fieldsMappings.get(0)) .isEqualTo( new FieldMapping("col1", FieldType.DATE.name(), "col1", JDBCType.DATE.name(), false)); assertThat(fieldsMappings.get(1)) .isEqualTo( new FieldMapping("col2", FieldType.DATE.name(), "col2", JDBCType.DATE.name(), true)); }
@Test public void executeFunctionReturnsFieldMappingsThatMatchTableMetaDataAndExistingPdxField() { Set<String> columnNames = new LinkedHashSet<>(singletonList("col1")); when(tableMetaDataView.getColumnNames()).thenReturn(columnNames); when(tableMetaDataView.isColumnNullable("col1")).thenReturn(false); when(tableMetaDataView.getColumnDataType("col1")).thenReturn(JDBCType.DATE); PdxField pdxField1 = mock(PdxField.class); when(pdxField1.getFieldName()).thenReturn("COL1"); when(pdxField1.getFieldType()).thenReturn(FieldType.LONG); when(pdxType.getFieldCount()).thenReturn(1); when(pdxType.getFields()).thenReturn(singletonList(pdxField1)); CliFunctionResult result = function.executeFunction(context); assertThat(result.isSuccessful()).isTrue(); ArrayList<FieldMapping> fieldsMappings = getFieldMappings(result); assertThat(fieldsMappings).hasSize(1); assertThat(fieldsMappings.get(0)) .isEqualTo( new FieldMapping("COL1", FieldType.LONG.name(), "col1", JDBCType.DATE.name(), false)); }
@Test public void executeFunctionGivenPdxSerializableCallsRegisterPdxMetaData() { Set<String> columnNames = new LinkedHashSet<>(singletonList("col1")); when(tableMetaDataView.getColumnNames()).thenReturn(columnNames); when(tableMetaDataView.isColumnNullable("col1")).thenReturn(false); when(tableMetaDataView.getColumnDataType("col1")).thenReturn(JDBCType.DATE); PdxField pdxField1 = mock(PdxField.class); when(pdxField1.getFieldName()).thenReturn("COL1"); when(pdxField1.getFieldType()).thenReturn(FieldType.LONG); when(pdxType.getFieldCount()).thenReturn(1); when(pdxType.getFields()).thenReturn(singletonList(pdxField1)); when(typeRegistry.getExistingTypeForClass(PdxClassDummy.class)).thenReturn(null) .thenReturn(pdxType); CliFunctionResult result = function.executeFunction(context); assertThat(result.isSuccessful()).isTrue(); verify(cache).registerPdxMetaData(any()); ArrayList<FieldMapping> fieldsMappings = getFieldMappings(result); assertThat(fieldsMappings).hasSize(1); assertThat(fieldsMappings.get(0)) .isEqualTo( new FieldMapping("COL1", FieldType.LONG.name(), "col1", JDBCType.DATE.name(), false)); }
@Test public void executeFunctionThrowsGivenExistingPdxTypeWithMultipleInexactMatches() { Set<String> columnNames = new LinkedHashSet<>(singletonList("col1")); when(tableMetaDataView.getColumnNames()).thenReturn(columnNames); when(tableMetaDataView.isColumnNullable("col1")).thenReturn(false); when(tableMetaDataView.getColumnDataType("col1")).thenReturn(JDBCType.DATE); when(pdxType.getFieldCount()).thenReturn(1); PdxField pdxField1 = mock(PdxField.class); when(pdxField1.getFieldName()).thenReturn("COL1"); when(pdxField1.getFieldType()).thenReturn(FieldType.DATE); PdxField pdxField2 = mock(PdxField.class); when(pdxField2.getFieldName()).thenReturn("Col1"); when(pdxField2.getFieldType()).thenReturn(FieldType.DATE); when(pdxType.getFields()).thenReturn(Arrays.asList(pdxField1, pdxField2)); Throwable throwable = catchThrowable(() -> function.executeFunction(context)); assertThat(throwable).isInstanceOf(JdbcConnectorException.class) .hasMessage("More than one PDX field name matched the column name \"col1\""); }
@Test public void executeFunctionThrowsGivenExistingPdxTypeWithNoMatches() { Set<String> columnNames = new LinkedHashSet<>(singletonList("col1")); when(tableMetaDataView.getColumnNames()).thenReturn(columnNames); when(tableMetaDataView.isColumnNullable("col1")).thenReturn(false); when(tableMetaDataView.getColumnDataType("col1")).thenReturn(JDBCType.DATE); when(pdxType.getFieldCount()).thenReturn(1); PdxField pdxField1 = mock(PdxField.class); when(pdxField1.getFieldName()).thenReturn("pdxCOL1"); when(pdxField1.getFieldType()).thenReturn(FieldType.DATE); PdxField pdxField2 = mock(PdxField.class); when(pdxField2.getFieldName()).thenReturn("pdxCol1"); when(pdxField2.getFieldType()).thenReturn(FieldType.DATE); when(pdxType.getFields()).thenReturn(Arrays.asList(pdxField1, pdxField2)); Throwable throwable = catchThrowable(() -> function.executeFunction(context)); assertThat(throwable).isInstanceOf(JdbcConnectorException.class) .hasMessage("No PDX field name matched the column name \"col1\""); }
@Test public void executeFunctionThrowsGivenExistingPdxTypeWithWrongNumberOfFields() { Set<String> columnNames = new LinkedHashSet<>(singletonList("col1")); when(tableMetaDataView.getColumnNames()).thenReturn(columnNames); when(tableMetaDataView.isColumnNullable("col1")).thenReturn(false); when(tableMetaDataView.getColumnDataType("col1")).thenReturn(JDBCType.DATE); when(pdxType.getFieldCount()).thenReturn(2); Throwable throwable = catchThrowable(() -> function.executeFunction(context)); assertThat(throwable).isInstanceOf(JdbcConnectorException.class) .hasMessage( "The table and pdx class must have the same number of columns/fields. But the table has 1 columns and the pdx class has 2 fields."); }
@Test public void executeFunctionReturnsResultWithCorrectMemberName() { when(regionMapping.getIds()).thenReturn("myId"); CliFunctionResult result = function.executeFunction(context); assertThat(result.isSuccessful()).isTrue(); assertThat(result.getMemberIdOrName()).isEqualTo(MEMBER_NAME); }
@Test public void executeFunctionReturnsNullInSlotZeroIfRegionMappingHasIds() { when(regionMapping.getIds()).thenReturn("myId"); CliFunctionResult result = function.executeFunction(context); assertThat(result.isSuccessful()).isTrue(); Object[] outputs = (Object[]) result.getResultObject(); assertThat(outputs[0]).isNull(); }
@Test public void executeFunctionReturnsViewsKeyColumnsInSlotZeroIfRegionMappingHasNullIds() { when(regionMapping.getIds()).thenReturn(null); when(tableMetaDataView.getKeyColumnNames()).thenReturn(Arrays.asList("keyCol1", "keyCol2")); CliFunctionResult result = function.executeFunction(context); assertThat(result.isSuccessful()).isTrue(); Object[] outputs = (Object[]) result.getResultObject(); assertThat(outputs[0]).isEqualTo("keyCol1,keyCol2"); }
@Test public void executeFunctionReturnsViewsKeyColumnsInSlotZeroIfRegionMappingHasEmptyIds() { when(regionMapping.getIds()).thenReturn(""); when(tableMetaDataView.getKeyColumnNames()).thenReturn(singletonList("keyCol1")); CliFunctionResult result = function.executeFunction(context); assertThat(result.isSuccessful()).isTrue(); Object[] outputs = (Object[]) result.getResultObject(); assertThat(outputs[0]).isEqualTo("keyCol1"); }