Repository: mercedes-benz/sechub
Issue: SecHub report results do not contain job UUID

## Situation
With release `v0.27.0-server` the reports did not conain a job uuid any longer.
This is critical for sechub client interactive false-positive handling  were the Job UUID of an report is used - and will fail because not existing.

## Wanted
When user fetches reports the Job UUID must be in report again

## Solution
Problem lays inside `SerecoProductResultTransformer.java` where after the refactoring the job UUID was not set. 
This must be fixed.
Also `ScanSecHubReport` shall have an fallback for reports that were currently already transformed without job uuid inside.



 

Changed files:
sechub-integrationtest/src/main/java/com/daimler/sechub/integrationtest/api/AssertReport.java
sechub-scan-product-sereco/src/main/java/com/daimler/sechub/domain/scan/product/sereco/SerecoProductResultTransformer.java
sechub-integrationtest/src/test/java/com/daimler/sechub/integrationtest/scenario10/PDSCodeScanSarifJobScenario10IntTest.java
sechub-scan/src/test/java/com/daimler/sechub/domain/scan/report/ScanSecHubReportTest.java
sechub-scan/src/main/java/com/daimler/sechub/domain/scan/report/ScanSecHubReport.java

diff --git a/sechub-integrationtest/src/main/java/com/daimler/sechub/integrationtest/api/AssertReport.java b/sechub-integrationtest/src/main/java/com/daimler/sechub/integrationtest/api/AssertReport.java
index b5e6ac84e..f7237c685 100644
--- a/sechub-integrationtest/src/main/java/com/daimler/sechub/integrationtest/api/AssertReport.java
+++ b/sechub-integrationtest/src/main/java/com/daimler/sechub/integrationtest/api/AssertReport.java
@@ -235,11 +235,15 @@ public class AssertReport {
         assertNotNull(findings);
         return findings;
     }
