@Test public void testExecuteJdbcErrorValidation() throws Exception { JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.setConnection(null); List<FieldExtension> fieldExtensionList = new ArrayList<>(); List<Parameter> parameters = new ArrayList<>(); populateParameters(jdbcExecutionRequest, fieldExtensionList, parameters); Map<String, Object> variableValuesToValidate = new HashMap<>(); variableValuesToValidate.put(BaseJavaDelegate.VARIABLE_JSON_RESPONSE, VARIABLE_VALUE_IS_NULL); variableValuesToValidate.put(ActivitiRuntimeHelper.VARIABLE_ERROR_MESSAGE, "JDBC connection is required"); executeWithoutLogging(ActivitiRuntimeHelper.class, () -> { testActivitiServiceTaskFailure(JAVA_DELEGATE_CLASS_NAME, fieldExtensionList, parameters, variableValuesToValidate); }); }
/** * Parameter validation, request statement list is empty */ @Test public void testExecuteJdbcParamValidationStatementsEmpty() { JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.getStatements().clear(); try { // Execute jdbcService.executeJdbc(jdbcExecutionRequest); Assert.fail("expected an IllegalArgumentException, but no exception was thrown"); } catch (Exception e) { Assert.assertEquals("thrown exception type", IllegalArgumentException.class, e.getClass()); Assert.assertEquals("thrown exception message", "JDBC statements are required", e.getMessage()); } }
@Test public void testExecuteJdbcSuccess() throws Exception { JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); List<FieldExtension> fieldExtensionList = new ArrayList<>(); List<Parameter> parameters = new ArrayList<>(); populateParameters(jdbcExecutionRequest, fieldExtensionList, parameters); JdbcExecutionResponse expectedJdbcExecutionResponse = new JdbcExecutionResponse(); expectedJdbcExecutionResponse.setStatements(jdbcExecutionRequest.getStatements()); expectedJdbcExecutionResponse.getStatements().get(0).setStatus(JdbcStatementStatus.SUCCESS); expectedJdbcExecutionResponse.getStatements().get(0).setResult("1"); String expectedJdbcExecutionResponseJson = jsonHelper.objectToJson(expectedJdbcExecutionResponse); Map<String, Object> variableValuesToValidate = new HashMap<>(); variableValuesToValidate.put(BaseJavaDelegate.VARIABLE_JSON_RESPONSE, expectedJdbcExecutionResponseJson); testActivitiServiceTaskSuccess(JAVA_DELEGATE_CLASS_NAME, fieldExtensionList, parameters, variableValuesToValidate); }
@Test public void testExecuteJdbcErrorConnection() { JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.getStatements().get(0).setSql(MockJdbcOperations.CASE_3_SQL); try { // Execute jdbcService.executeJdbc(jdbcExecutionRequest); Assert.fail("expected an IllegalArgumentException, but no exception was thrown"); } catch (Exception e) { Assert.assertEquals("thrown exception type", IllegalArgumentException.class, e.getClass()); Assert.assertEquals("thrown exception message", "java.sql.SQLException: test CannotGetJdbcConnectionException cause", e.getMessage()); } }
/** * Parameter validation, request statement sql is empty */ @Test public void testExecuteJdbcParamValidationStatementTypeSqlEmpty() { JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.getStatements().get(0).setSql(" \t\n\r"); try { // Execute jdbcService.executeJdbc(jdbcExecutionRequest); Assert.fail("expected an IllegalArgumentException, but no exception was thrown"); } catch (Exception e) { Assert.assertEquals("thrown exception type", IllegalArgumentException.class, e.getClass()); Assert.assertEquals("thrown exception message", "JDBC statement [0] SQL is required", e.getMessage()); } }
/** * Parameter validation, request statement list is null */ @Test public void testExecuteJdbcParamValidationStatementsNull() { JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.setStatements(null); try { // Execute jdbcService.executeJdbc(jdbcExecutionRequest); Assert.fail("expected an IllegalArgumentException, but no exception was thrown"); } catch (Exception e) { Assert.assertEquals("thrown exception type", IllegalArgumentException.class, e.getClass()); Assert.assertEquals("thrown exception message", "JDBC statements are required", e.getMessage()); } }
/** * Parameter validation, request statement type is null */ @Test public void testExecuteJdbcParamValidationStatementTypeNull() { JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.getStatements().get(0).setType(null); try { // Execute jdbcService.executeJdbc(jdbcExecutionRequest); Assert.fail("expected an IllegalArgumentException, but no exception was thrown"); } catch (Exception e) { Assert.assertEquals("thrown exception type", IllegalArgumentException.class, e.getClass()); Assert.assertEquals("thrown exception message", "JDBC statement [0] type is required", e.getMessage()); } }
/** * Parameter validation, request connection is null */ @Test public void testExecuteJdbcParamValidationConnectionNull() { JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.setConnection(null); try { // Execute jdbcService.executeJdbc(jdbcExecutionRequest); Assert.fail("expected an IllegalArgumentException, but no exception was thrown"); } catch (Exception e) { Assert.assertEquals("thrown exception type", IllegalArgumentException.class, e.getClass()); Assert.assertEquals("thrown exception message", "JDBC connection is required", e.getMessage()); } }
@Test public void testExecuteJdbcErrorStatement() throws Exception { JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.getStatements().get(0).setSql(MockJdbcOperations.CASE_2_SQL); List<FieldExtension> fieldExtensionList = new ArrayList<>(); List<Parameter> parameters = new ArrayList<>(); populateParameters(jdbcExecutionRequest, fieldExtensionList, parameters); JdbcExecutionResponse expectedJdbcExecutionResponse = new JdbcExecutionResponse(); expectedJdbcExecutionResponse.setStatements(jdbcExecutionRequest.getStatements()); expectedJdbcExecutionResponse.getStatements().get(0).setStatus(JdbcStatementStatus.ERROR); expectedJdbcExecutionResponse.getStatements().get(0).setErrorMessage("java.sql.SQLException: test DataIntegrityViolationException cause"); String expectedJdbcExecutionResponseString = jsonHelper.objectToJson(expectedJdbcExecutionResponse); Map<String, Object> variableValuesToValidate = new HashMap<>(); variableValuesToValidate.put(BaseJavaDelegate.VARIABLE_JSON_RESPONSE, expectedJdbcExecutionResponseString); variableValuesToValidate.put(ActivitiRuntimeHelper.VARIABLE_ERROR_MESSAGE, "There are failed executions. See JSON response for details."); executeWithoutLogging(ActivitiRuntimeHelper.class, () -> { testActivitiServiceTaskFailure(JAVA_DELEGATE_CLASS_NAME, fieldExtensionList, parameters, variableValuesToValidate); }); }
/** * When S3 properties location is specified, bucket name must not be a blank string. */ @Test public void testExecuteJdbcParamValidationS3PropertiesLocationBucketNameBlank() { JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.setS3PropertiesLocation(new S3PropertiesLocation(BLANK_TEXT, "test_key")); try { jdbcService.executeJdbc(jdbcExecutionRequest); Assert.fail("expected an IllegalArgumentException, but no exception was thrown"); } catch (Exception e) { Assert.assertEquals("thrown exception type", IllegalArgumentException.class, e.getClass()); Assert.assertEquals("thrown exception message", "S3 properties location bucket name is required", e.getMessage()); } }
/** * When S3 properties location is specified, object key must not be a blank string. */ @Test public void testExecuteJdbcParamValidationS3PropertiesLocationKeyBlank() { JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.setS3PropertiesLocation(new S3PropertiesLocation("test_bucket", BLANK_TEXT)); try { jdbcService.executeJdbc(jdbcExecutionRequest); Assert.fail("expected an IllegalArgumentException, but no exception was thrown"); } catch (Exception e) { Assert.assertEquals("thrown exception type", IllegalArgumentException.class, e.getClass()); Assert.assertEquals("thrown exception message", "S3 properties location key is required", e.getMessage()); } }
/** * Parameter validation, request connection URL is empty */ @Test public void testExecuteJdbcParamValidationConnectionUrlEmpty() { JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.getConnection().setUrl(" \t\n\r"); try { // Execute jdbcService.executeJdbc(jdbcExecutionRequest); Assert.fail("expected an IllegalArgumentException, but no exception was thrown"); } catch (Exception e) { Assert.assertEquals("thrown exception type", IllegalArgumentException.class, e.getClass()); Assert.assertEquals("thrown exception message", "JDBC connection URL is required", e.getMessage()); } }
/** * Parameter validation, request connection password is null. Password can be empty however, since some databases allow that. */ @Test public void testExecuteJdbcParamValidationConnectionPasswordNull() { JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.getConnection().setPassword(null); try { // Execute jdbcService.executeJdbc(jdbcExecutionRequest); Assert.fail("expected an IllegalArgumentException, but no exception was thrown"); } catch (Exception e) { Assert.assertEquals("thrown exception type", IllegalArgumentException.class, e.getClass()); Assert.assertEquals("thrown exception message", "JDBC connection password is required", e.getMessage()); } }
/** * Parameter validation, request connection username is null. Username can be empty however, since some databases allow that. */ @Test public void testExecuteJdbcParamValidationConnectionUsernameNull() { JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.getConnection().setUsername(null); try { // Execute jdbcService.executeJdbc(jdbcExecutionRequest); Assert.fail("expected an IllegalArgumentException, but no exception was thrown"); } catch (Exception e) { Assert.assertEquals("thrown exception type", IllegalArgumentException.class, e.getClass()); Assert.assertEquals("thrown exception message", "JDBC connection user name is required", e.getMessage()); } }
/** * Parameter validation, request connection database type is null. */ @Test public void testExecuteJdbcParamValidationConnectionDatabaseTypeNull() { JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.getConnection().setDatabaseType(null); try { // Execute jdbcService.executeJdbc(jdbcExecutionRequest); Assert.fail("expected an IllegalArgumentException, but no exception was thrown"); } catch (Exception e) { Assert.assertEquals("thrown exception type", IllegalArgumentException.class, e.getClass()); Assert.assertEquals("thrown exception message", "JDBC connection database type is required", e.getMessage()); } }
/** * If the result of replacing SQL using S3 properties is blank, throws a validation error. */ @Test public void testExecuteJdbcWithS3PropertiesParamSqlBlankAfterReplace() { String s3BucketName = "test_bucket"; String s3ObjectKey = "test_key"; String content = "foo="; putS3Object(s3BucketName, s3ObjectKey, content); JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.getStatements().get(0).setSql("${foo}"); jdbcExecutionRequest.setS3PropertiesLocation(new S3PropertiesLocation(s3BucketName, s3ObjectKey)); try { jdbcService.executeJdbc(jdbcExecutionRequest); Assert.fail("expected an IllegalArgumentException, but no exception was thrown"); } catch (Exception e) { Assert.assertEquals("thrown exception type", IllegalArgumentException.class, e.getClass()); Assert.assertEquals("thrown exception message", "JDBC statement [0] SQL is required", e.getMessage()); } }
/** * If the result of replacing URL using S3 properties is blank, throws a validation error. */ @Test public void testExecuteJdbcWithS3PropertiesParamUrlBlankAfterReplace() { String s3BucketName = "test_bucket"; String s3ObjectKey = "test_key"; String content = "foo="; putS3Object(s3BucketName, s3ObjectKey, content); JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.getConnection().setUrl("${foo}"); jdbcExecutionRequest.setS3PropertiesLocation(new S3PropertiesLocation(s3BucketName, s3ObjectKey)); try { jdbcService.executeJdbc(jdbcExecutionRequest); Assert.fail("expected an IllegalArgumentException, but no exception was thrown"); } catch (Exception e) { Assert.assertEquals("thrown exception type", IllegalArgumentException.class, e.getClass()); Assert.assertEquals("thrown exception message", "JDBC connection URL is required", e.getMessage()); } }
/** * Some JDBC exception messages echoes back parts of the SQL statement. This is problem for security if some of the variables were replaced, and may * accidentally expose secret information in the response error message. The application should mask any values given in the properties which exist in the * exception message. * <p/> * This test will use a SQL that will throw an exception, and the exception message is known. Then asserts that the value has been replaced with a mask in * the response error message. */ @Test public void testExecuteJdbcSensitiveDataIsMaskedInErrorMessage() { String s3BucketName = "test_bucket"; String s3ObjectKey = "test_key"; String content = "foo=DataIntegrityViolationException"; putS3Object(s3BucketName, s3ObjectKey, content); JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.getStatements().get(0).setSql(MockJdbcOperations.CASE_2_SQL); jdbcExecutionRequest.setS3PropertiesLocation(new S3PropertiesLocation(s3BucketName, s3ObjectKey)); JdbcExecutionResponse jdbcExecutionResponse = jdbcService.executeJdbc(jdbcExecutionRequest); Assert.assertEquals("jdbc execution response statement [0] error message", "java.sql.SQLException: test **** cause", jdbcExecutionResponse.getStatements().get(0).getErrorMessage()); }
/** * Use case where a single successful statement is executed. */ @Test public void testExecuteJdbcStatementSuccess() { // Get test request JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); // Execute JdbcExecutionResponse jdbcExecutionResponse = jdbcService.executeJdbc(jdbcExecutionRequest); // Assert results Assert.assertNull("JDBC connection is not null", jdbcExecutionResponse.getConnection()); Assert.assertEquals("JDBC statements size", jdbcExecutionRequest.getStatements().size(), jdbcExecutionResponse.getStatements().size()); { JdbcStatement expectedJdbcStatement = jdbcExecutionRequest.getStatements().get(0); JdbcStatement actualJdbcStatement = jdbcExecutionResponse.getStatements().get(0); Assert.assertEquals("JDBC statement [0] type", expectedJdbcStatement.getType(), actualJdbcStatement.getType()); Assert.assertEquals("JDBC statement [0] sql", expectedJdbcStatement.getSql(), actualJdbcStatement.getSql()); Assert.assertEquals("JDBC statement [0] status", JdbcStatementStatus.SUCCESS, actualJdbcStatement.getStatus()); Assert.assertEquals("JDBC statement [0] result", "1", actualJdbcStatement.getResult()); } }
/** * Execute JDBC using S3 properties file. Unfortunately, not many assertions that can be done through the service layer. Asserts that no errors are thrown, * and that the response SQL does not expose the secrets. */ @Test public void testExecuteJdbcWithS3PropertiesSuccess() { String s3BucketName = "test_bucket"; String s3ObjectKey = "test_key"; String content = "foo=bar"; putS3Object(s3BucketName, s3ObjectKey, content); JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultUpdateJdbcExecutionRequest(); jdbcExecutionRequest.getConnection().setUrl("test_url_${foo}"); jdbcExecutionRequest.getConnection().setUsername("test_username_${foo}"); jdbcExecutionRequest.getConnection().setPassword("test_password_${foo}"); JdbcStatement jdbcStatement = jdbcExecutionRequest.getStatements().get(0); jdbcStatement.setSql("test_sql_${foo}"); jdbcExecutionRequest.setS3PropertiesLocation(new S3PropertiesLocation(s3BucketName, s3ObjectKey)); try { JdbcExecutionResponse jdbcExecutionResponse = jdbcService.executeJdbc(jdbcExecutionRequest); Assert.assertEquals("jdbc execution response statement [0] sql", "test_sql_${foo}", jdbcExecutionResponse.getStatements().get(0).getSql()); } catch (Exception e) { Assert.fail("unexpected exception was thrown. " + e); } }