diff --git a/spring-cloud-dataflow-server-core/src/main/java/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamService.java b/spring-cloud-dataflow-server-core/src/main/java/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamService.java index ec9d87315b..b18b85cc93 100644 --- a/spring-cloud-dataflow-server-core/src/main/java/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamService.java +++ b/spring-cloud-dataflow-server-core/src/main/java/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamService.java @@ -243,13 +243,12 @@ private void updateStreamDefinitionFromReleaseManifest(String streamName, String streamDefinition.getOriginalDslText(), streamDefinition.getDescription()); logger.debug("Updated StreamDefinition: " + updatedStreamDefinition); - // TODO consider adding an explicit UPDATE method to the streamDefRepository - // Note: Not transactional and can lead to loosing the stream definition + // NOTE: Not transactional and can lead to losing the stream definition this.streamDefinitionRepository.delete(updatedStreamDefinition); this.streamDefinitionRepository.save(updatedStreamDefinition); this.auditRecordService.populateAndSaveAuditRecord( AuditOperationType.STREAM, AuditActionType.UPDATE, streamName, - updatedStreamDefinition.getDslText(), null); + this.streamDefinitionService.redactDsl(updatedStreamDefinition), null); } @Override diff --git a/spring-cloud-dataflow-server-core/src/test/java/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamServiceIntegrationTests.java b/spring-cloud-dataflow-server-core/src/test/java/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamServiceIntegrationTests.java index 81bf2d03e5..54c425b0e0 100644 --- a/spring-cloud-dataflow-server-core/src/test/java/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamServiceIntegrationTests.java +++ b/spring-cloud-dataflow-server-core/src/test/java/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamServiceIntegrationTests.java @@ -20,6 +20,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; +import java.time.Instant; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -41,7 +42,11 @@ import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.cloud.dataflow.audit.service.AuditRecordService; import org.springframework.cloud.dataflow.core.ApplicationType; +import org.springframework.cloud.dataflow.core.AuditActionType; +import org.springframework.cloud.dataflow.core.AuditOperationType; +import org.springframework.cloud.dataflow.core.AuditRecord; import org.springframework.cloud.dataflow.core.StreamDefinition; import org.springframework.cloud.dataflow.core.StreamDeployment; import org.springframework.cloud.dataflow.registry.service.AppRegistryService; @@ -64,6 +69,8 @@ import org.springframework.cloud.skipper.domain.RollbackRequest; import org.springframework.cloud.skipper.domain.UpgradeRequest; import org.springframework.cloud.skipper.domain.UploadRequest; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; @@ -100,6 +107,9 @@ public class DefaultStreamServiceIntegrationTests { @Autowired private AppRegistryService appRegistryService; + @Autowired + private AuditRecordService auditRecordService; + @MockBean private SkipperClient skipperClient; @@ -179,14 +189,13 @@ public void testInstallVersionOverride() throws IOException { public void testUpdateStreamDslOnDeploy() throws IOException { // Create stream - StreamDefinition streamDefinition = new StreamDefinition("ticktock", - "time --fixed-delay=100 | log --level=DEBUG"); + String originalDsl = "time --fixed-delay=100 --spring.cloud.config.password=5150 | log --level=DEBUG"; + StreamDefinition streamDefinition = new StreamDefinition("ticktock", originalDsl); this.streamDefinitionRepository.deleteById(streamDefinition.getName()); this.streamDefinitionRepository.save(streamDefinition); StreamDefinition streamDefinitionBeforeDeploy = this.streamDefinitionRepository.findById("ticktock").get(); - assertThat(streamDefinitionBeforeDeploy.getDslText()) - .isEqualTo("time --fixed-delay=100 | log --level=DEBUG"); + assertThat(streamDefinitionBeforeDeploy.getDslText()).isEqualTo(originalDsl); String expectedReleaseManifest = StreamUtils.copyToString( TestResourceUtils.qualifiedResource(getClass(), "deployManifest.yml").getInputStream(), @@ -203,9 +212,27 @@ public void testUpdateStreamDslOnDeploy() throws IOException { streamService.deployStream("ticktock", deploymentProperties); + assertThatAuditRecordDataIsRedacted(AuditActionType.DEPLOY); + assertThatAuditRecordDataIsRedacted(AuditActionType.UPDATE); + + String expectedUpdatedDsl = "time --spring.cloud.config.password=5150 --trigger.fixed-delay=100 | log --log.level=DEBUG"; StreamDefinition streamDefinitionAfterDeploy = this.streamDefinitionRepository.findById("ticktock").get(); - assertThat(streamDefinitionAfterDeploy.getDslText()) - .isEqualTo("time --trigger.fixed-delay=100 | log --log.level=DEBUG"); + assertThat(streamDefinitionAfterDeploy.getDslText()).isEqualTo(expectedUpdatedDsl); + } + + private void assertThatAuditRecordDataIsRedacted(AuditActionType auditActionType) { + Page auditRecords = this.auditRecordService.findAuditRecordByAuditOperationTypeAndAuditActionTypeAndDate( + PageRequest.of(0, 1), + new AuditActionType[]{ auditActionType }, + new AuditOperationType[]{ AuditOperationType.STREAM }, + Instant.now().minusSeconds(5), + Instant.now().plusSeconds(1) + ); + assertThat(auditRecords.getNumberOfElements()).isEqualTo(1); + assertThat(auditRecords.get().map(AuditRecord::getAuditData).findFirst()) + .hasValueSatisfying((auditData) -> assertThat(auditData) + .contains("--spring.cloud.config.password='******'") + .doesNotContain("--spring.cloud.config.password='5150'")); } @Test diff --git a/spring-cloud-dataflow-server-core/src/test/resources/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamServiceIntegrationTests-deployManifest.yml b/spring-cloud-dataflow-server-core/src/test/resources/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamServiceIntegrationTests-deployManifest.yml index 2900acedf1..5d9f754c77 100644 --- a/spring-cloud-dataflow-server-core/src/test/resources/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamServiceIntegrationTests-deployManifest.yml +++ b/spring-cloud-dataflow-server-core/src/test/resources/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamServiceIntegrationTests-deployManifest.yml @@ -10,6 +10,7 @@ spec: applicationProperties: spring.cloud.dataflow.stream.app.label: time trigger.fixed-delay: 100 + spring.cloud.config.password: 5150 spring.cloud.stream.bindings.output.producer.requiredGroups: ticktock spring.cloud.stream.bindings.output.destination: ticktock.time spring.cloud.dataflow.stream.name: ticktock diff --git a/spring-cloud-dataflow-server-core/src/test/resources/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamServiceIntegrationTests-install.yml b/spring-cloud-dataflow-server-core/src/test/resources/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamServiceIntegrationTests-install.yml index e8ff31eac3..749245d211 100644 --- a/spring-cloud-dataflow-server-core/src/test/resources/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamServiceIntegrationTests-install.yml +++ b/spring-cloud-dataflow-server-core/src/test/resources/org/springframework/cloud/dataflow/server/service/impl/DefaultStreamServiceIntegrationTests-install.yml @@ -23,4 +23,5 @@ "wavefront.application.service": ${spring.cloud.dataflow.stream.app.label:unknown}-${spring.cloud.dataflow.stream.app.type:unknown}-${vcap.application.instance_index:${spring.cloud.stream.instanceIndex:0}} "version": "1.2.0.RELEASE" "deploymentProperties": + "spring.cloud.deployer.bootVersion": "2" "spring.cloud.deployer.group": "ticktock"