-
-    public AssertReport hasJobUUID(String uuidAsString) {
-        assertEquals(UUID.fromString(uuidAsString), report.getJobUUID());
+    
+    public AssertReport hasJobUUID(UUID uuid) {
+        assertEquals(uuid, report.getJobUUID());
         return this;
     }
+    
+    public AssertReport hasJobUUID(String uuidAsString) {
+        return hasJobUUID(UUID.fromString(uuidAsString));
+    }
 
     public AssertReport dump() {
         LOG.info("-----------------------------------------------------------");
diff --git a/sechub-integrationtest/src/test/java/com/daimler/sechub/integrationtest/scenario10/PDSCodeScanSarifJobScenario10IntTest.java b/sechub-integrationtest/src/test/java/com/daimler/sechub/integrationtest/scenario10/PDSCodeScanSarifJobScenario10IntTest.java
index ddb83f8f8..8ee2d60ed 100644
--- a/sechub-integrationtest/src/test/java/com/daimler/sechub/integrationtest/scenario10/PDSCodeScanSarifJobScenario10IntTest.java
+++ b/sechub-integrationtest/src/test/java/com/daimler/sechub/integrationtest/scenario10/PDSCodeScanSarifJobScenario10IntTest.java
@@ -66,6 +66,7 @@ public class PDSCodeScanSarifJobScenario10IntTest {
         assertReport(report).
             hasStatus(SecHubStatus.SUCCESS).
             hasMessages(0).
+            hasJobUUID(jobUUID).
             hasTrafficLight(RED).
                finding(0).
                    hasSeverity(Severity.HIGH).
diff --git a/sechub-scan-product-sereco/src/main/java/com/daimler/sechub/domain/scan/product/sereco/SerecoProductResultTransformer.java b/sechub-scan-product-sereco/src/main/java/com/daimler/sechub/domain/scan/product/sereco/SerecoProductResultTransformer.java
index 28c9e8ba6..d23cb466a 100644
--- a/sechub-scan-product-sereco/src/main/java/com/daimler/sechub/domain/scan/product/sereco/SerecoProductResultTransformer.java
+++ b/sechub-scan-product-sereco/src/main/java/com/daimler/sechub/domain/scan/product/sereco/SerecoProductResultTransformer.java
@@ -56,6 +56,7 @@ public class SerecoProductResultTransformer implements ReportProductResultTransf
 
         ReportTransformationResult transformerResult = new ReportTransformationResult();
         transformerResult.setReportVersion(SecHubReportVersion.VERSION_1_0.getVersionAsString());
+        transformerResult.setJobUUID(sechubJobUUID);
 
         List<SecHubFinding> findings = transformerResult.getResult().getFindings();
 
diff --git a/sechub-scan/src/main/java/com/daimler/sechub/domain/scan/report/ScanSecHubReport.java b/sechub-scan/src/main/java/com/daimler/sechub/domain/scan/report/ScanSecHubReport.java
index 53882039f..db3ed5278 100644
--- a/sechub-scan/src/main/java/com/daimler/sechub/domain/scan/report/ScanSecHubReport.java
+++ b/sechub-scan/src/main/java/com/daimler/sechub/domain/scan/report/ScanSecHubReport.java
@@ -59,6 +59,11 @@ public class ScanSecHubReport implements SecHubReportData, JSONable<ScanSecHubRe
         if (ScanReportResultType.MODEL.equals(resultType)) {
             try {
                 model = SecHubReportModel.fromJSONString(report.getResult());
+                if (model.getJobUUID() == null) {
+                    // Fallback for problems when model did not contain job uuid - see https://github.com/Daimler/sechub/issues/864 
+                    LOG.warn("Job uuid not found inside report result JSON, will set Job UUID from entity data");
+                    model.setJobUUID(report.getSecHubJobUUID());
+                }
 
             } catch (JSONConverterException e) {
                 LOG.error("FATAL PROBLEM! Failed to create sechub result by model for job:{}", report.getSecHubJobUUID(), e);
diff --git a/sechub-scan/src/test/java/com/daimler/sechub/domain/scan/report/ScanSecHubReportTest.java b/sechub-scan/src/test/java/com/daimler/sechub/domain/scan/report/ScanSecHubReportTest.java
index e35ace13f..6c9bac7aa 100644
--- a/sechub-scan/src/test/java/com/daimler/sechub/domain/scan/report/ScanSecHubReportTest.java
+++ b/sechub-scan/src/test/java/com/daimler/sechub/domain/scan/report/ScanSecHubReportTest.java
@@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.*;
 
 import java.io.File;
 import java.util.List;
+import java.util.UUID;
 
 import org.junit.jupiter.api.Test;
 
@@ -18,6 +19,8 @@ import com.daimler.sechub.commons.model.Severity;
 import com.daimler.sechub.commons.model.TrafficLight;
 import com.daimler.sechub.domain.scan.ScanDomainTestFileSupport;
 
+import static org.mockito.Mockito.*;
+
 class ScanSecHubReportTest {
 
     @Test
@@ -115,6 +118,52 @@ class ScanSecHubReportTest {
         assertEquals(TrafficLight.GREEN, reportToTest.getTrafficLight());
     }
 
+    @Test
+    void report_by_model_sets_jobUUID_from_scanreport_when_not_inside_model() {
+
+        /* prepare */
+        UUID uuid = UUID.randomUUID();
+        
+        ScanReport report = mock(ScanReport.class);
+        when(report.getResultType()).thenReturn(ScanReportResultType.MODEL);
+        when(report.getSecHubJobUUID()).thenReturn(uuid);
+        
+        SecHubReportModel model = new SecHubReportModel();
+        
+        String jsonResult = model.toJSON();
+        when(report.getResult()).thenReturn(jsonResult);
+        
+        /* execute */
+        ScanSecHubReport createdReport = new ScanSecHubReport(report);
+
+        /* test */
+        assertEquals(uuid, createdReport.getJobUUID());
+    }
+    
+    @Test
+    void report_by_model_has_jobUUID_from_model_when_there_not_null() {
+
+        /* prepare */
+        UUID uuid1 = UUID.randomUUID();
+        UUID uuid2 = UUID.randomUUID();
+        
+        ScanReport report = mock(ScanReport.class);
+        when(report.getResultType()).thenReturn(ScanReportResultType.MODEL);
+        when(report.getSecHubJobUUID()).thenReturn(uuid1);
+        
+        SecHubReportModel model = new SecHubReportModel();
+        model.setJobUUID(uuid2);
+        
+        String jsonResult = model.toJSON();
+        when(report.getResult()).thenReturn(jsonResult);
+        
+        /* execute */
+        ScanSecHubReport createdReport = new ScanSecHubReport(report);
+
+        /* test */
+        assertEquals(uuid2, createdReport.getJobUUID());
+    }
+    
     @Test
     void report_by_model_sets_version_to_version_from_model() {