Skip to content

Commit

Permalink
Merge pull request #1526 from mercedes-benz/feature-1474-clusterwide-…
Browse files Browse the repository at this point in the history
…pds-cancel-operation

Make SecHub&PDS cancel cluster ready, provide config defaults and events
  • Loading branch information
de-jcup authored Sep 16, 2022
2 parents 6781be2 + e585d9b commit 384fcd5
Show file tree
Hide file tree
Showing 202 changed files with 4,647 additions and 882 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/create-releases.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ jobs:
# SecHub Server + PDS
# ----------------------
- name: Build Server and PDS artifacts
run: ./gradlew ensureLocalhostCertificate build buildWrapperOwaspZap generateOpenapi buildDeveloperAdminUI -x :sechub-integrationtest:test -x :sechub-cli:build
run: ./gradlew ensureLocalhostCertificate build buildWrapperOwaspZap generateOpenapi buildDeveloperAdminUI -x :sechub-integrationtest:test -x :sechub-cli:build --parallel

# ----------------------
# API Java publish
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
run: ./gradlew :sechub-cli:buildGo :sechub-cli:testGo

- name: Build Server, DAUI and generate OpenAPI file
run: ./gradlew ensureLocalhostCertificate build generateOpenapi buildDeveloperAdminUI buildPDSToolsCLI -x :sechub-integrationtest:test -x :sechub-cli:build
run: ./gradlew ensureLocalhostCertificate build generateOpenapi buildDeveloperAdminUI buildPDSToolsCLI -x :sechub-integrationtest:test -x :sechub-cli:build --parallel

