Skip to content

Commit

Permalink
fix(stages): Add missing stages from stage provider (#3968)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonsie committed Oct 15, 2020
1 parent 661094a commit 7208912
Showing 1 changed file with 36 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import com.netflix.spinnaker.orca.api.pipeline.graph.StageDefinitionBuilder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.Nonnull;
import org.slf4j.Logger;
Expand All @@ -44,40 +42,12 @@ public class DefaultStageResolver implements StageResolver {
public DefaultStageResolver(
ObjectProvider<Collection<StageDefinitionBuilder>> stageDefinitionBuildersProvider) {
this.stageDefinitionBuildersProvider = stageDefinitionBuildersProvider;
computeStageDefinitionBuilders();
}

/**
* Compute a cache of stage definition builders. A local map is first built and validated for
* duplicate stages and then copied to the thread safe cache.
*
* <p>This allows us to re-compute the stage definition builder cache if necessary (on a cache
* miss for example) and ensures the validation always runs correctly against the latest set of
* {@link StageDefinitionBuilder} classes.
*/
private void computeStageDefinitionBuilders() {
Collection<StageDefinitionBuilder> stageDefinitionBuilders =
stageDefinitionBuildersProvider.getIfAvailable(ArrayList::new);
Map<String, StageDefinitionBuilder> localStageDefinitionBuildersByAlias = new HashMap<>();

for (StageDefinitionBuilder stageDefinitionBuilder : stageDefinitionBuilders) {
localStageDefinitionBuildersByAlias.put(
stageDefinitionBuilder.getType(), stageDefinitionBuilder);
for (String alias : stageDefinitionBuilder.aliases()) {
if (localStageDefinitionBuildersByAlias.containsKey(alias)) {
throw new DuplicateStageAliasException(
format(
"Duplicate stage alias detected (alias: %s, previous: %s, current: %s)",
alias,
localStageDefinitionBuildersByAlias.get(alias).getClass().getCanonicalName(),
stageDefinitionBuilder.getClass().getCanonicalName()));
}

localStageDefinitionBuildersByAlias.put(alias, stageDefinitionBuilder);
}
stageDefinitionBuilderByAlias.put(stageDefinitionBuilder.getType(), stageDefinitionBuilder);
addAliases(stageDefinitionBuilder);
}

stageDefinitionBuilderByAlias.putAll(localStageDefinitionBuildersByAlias);
}

/**
Expand All @@ -95,9 +65,9 @@ public StageDefinitionBuilder getStageDefinitionBuilder(@Nonnull String type, St

if (stageDefinitionBuilder == null) {
log.debug(
"Stage definition builder for '{}' not found in initial stage definition builder cache, re-computing...",
"Stage definition builder for '{}' not found in initial stage definition builder cache, fetching missing stage from stage provider.",
type);
computeStageDefinitionBuilders();
addMissingStagesFromStageProvider();
stageDefinitionBuilder = getOrDefault(type, typeAlias);

if (stageDefinitionBuilder == null) {
Expand Down Expand Up @@ -125,4 +95,36 @@ private StageDefinitionBuilder getOrDefault(@Nonnull String type, String typeAli

return stageDefinitionBuilder;
}

/**
* Lookup stages from the stage provider and add missing stages to stageDefinitionBuilderByAlias
* cache.
*/
private void addMissingStagesFromStageProvider() {
for (StageDefinitionBuilder stageDefinitionBuilder :
stageDefinitionBuildersProvider.getIfAvailable(ArrayList::new)) {
if (stageDefinitionBuilderByAlias.get(stageDefinitionBuilder.getType()) == null) {
stageDefinitionBuilderByAlias.put(stageDefinitionBuilder.getType(), stageDefinitionBuilder);
addAliases(stageDefinitionBuilder);
log.info(
"{} stage resolved from stage provider and added to cache",
stageDefinitionBuilder.getType());
}
}
}

private void addAliases(StageDefinitionBuilder stageDefinitionBuilder) {
for (String alias : stageDefinitionBuilder.aliases()) {
if (stageDefinitionBuilderByAlias.containsKey(alias)) {
throw new DuplicateStageAliasException(
format(
"Duplicate stage alias detected (alias: %s, previous: %s, current: %s)",
alias,
stageDefinitionBuilderByAlias.get(alias).getClass().getCanonicalName(),
stageDefinitionBuilder.getClass().getCanonicalName()));
}

stageDefinitionBuilderByAlias.put(alias, stageDefinitionBuilder);
}
}
}

0 comments on commit 7208912

Please sign in to comment.