-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(plugins): filled in scaffolding #11
base: master
Are you sure you want to change the base?
Changes from 12 commits
cd4a3c2
5320954
0581af4
442e404
c0f6c4c
895a5c8
7d62393
f9ab27a
bc56a28
fde6cb6
c858bd4
a3aa65e
9c3c8f0
2aa3953
7fc46c2
00f5f88
8dd69f7
d525300
c752ffa
34ead88
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright 2019 Armory, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
apply from: "$rootDir/gradle/kotlin.gradle" | ||
apply from: "$rootDir/gradle/spock.gradle" | ||
|
||
test { | ||
useJUnitPlatform { | ||
includeEngines "junit-vintage", "junit-jupiter" | ||
} | ||
} | ||
|
||
dependencies { | ||
implementation("com.google.guava:guava") | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* Copyright 2019 Armory, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.netflix.spinnaker.orca.api; | ||
|
||
import com.google.common.annotations.Beta; | ||
|
||
@Beta | ||
public interface Stage<T> { | ||
<T> StageOutput execute(StageInput<T> stageInput); | ||
|
||
String getName(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Copyright 2019 Armory, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.netflix.spinnaker.orca.api; | ||
|
||
import com.google.common.annotations.Beta; | ||
|
||
@Beta | ||
public class StageInput<T> { | ||
private T value; | ||
|
||
public StageInput(T value) { | ||
this.value = value; | ||
} | ||
|
||
public void setValue(T value) { | ||
this.value = value; | ||
} | ||
|
||
public T getValue() { | ||
return this.value; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* Copyright 2019 Armory, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.netflix.spinnaker.orca.api; | ||
|
||
import com.google.common.annotations.Beta; | ||
import java.util.Map; | ||
|
||
@Beta | ||
public class StageOutput { | ||
private StageStatus status; | ||
|
||
public void setStatus(StageStatus status) { | ||
this.status = status; | ||
} | ||
|
||
public StageStatus getStatus() { | ||
return this.status; | ||
} | ||
|
||
private Map outputs; | ||
|
||
public void setOutputs(Map outputs) { | ||
this.outputs = outputs; | ||
} | ||
|
||
public Map getOutputs() { | ||
return this.outputs; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* Copyright 2019 Armory, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.netflix.spinnaker.orca.api; | ||
|
||
import com.google.common.annotations.Beta; | ||
|
||
@Beta | ||
public enum StageStatus { | ||
TERMINAL, | ||
RUNNING, | ||
COMPLETED, | ||
NOT_STARTED | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Copyright 2019 Armory, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.netflix.spinnaker.orca.pipeline; | ||
|
||
import com.netflix.spinnaker.orca.pipeline.model.Stage; | ||
import javax.annotation.Nonnull; | ||
|
||
public class ApiStageDefinitionBuilder implements StageDefinitionBuilder { | ||
private com.netflix.spinnaker.orca.api.Stage apiStage; | ||
|
||
public ApiStageDefinitionBuilder(com.netflix.spinnaker.orca.api.Stage apiStage) { | ||
this.apiStage = apiStage; | ||
} | ||
|
||
public void taskGraph(@Nonnull Stage stage, @Nonnull TaskNode.Builder builder) { | ||
ApiTask task = new ApiTask(apiStage); | ||
builder.withTask(apiStage.getName(), task.getClass()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* Copyright 2019 Armory, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.netflix.spinnaker.orca.pipeline; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.netflix.spinnaker.orca.ExecutionStatus; | ||
import com.netflix.spinnaker.orca.Task; | ||
import com.netflix.spinnaker.orca.TaskResult; | ||
import com.netflix.spinnaker.orca.api.StageInput; | ||
import com.netflix.spinnaker.orca.api.StageOutput; | ||
import com.netflix.spinnaker.orca.jackson.OrcaObjectMapper; | ||
import com.netflix.spinnaker.orca.pipeline.model.Stage; | ||
import java.lang.reflect.Method; | ||
import java.lang.reflect.Type; | ||
import java.lang.reflect.TypeVariable; | ||
import java.util.Map; | ||
import javax.annotation.Nonnull; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.core.GenericTypeResolver; | ||
import org.springframework.core.ResolvableType; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Slf4j | ||
@Component | ||
public class ApiTask implements Task { | ||
private com.netflix.spinnaker.orca.api.Stage apiStage; | ||
|
||
ApiTask(com.netflix.spinnaker.orca.api.Stage apiStage) { | ||
this.apiStage = apiStage; | ||
} | ||
|
||
@Nonnull | ||
public TaskResult execute(@Nonnull Stage stage) { | ||
ObjectMapper objectMapper = OrcaObjectMapper.newInstance(); | ||
|
||
ExecutionStatus status; | ||
try { | ||
Class[] cArg = new Class[1]; | ||
cArg[0] = StageInput.class; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can do |
||
Method method = apiStage.getClass().getMethod("execute", cArg); | ||
Type type = ResolvableType.forMethodParameter(method, 0).getGeneric().getType(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Small nit: imight be a bit more descriptive to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
Map<TypeVariable, Type> typeVariableMap = | ||
GenericTypeResolver.getTypeVariableMap(apiStage.getClass()); | ||
|
||
StageInput stageInput = | ||
new StageInput( | ||
objectMapper.convertValue( | ||
stage.getContext(), GenericTypeResolver.resolveType(type, typeVariableMap))); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, the idea here is that I can have a
and use it as my stage input like so
Is this correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One would create a new class like:
and then in their new stage do:
|
||
StageOutput outputs = apiStage.execute(stageInput); | ||
switch (outputs.getStatus()) { | ||
case TERMINAL: | ||
status = ExecutionStatus.TERMINAL; | ||
break; | ||
case RUNNING: | ||
status = ExecutionStatus.RUNNING; | ||
break; | ||
case COMPLETED: | ||
status = ExecutionStatus.SUCCEEDED; | ||
break; | ||
case NOT_STARTED: | ||
status = ExecutionStatus.NOT_STARTED; | ||
break; | ||
default: | ||
status = ExecutionStatus.FAILED_CONTINUE; | ||
break; | ||
} | ||
} catch (Exception e) { | ||
log.error("Cannot execute stage " + apiStage.getName()); | ||
log.error(e.getMessage()); | ||
status = ExecutionStatus.TERMINAL; | ||
} | ||
|
||
return TaskResult.ofStatus(status); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't we want to throw the outputs of the stage back into the context here? This would allow us to use any outputs from the stage in downstream stages.
|
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a fan of duplicated class name. It hurts readability and increases complexity by having to determine which type of Stage object you're working with.