Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.opendevstack.component_provisioner.server.controllers.exceptions.ProjectComponentAlreadyProvisionedException;
import org.opendevstack.component_provisioner.server.controllers.exceptions.UserNotAllowedException;
import org.opendevstack.component_provisioner.server.controllers.model.ActionType;
import org.opendevstack.component_provisioner.server.facade.ProvisionActionWrapper;
import org.opendevstack.component_provisioner.server.model.ProvisionAction;
import org.opendevstack.component_provisioner.server.services.AuthenticationProvider;
import org.opendevstack.component_provisioner.server.services.ComponentCatalogService;
Expand Down Expand Up @@ -59,12 +60,6 @@ public void validate(ProvisionAction provisionAction) {
validateUserHasPermissionsToProvision(projectKey, accessToken);
}

public void validateActionHasWorkflowDefined(ProvisionAction provisionAction) {
var workflow = getWorkflow(provisionAction);
var workflowName = getWorkflowName(provisionAction);
validateWorkflowPresence(workflow, workflowName);
}

public void validateReceivesOnlyVisibleParameters(ProvisionAction provisionAction, CatalogItem catalogItem) {
var catalogItemProvisionUserAction = Optional.ofNullable(catalogItem)
.map(CatalogItem::getUserActions)
Expand Down Expand Up @@ -151,9 +146,11 @@ private static void validateInputParams(String projectKey, String accessToken, S
}
}