- name: Generate and build API Java
run: ./gradlew :sechub-api-java:buildAPIJava
Expand Down
2 changes: 1 addition & 1 deletion continous-integration-multibranch-pipeline.jenkins
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pipeline {
// We do NOT build sechub-integrationtest
// Reason: because we do NOT want to have the integration tests executed, otherwise gradle will not execute them
// on integration phase again (because nothing has changed, so gradle will cache the results which are ignored ...
callGradleWrapper("ensureLocalhostCertificate build generateOpenapi buildDeveloperAdminUI -x :sechub-integrationtest:test -x :sechub-cli:build -Psechub.test.wiremock.https_port=${env.SECHUB_TEST_WIREMOCK_HTTPS_PORT} -Psechub.test.wiremock.http_port=${env.SECHUB_TEST_WIREMOCK_HTTP_PORT}")
callGradleWrapper("ensureLocalhostCertificate build generateOpenapi buildDeveloperAdminUI -x :sechub-integrationtest:test -x :sechub-cli:build -Psechub.test.wiremock.https_port=${env.SECHUB_TEST_WIREMOCK_HTTPS_PORT} -Psechub.test.wiremock.http_port=${env.SECHUB_TEST_WIREMOCK_HTTP_PORT} --parallel")
callGradleWrapper(":sechub-api-java:buildAPIJava")
}
}
Expand Down
2 changes: 1 addition & 1 deletion release-pipeline.jenkins
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ pipeline {
* Reason: because we do NOT want to have the integration tests executed, otherwise gradle will not execute them
* on integration phase again (because nothing has changed, so gradle will cache the results which are ignored ...
*/
callGradleWrapper("ensureLocalhostCertificate build generateOpenapi buildDeveloperAdminUI -x :sechub-integrationtest:test -x :sechub-cli:build -Psechub.test.wiremock.https_port=${env.SECHUB_TEST_WIREMOCK_HTTPS_PORT} -Psechub.test.wiremock.http_port=${env.SECHUB_TEST_WIREMOCK_HTTP_PORT}")
callGradleWrapper("ensureLocalhostCertificate build generateOpenapi buildDeveloperAdminUI -x :sechub-integrationtest:test -x :sechub-cli:build -Psechub.test.wiremock.https_port=${env.SECHUB_TEST_WIREMOCK_HTTPS_PORT} -Psechub.test.wiremock.http_port=${env.SECHUB_TEST_WIREMOCK_HTTP_PORT} --parallel")
callGradleWrapper(":sechub-api-java:buildAPIJava")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ private void waitForJobDone(PDSContext context) throws AdapterException {
config.getTimeOutInMilliseconds());
/* @formatter:on */

while (!jobEnded && isNotTimeout(config, started)) {
StateFulTimeOutCheck timeOutCheck = new StateFulTimeOutCheck();

while (!jobEnded && timeOutCheck.isNotTimeout(config, started)) {

count++;

Expand All @@ -136,8 +138,9 @@ private void waitForJobDone(PDSContext context) throws AdapterException {
jobEnded = true;
break;
case FAILED:
throw asAdapterException("PDS job execution failed", config);
throw asAdapterException("PDS job execution failed: TimeOut=" + timeOutCheck.wasTimeOut() + ",JobEnded=" + jobEnded, config);
case CANCELED:
case CANCEL_REQUESTED:
throw asAdapterCanceledByUserException(config);
default:
// just do nothing else
Expand All @@ -151,7 +154,8 @@ private void waitForJobDone(PDSContext context) throws AdapterException {
try {
Thread.sleep(timeToWaitForNextCheckOperationInMilliseconds);
} catch (InterruptedException e) {
throw new AdapterException(getAdapterLogId(null), "Execution thread was interrupted");
throw new AdapterException(getAdapterLogId(null),
"Execution thread was interrupted. Type:" + context.getRuntimeContext().getType() + ", Thread was:" + Thread.currentThread().getName());
}

}
Expand All @@ -164,8 +168,17 @@ private void waitForJobDone(PDSContext context) throws AdapterException {

}

private boolean isNotTimeout(PDSAdapterConfig config, long started) {
return calculateElapsedTime(started) < config.getTimeOutInMilliseconds();
private class StateFulTimeOutCheck {
boolean stillTimeLeft = true;

boolean isNotTimeout(PDSAdapterConfig config, long started) {
stillTimeLeft = calculateElapsedTime(started) < config.getTimeOutInMilliseconds();
return stillTimeLeft;
}

boolean wasTimeOut() {
return !stillTimeLeft;
}
}

private long calculateElapsedTime(long started) {
Expand Down Expand Up @@ -346,8 +359,8 @@ private AdapterExecutionResult handleExecutionType(PDSContext context, AdapterRu
return handleExecutionTypeInitial(context, runtimeContext);
case RESTART:
return handleExecutionTypeRestart(context, runtimeContext);
case STOP:
return handleExecutionTypeStop(context, runtimeContext);
case CANCEL:
return handleExecutionTypeCancel(context, runtimeContext);
default:
throw new IllegalStateException("the execution type: " + executionType + " is not supported");
}
Expand Down Expand Up @@ -424,18 +437,18 @@ private AdapterExecutionResult handleExecutionTypeRestart(PDSContext context, Ad
return NO_EXISTING_ADAPTER_EXECUTION_RESULT;
}

private AdapterExecutionResult handleExecutionTypeStop(PDSContext context, AdapterRuntimeContext runtimeContext) throws AdapterException {
private AdapterExecutionResult handleExecutionTypeCancel(PDSContext context, AdapterRuntimeContext runtimeContext) throws AdapterException {
AdapterMetaData metaData = runtimeContext.getMetaData();
String pdsJobUUID = metaData.getValueAsStringOrNull(PDS_JOB_UUID);

if (pdsJobUUID == null || pdsJobUUID.isEmpty()) {
LOG.error("PDS job uuid was :{}, so stop not possible.", pdsJobUUID);
LOG.error("PDS job uuid from adapter meta data was :{}, so stop not possible.", pdsJobUUID);
throw asAdapterException("PDS job uuid not set, cannot cancel", context);
}
context.setPDSJobUUID(UUID.fromString(pdsJobUUID));
cancelJob(context);

return new AdapterExecutionResult("");
return AdapterExecutionResult.createCancelResult();
}

/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,32 @@ void restart_pds_job_uuid_found_in_metadata_but_was_canceled(PDSJobStatusState f

}

@ParameterizedTest
@EnumSource(value = PDSJobStatusState.class)
@DisplayName("Cancel - Meta data found and PDS job uuid set and former job state can be canceled")
void stop_pds_job_uuid_found_in_metadata_and_running(PDSJobStatusState formerPdsJobState) throws Exception {
/* prepare */
prepareMinimumPDSConfig();

UUID formerPdsJobUUID = pdsJobUUID1;
AdapterMetaData metaData = new AdapterMetaData();
when(callback.getMetaDataOrNull()).thenReturn(metaData);
metaData.setValue("PDS_JOB_UUID", formerPdsJobUUID.toString());

preparePDSJobStatus(formerPdsJobUUID, formerPdsJobState);

preparePDSJobCreation(pdsJobUUID2);
preparePDSJobStatus(pdsJobUUID2, PDSJobStatusState.DONE);
preparePDSMessages(pdsJobUUID2, Collections.emptyList());

/* execute */
boolean stopped = adapterToTest.cancel(config, callback);

/* test */
assertTrue(stopped);

}

/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* + ................Helper.......................... + */
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public final AdapterExecutionResult start(C config, AdapterMetaDataCallback call
}

@Override
public final boolean stop(C config, AdapterMetaDataCallback callback) throws AdapterException {
public final boolean cancel(C config, AdapterMetaDataCallback callback) throws AdapterException {
AdapterMetaData metaData = callback.getMetaDataOrNull();

if (metaData == null) {
Expand All @@ -89,11 +89,11 @@ public final boolean stop(C config, AdapterMetaDataCallback callback) throws Ada
AdapterRuntimeContext runtimeContext = new AdapterRuntimeContext();
runtimeContext.callback = null;
runtimeContext.metaData = metaData;
runtimeContext.type = ExecutionType.STOP;
runtimeContext.type = ExecutionType.CANCEL;

execute(config, runtimeContext);
AdapterExecutionResult result = execute(config, runtimeContext);

return runtimeContext.stopped;
return result.hasBeenCanceled();
}

protected abstract AdapterExecutionResult execute(C config, AdapterRuntimeContext runtimeContext) throws AdapterException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ public interface Adapter<C extends AdapterConfig> {
AdapterExecutionResult start(C config, AdapterMetaDataCallback callback) throws AdapterException;

/**
* Try to stop
* Triggers cancel returns <code>true</code> when cancel was done
*
* @param config
* @param callback
* @return <code>true</code> when stop was possible
*/
boolean stop(C config, AdapterMetaDataCallback callback) throws AdapterException;
boolean cancel(C config, AdapterMetaDataCallback callback) throws AdapterException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,21 @@ public class AdapterExecutionResult {

private String productResult;

/**
* Create an empty adapter execution result which is marked as "stopped"
*
* @return execution result
*/
public static AdapterExecutionResult createCancelResult() {
AdapterExecutionResult result = new AdapterExecutionResult("");
result.canceled = true;
return result;
}

private List<SecHubMessage> productMessages = new ArrayList<>();

private boolean canceled;

public AdapterExecutionResult(String productResult) {
this(productResult, null);
}
Expand Down Expand Up @@ -43,4 +56,8 @@ public List<SecHubMessage> getProductMessages() {
public String getProductResult() {
return productResult;
}

public boolean hasBeenCanceled() {
return canceled;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ public class AdapterRuntimeContext {
AdapterMetaDataCallback callback;
AdapterMetaData metaData;
ExecutionType type = ExecutionType.INITIAL;
boolean stopped;

public void markStopped() {
this.stopped = true;
}

public ExecutionType getType() {
return type;
Expand All @@ -29,6 +24,6 @@ public enum ExecutionType {

RESTART,

STOP
CANCEL
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ public void receiveAsyncMessage(DomainMessage request) {
case JOB_FAILED:
handleJobFailed(request);
break;
case JOB_CANCELED:
handleJobCanceled(request);
case JOB_CANCELLATION_RUNNING:
handleJobCancellationRunning(request);
break;
case AUTO_CLEANUP_CONFIGURATION_CHANGED:
handleAutoCleanUpConfigurationChanged(request);
Expand All @@ -61,8 +61,8 @@ private void handleAutoCleanUpConfigurationChanged(DomainMessage request) {
configService.updateAutoCleanupInDays(message.getAutoCleanupInDays());
}

@IsReceivingAsyncMessage(MessageID.JOB_CANCELED)
private void handleJobCanceled(DomainMessage request) {
@IsReceivingAsyncMessage(MessageID.JOB_CANCELLATION_RUNNING)
private void handleJobCancellationRunning(DomainMessage request) {
JobMessage message = request.get(MessageDataKeys.JOB_CANCEL_DATA);
// we do drop job info - we only hold running and waiting jobs!
deleteService.delete(message.getJobUUID());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public List<JobInformation> fetchAllRunningJobs() {
}

/* @formatter:off */
@UseCaseAdminCancelsJob(@Step(number=1,name="Rest call",description="Triggers job cancelation request, owners of project will be informed",needsRestDoc=true))
@UseCaseAdminCancelsJob(@Step(number=1,name="Rest call",description="Triggers job cancellation request, owners of project will be informed",needsRestDoc=true))
@RequestMapping(path = AdministrationAPIConstants.API_ADMIN_CANCELS_JOB, method = RequestMethod.POST, produces= {MediaType.APPLICATION_JSON_VALUE})
public void cancelJob(@PathVariable(name="jobUUID") UUID jobUUID) {
/* @formatter:on */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public class JobCancelService {
public void cancelJob(UUID jobUUID) {
assertion.assertIsValidJobUUID(jobUUID);

auditLogService.log("Requested cancelation of job {}", jobUUID);
auditLogService.log("Requested cancellation of job {}", jobUUID);

JobMessage message = buildMessage(jobUUID);

Expand Down Expand Up @@ -87,10 +87,10 @@ private JobMessage buildMessage(UUID jobUUID) {
return message;
}

@IsSendingAsyncMessage(MessageID.REQUEST_JOB_CANCELATION)
@IsSendingAsyncMessage(MessageID.REQUEST_JOB_CANCELLATION)
private void informCancelJobRequested(JobMessage message) {

DomainMessage infoRequest = DomainMessageFactory.createEmptyRequest(MessageID.REQUEST_JOB_CANCELATION);
DomainMessage infoRequest = DomainMessageFactory.createEmptyRequest(MessageID.REQUEST_JOB_CANCELLATION);
infoRequest.set(MessageDataKeys.JOB_CANCEL_DATA, message);

eventBusService.sendAsynchron(infoRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public T markGenerated() {
}

@SuppressWarnings("unchecked")
public T markAlwaysSentToPDS() {
public T markSendToPDS() {
this.sentToPDS = true;
return (T) this;
}
Expand Down
Loading

0 comments on commit 384fcd5

Please sign in to comment.