/** * Creates and returns a {@link JdbcStatement} at a state which has not yet been executed based on the given request. * <p/> * The status will be set to {@link JdbcStatementStatus#SKIPPED} and result null. * * @param requestJdbcStatement the requested JDBC statement * * @return a new {@link JdbcStatement} */ private JdbcStatement createDefaultResponseJdbcStatement(JdbcStatement requestJdbcStatement) { JdbcStatement responseJdbcStatement = new JdbcStatement(); responseJdbcStatement.setType(requestJdbcStatement.getType()); responseJdbcStatement.setSql(requestJdbcStatement.getSql()); responseJdbcStatement.setContinueOnError(requestJdbcStatement.isContinueOnError()); responseJdbcStatement.setStatus(JdbcStatementStatus.SKIPPED); return responseJdbcStatement; }
/** * Validates parameters specified in the given statement. * * @param jdbcStatement statement to validate * @param jdbcStatementIndex the index number of the statement in the list */ private void validateJdbcStatement(JdbcStatement jdbcStatement, int jdbcStatementIndex) { Assert.notNull(jdbcStatement, "JDBC statement [" + jdbcStatementIndex + "] is required"); Assert.notNull(jdbcStatement.getType(), "JDBC statement [" + jdbcStatementIndex + "] type is required"); validateSqlStatement(jdbcStatement.getSql(), jdbcStatementIndex); }
/** * Returns a valid list of JDBC QUERY statements.It contains only 1 statement, and the statement is CASE_1_SQL in mock JDBC (success, result 1) * * @return list of statements */ private List<JdbcStatement> createDefaultQueryJdbcStatements() { List<JdbcStatement> jdbcStatements = new ArrayList<>(); { JdbcStatement jdbcStatement = new JdbcStatement(); jdbcStatement.setType(JdbcStatementType.QUERY); jdbcStatement.setSql(MockJdbcOperations.CASE_1_SQL); jdbcStatements.add(jdbcStatement); } return jdbcStatements; }
public Object copyTo(ObjectLocator locator, Object target, CopyStrategy2 strategy) { final Object draftCopy = ((target == null)?createNewInstance():target); if (draftCopy instanceof JdbcStatement) { final JdbcStatement copy = ((JdbcStatement) draftCopy); if (typeShouldBeCopiedAndSet == Boolean.TRUE) { JdbcStatementType sourceType; sourceType = this.getType(); JdbcStatementType copyType = ((JdbcStatementType) strategy.copy(LocatorUtils.property(locator, "type", sourceType), sourceType, (this.type!= null))); copy.setType(copyType); } else { if (typeShouldBeCopiedAndSet == Boolean.FALSE) { if (sqlShouldBeCopiedAndSet == Boolean.TRUE) { String sourceSql; sourceSql = this.getSql(); String copySql = ((String) strategy.copy(LocatorUtils.property(locator, "sql", sourceSql), sourceSql, (this.sql!= null))); copy.setSql(copySql); } else { if (sqlShouldBeCopiedAndSet == Boolean.FALSE) { if (continueOnErrorShouldBeCopiedAndSet == Boolean.TRUE) { Boolean sourceContinueOnError; sourceContinueOnError = this.isContinueOnError(); Boolean copyContinueOnError = ((Boolean) strategy.copy(LocatorUtils.property(locator, "continueOnError", sourceContinueOnError), sourceContinueOnError, (this.continueOnError!= null))); copy.setContinueOnError(copyContinueOnError); } else { if (continueOnErrorShouldBeCopiedAndSet == Boolean.FALSE) { if (statusShouldBeCopiedAndSet == Boolean.TRUE) {
public StringBuilder appendFields(ObjectLocator locator, StringBuilder buffer, ToStringStrategy2 strategy) { theType = this.getType(); strategy.appendField(locator, this, "type", buffer, theType, (this.type!= null)); theSql = this.getSql(); strategy.appendField(locator, this, "sql", buffer, theSql, (this.sql!= null)); theContinueOnError = this.isContinueOnError(); strategy.appendField(locator, this, "continueOnError", buffer, theContinueOnError, (this.continueOnError!= null)); theStatus = this.getStatus(); strategy.appendField(locator, this, "status", buffer, theStatus, (this.status!= null)); theResult = this.getResult(); strategy.appendField(locator, this, "result", buffer, theResult, (this.result!= null)); theResultSet = this.getResultSet(); strategy.appendField(locator, this, "resultSet", buffer, theResultSet, (this.resultSet!= null)); theErrorMessage = this.getErrorMessage(); strategy.appendField(locator, this, "errorMessage", buffer, theErrorMessage, (this.errorMessage!= null));
JdbcStatement expectedJdbcStatement = new JdbcStatement(); expectedJdbcStatement.setType(originalJdbcStatement.getType()); expectedJdbcStatement.setSql(originalJdbcStatement.getSql()); expectedJdbcStatement.setStatus(JdbcStatementStatus.SUCCESS); expectedJdbcStatement.setResult("1"); expectedJdbcExecutionResponse.setStatements(Arrays.asList(expectedJdbcStatement)); Parameter expectedJdbcExecutionResponseParameter = new Parameter("service_jsonResponse", jsonHelper.objectToJson(expectedJdbcExecutionResponse));
try String sql = evaluate(jdbcStatement.getSql(), variables, "jdbc statement sql"); validateSqlStatement(sql, jdbcStatementIndex); if (JdbcStatementType.UPDATE.equals(jdbcStatement.getType())) jdbcStatement.setStatus(JdbcStatementStatus.SUCCESS); jdbcStatement.setResult(String.valueOf(result)); else if (JdbcStatementType.QUERY.equals(jdbcStatement.getType())) jdbcStatement.setStatus(JdbcStatementStatus.SUCCESS); jdbcStatement.setResultSet(jdbcStatementResultSet); throw new IllegalStateException("Unsupported JDBC statement type '" + jdbcStatement.getType() + "'"); jdbcStatement.setStatus(JdbcStatementStatus.ERROR); jdbcStatement.setErrorMessage(maskSensitiveInformation(exception, variables));
/** * Test case where user specifies a QUERY statement type, but there are SQL errors. The status should be ERROR and no result set should exist in the * result. */ @Test public void testExecuteJdbcStatementTypeQueryError() { // Get test request JdbcExecutionRequest jdbcExecutionRequest = jdbcServiceTestHelper.createDefaultQueryJdbcExecutionRequest(); JdbcStatement expectedJdbcStatement = jdbcExecutionRequest.getStatements().get(0); expectedJdbcStatement.setSql(MockJdbcOperations.CASE_2_SQL); JdbcExecutionResponse jdbcExecutionResponse = jdbcService.executeJdbc(jdbcExecutionRequest); Assert.assertEquals("JDBC statements size", 1, jdbcExecutionResponse.getStatements().size()); JdbcStatement actualJdbcStatement = jdbcExecutionResponse.getStatements().get(0); Assert.assertNotNull("JDBC statement error message", actualJdbcStatement.getErrorMessage()); Assert.assertEquals("JDBC statement error message", "java.sql.SQLException: test DataIntegrityViolationException cause", actualJdbcStatement.getErrorMessage()); Assert.assertNull("JDBC statement result", actualJdbcStatement.getResult()); Assert.assertEquals("JDBC statement status", JdbcStatementStatus.ERROR, actualJdbcStatement.getStatus()); Assert.assertEquals("JDBC statement type", expectedJdbcStatement.getType(), actualJdbcStatement.getType()); Assert.assertNull("JDBC statement result set", actualJdbcStatement.getResultSet()); }
jdbcExecutionRequest.getStatements().add(new JdbcStatement(JdbcStatementType.UPDATE, MockJdbcOperations.CASE_2_SQL, true, null, null, null, null)); jdbcExecutionRequest.getStatements().add(new JdbcStatement(JdbcStatementType.UPDATE, MockJdbcOperations.CASE_1_SQL, false, null, null, null, null)); Assert.assertEquals("JDBC statement [0] status", JdbcStatementStatus.SUCCESS, actualJdbcStatement.getStatus()); JdbcStatement actualJdbcStatement = jdbcExecutionResponse.getStatements().get(1); Assert.assertEquals("JDBC statement [1] continue on error", expectedJdbcStatement.isContinueOnError(), actualJdbcStatement.isContinueOnError()); Assert.assertEquals("JDBC statement [1] status", JdbcStatementStatus.ERROR, actualJdbcStatement.getStatus()); Assert.assertNull("JDBC statement [1] result is not null", actualJdbcStatement.getResult()); Assert.assertEquals("JDBC statement [1] error message", "java.sql.SQLException: test DataIntegrityViolationException cause", actualJdbcStatement.getErrorMessage()); JdbcStatement actualJdbcStatement = jdbcExecutionResponse.getStatements().get(2); Assert.assertEquals("JDBC statement [2] status", expectedJdbcStatement.isContinueOnError(), actualJdbcStatement.isContinueOnError()); Assert.assertEquals("JDBC statement [2] status", JdbcStatementStatus.SUCCESS, actualJdbcStatement.getStatus());
/** * 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()); } }
@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); }); }
executeStatement(jdbcTemplate, jdbcStatement, variables, i); if (JdbcStatementStatus.ERROR.equals(jdbcStatement.getStatus()) && !Boolean.TRUE.equals(jdbcStatement.isContinueOnError()))
@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); }
/** * Create an instance of {@link JdbcStatement } * */ public JdbcStatement createJdbcStatement() { return new JdbcStatement(); }
/** * 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); } }
/** * 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()); }
@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()); } }
if (JdbcStatementStatus.ERROR.equals(jdbcStatement.getStatus()))
/** * 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()); } }
public Object copyTo(ObjectLocator locator, Object target, CopyStrategy2 strategy) { final Object draftCopy = ((target == null)?createNewInstance():target); if (draftCopy instanceof JdbcStatement) { final JdbcStatement copy = ((JdbcStatement) draftCopy); if (typeShouldBeCopiedAndSet == Boolean.TRUE) { JdbcStatementType sourceType; sourceType = this.getType(); JdbcStatementType copyType = ((JdbcStatementType) strategy.copy(LocatorUtils.property(locator, "type", sourceType), sourceType, (this.type!= null))); copy.setType(copyType); } else { if (typeShouldBeCopiedAndSet == Boolean.FALSE) { if (sqlShouldBeCopiedAndSet == Boolean.TRUE) { String sourceSql; sourceSql = this.getSql(); String copySql = ((String) strategy.copy(LocatorUtils.property(locator, "sql", sourceSql), sourceSql, (this.sql!= null))); copy.setSql(copySql); } else { if (sqlShouldBeCopiedAndSet == Boolean.FALSE) { if (continueOnErrorShouldBeCopiedAndSet == Boolean.TRUE) { Boolean sourceContinueOnError; sourceContinueOnError = this.isContinueOnError(); Boolean copyContinueOnError = ((Boolean) strategy.copy(LocatorUtils.property(locator, "continueOnError", sourceContinueOnError), sourceContinueOnError, (this.continueOnError!= null))); copy.setContinueOnError(copyContinueOnError); } else { if (continueOnErrorShouldBeCopiedAndSet == Boolean.FALSE) { if (statusShouldBeCopiedAndSet == Boolean.TRUE) {