private void validateWorkflowPresence(String workflow, String workflowName) {
log.debug("Validating presence of workflow or workflow_name. Workflow: {}, Workflow name: {}", workflow, workflowName);
public void validateWorkflowPresence(ProvisionAction provisionAction) {
var workflow = getWorkflow(provisionAction);
var workflowName = getWorkflowName(provisionAction);

log.debug("Validating presence of workflow or workflow_name. Workflow: {}, Workflow name: {}", workflow, workflowName);
if (StringUtils.isBlank(workflow) && StringUtils.isBlank(workflowName)) {
throw new InvalidRestEntityException("Either workflow or workflow_name are required.");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.opendevstack.component_provisioner.server.facade;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
Expand All @@ -21,10 +22,14 @@
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class ProvisionResultsApiFacade {

Expand All @@ -43,22 +48,6 @@ public class ProvisionResultsApiFacade {
@Value("${component-provisioner.awx.workflows.deletion-wrapper-workflow-id}")
private String deletionWrapperWorkflowId;

public ProvisionResultsApiFacade(AwxService awxService,
ComponentCatalogService componentCatalogService,
EntitiesMapper entitiesMapper,
ProvisionService provisionService,
AuthenticationProvider authenticationProvider,
ProjectsInfoService projectsInfoService,
ApplicationAuthenticationProvider applicationAuthenticationProvider) {
this.awxService = awxService;
this.componentCatalogService = componentCatalogService;
this.entitiesMapper = entitiesMapper;
this.provisionService = provisionService;
this.authenticationProvider = authenticationProvider;
this.projectsInfoService = projectsInfoService;
this.applicationAuthenticationProvider = applicationAuthenticationProvider;
}

public AwxResponse requestDeletion(
String projectKey,
String componentId,
Expand Down Expand Up @@ -302,6 +291,18 @@ private void addDeletionWrapperWorkflowParameters(String catalogItemId,
.build()
);
}
var dispatchedWorkflowParams = action.getParameters().stream().map(CreateIncidentParameter::getName).collect(Collectors.toSet());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dispatchedWorkflowParams.add("notifications_group_id"); // This param is added later by the entitiesMapper, so we need to manually add it

var allParams = new ArrayList<>(action.getParameters());
var createIncidentParamDispatchedWorkflowParams = CreateIncidentParameter.builder()
.name("dispatched_workflow_params")
.value(dispatchedWorkflowParams)
.type(ParameterType.MULTIPLELIST.getValue())
.build();
allParams.add(createIncidentParamDispatchedWorkflowParams);

action.setParameters(allParams);
}

private void addCallerParameter(CreateIncidentAction action) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.opendevstack.component_provisioner.server.controllers.validators.ParameterType;
import org.opendevstack.component_provisioner.server.controllers.validators.ProvisionerActionsApiValidator;
import org.opendevstack.component_provisioner.server.mappers.EntitiesMapper;
import org.opendevstack.component_provisioner.server.model.CreateIncidentParameter;
import org.opendevstack.component_provisioner.server.model.ProvisionAction;
import org.opendevstack.component_provisioner.server.model.ProvisionActionParameter;
import org.opendevstack.component_provisioner.server.model.ProvisionActionResponse;
Expand All @@ -24,9 +25,11 @@
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static org.opendevstack.component_provisioner.server.services.ProvisionerActionsParameterExtractor.getLocation;

Expand Down Expand Up @@ -56,9 +59,10 @@ public AwxResponse triggerProvisionAction(ProvisionAction provisionAction) {
provisionerActionsApiValidator.validateReceivesOnlyVisibleParameters(resolvedActionWrapper.toProvisionAction(), catalogItem);
var systemParametersActionWrapper = addSystemParametersToAction(resolvedActionWrapper);
var requiredCatalogItemParamsWrapper = addMandatoryCatalogItemParamsIfMissing(systemParametersActionWrapper, catalogItem);
provisionerActionsApiValidator.validateActionHasWorkflowDefined(requiredCatalogItemParamsWrapper.toProvisionAction());
provisionerActionsApiValidator.validateMandatoryFields(requiredCatalogItemParamsWrapper.toProvisionAction(), catalogItem);
var updateProvisionActionWithoutPlaceholdersWrapper = placeholderPostProcessor.process(requiredCatalogItemParamsWrapper);
var workflowWrapperParamsActionWrapper = addProvisionWorkflowWrapper(requiredCatalogItemParamsWrapper);
provisionerActionsApiValidator.validateWorkflowPresence(workflowWrapperParamsActionWrapper.toProvisionAction());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not make sense to validate and object, and use another one later on. (Even when they should be virtuallly equals.

Better to create the object, validate it, and reuse it later on.

var provisionAction = workflowWrapperParamsActionWrapper.toProvisionAction(); provisionerActionsApiValidator.validateWorkflowPresence(provisionAction); provisionerActionsApiValidator.validateMandatoryFields(provisionAction, catalogItem);

provisionerActionsApiValidator.validateMandatoryFields(workflowWrapperParamsActionWrapper.toProvisionAction(), catalogItem);
var updateProvisionActionWithoutPlaceholdersWrapper = placeholderPostProcessor.process(workflowWrapperParamsActionWrapper);
var updatedProvisionActionWithOdsApiParametersWrapper = replaceParametersService.replaceProvisioningParametersFromOdsApi(updateProvisionActionWithoutPlaceholdersWrapper);

notifyComponentCatalogProvisionStarts(updatedProvisionActionWithOdsApiParametersWrapper);
Expand Down Expand Up @@ -113,11 +117,10 @@ public ProvisionActionWrapper addSystemParametersToAction(ProvisionActionWrapper
var locationProvisionWrapper = addClusterLocationToAction(provisionActionWrapper);
var callerProvisionWrapper = addCallerToAction(locationProvisionWrapper);
var bearerTokenWrapper = addBearerTokenToActions(callerProvisionWrapper);
var addProvisionWorkflowWrapper = addProvisionWorkflowWrapper(bearerTokenWrapper);

log.debug("Added system parameters to provision action: '{}'", addProvisionWorkflowWrapper);
log.debug("Added system parameters to provision action: '{}'", bearerTokenWrapper);

return addProvisionWorkflowWrapper;
return bearerTokenWrapper;
}

private void updateAwxJobIdIntoProjectComponents(ProvisionActionWrapper provisionActionWrapper, AwxResponse awxResponse) {
Expand Down Expand Up @@ -241,6 +244,15 @@ private ProvisionActionWrapper addProvisionWorkflowWrapper(ProvisionActionWrappe
);
}

var dispatchedWorkflowParams = provisionActionWrapperWithoutWorkflowInfo.getParametersMap().values().stream().map(ProvisionActionParameter::getName).collect(Collectors.toSet());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest to follow normal stream format, I mean

var dispatchedWorkflowParams = provisionActionWrapperWithoutWorkflowInfo.getParametersMap().values().stream() .map(ProvisionActionParameter::getName) .collect(Collectors.toSet());

dispatchedWorkflowParams.add("notifications_group_id"); // This param is added later by the entitiesMapper, so we need to manually add it
var provisionParamDispatchedWorkflowParams = ProvisionActionParameter.builder()
.name("dispatched_workflow_params")
.value(dispatchedWorkflowParams)
.type(ParameterType.MULTIPLELIST.getValue())
.build();
parametersToAdd.add(provisionParamDispatchedWorkflowParams);

return provisionActionWrapperWithoutWorkflowInfo.cloneWithParameters(parametersToAdd);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,48 +505,49 @@ void validateReceivesOnlyVisibleParameters_succeedsWhenInternalParamsCombinedWit
}

@Test
void validateActionHasWorkflowDefined_throwsInvalidRestEntityException_whenBothWorkflowAndWorkflowNameMissing() {
void validateWorkflowPresence_throwsInvalidRestEntityException_whenBothWorkflowAndWorkflowNameMissing() {
var action = ProvisionActionMother.of(List.of(
ProvisionActionParameterMother.of("project_key", "pkey"),
ProvisionActionParameterMother.of("component_id", "cid"),
ProvisionActionParameterMother.of("catalog_item_id", "catid"),
ProvisionActionParameterMother.of("access_token", "accessToken")
));

// when / then
assertThrows(InvalidRestEntityException.class,
() -> provisionerActionsApiValidator.validateActionHasWorkflowDefined(action));
() -> provisionerActionsApiValidator.validateWorkflowPresence(action));
}

@Test
void validateActionHasWorkflowDefined_succeeds_whenWorkflowProvidedByUser() {
void validateWorkflowPresence_succeeds_whenWorkflowProvidedByUser() {
var action = ProvisionActionMother.of(List.of(
ProvisionActionParameterMother.of("workflow", "wf-123")
));

assertThatNoException().isThrownBy(() -> provisionerActionsApiValidator.validateActionHasWorkflowDefined(action));
assertThatNoException().isThrownBy(() -> provisionerActionsApiValidator.validateWorkflowPresence(action));
}

@Test
void validateActionHasWorkflowDefined_succeeds_whenWorkflowNameProvidedByUser() {
void validateWorkflowPresence_succeeds_whenWorkflowNameProvidedByUser() {
var action = ProvisionActionMother.of(List.of(
ProvisionActionParameterMother.of("workflow_name", "wf-name")
));

assertThatNoException().isThrownBy(() -> provisionerActionsApiValidator.validateActionHasWorkflowDefined(action));
assertThatNoException().isThrownBy(() -> provisionerActionsApiValidator.validateWorkflowPresence(action));
}

@Test
void validateActionHasWorkflowDefined_succeeds_whenBothWorkflowAndWorkflowNameProvided() {
void validateWorkflowPresence_succeeds_whenBothWorkflowAndWorkflowNameProvided() {
var action = ProvisionActionMother.of(List.of(
ProvisionActionParameterMother.of("workflow", "wf-123"),
ProvisionActionParameterMother.of("workflow_name", "wf-name")
));

assertThatNoException().isThrownBy(() -> provisionerActionsApiValidator.validateActionHasWorkflowDefined(action));
assertThatNoException().isThrownBy(() -> provisionerActionsApiValidator.validateWorkflowPresence(action));
}

@Test
void validateActionHasWorkflowDefined_succeeds_whenWorkflowComesFromHiddenCatalogItemParam() {
void validateWorkflowPresence_succeeds_whenWorkflowComesFromHiddenCatalogItemParam() {
// Workflow was not provided by the user but was injected from the catalog item's
// hidden (non-visible) mandatory parameter before this validation is invoked
var action = ProvisionActionMother.of(List.of(
Expand All @@ -556,6 +557,6 @@ void validateActionHasWorkflowDefined_succeeds_whenWorkflowComesFromHiddenCatalo
ProvisionActionParameterMother.of("workflow", "wf-from-hidden-param")
));

assertThatNoException().isThrownBy(() -> provisionerActionsApiValidator.validateActionHasWorkflowDefined(action));
assertThatNoException().isThrownBy(() -> provisionerActionsApiValidator.validateWorkflowPresence(action));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -780,4 +780,46 @@ void givenAwxTriggerFails_whenRequestDeletionIsCalled_thenReturnsErrorStatus() {
assertThat(result.httpStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR);
}

@Test
void givenWrapperWorkflow_whenAddDeletionWrapperWorkflowParametersIsCalled_thenDispatchedWorkflowParamsContainsAllParametersAndNotification() {
// given
var action = CreateIncidentActionMother.of();
action.setParameters(new ArrayList<>());

when(authenticationProvider.getAccessToken()).thenReturn("token");

// when
ReflectionTestUtils.invokeMethod(
facade,
"addDeletionWrapperWorkflowParameters",
"catalogId",
"wfId",
"wfName",
"60",
action
);

// then
var dispatchedParam = action.getParameters().stream()
.filter(p -> "dispatched_workflow_params".equals(p.getName()))
.findFirst()
.orElse(null);

assertThat(dispatchedParam).isNotNull();
assertThat(dispatchedParam.getValue()).isInstanceOf(java.util.Set.class);

@SuppressWarnings("unchecked")
var dispatchedSet = (java.util.Set<String>) dispatchedParam.getValue();

var expectedParamNames = action.getParameters().stream()
.map(CreateIncidentParameter::getName)
.filter(name -> !"dispatched_workflow_params".equals(name))
.toList();

assertThat(dispatchedSet).containsAll(expectedParamNames);

assertThat(dispatchedSet).contains("notifications_group_id");
}


}
Loading
Loading