-
Notifications
You must be signed in to change notification settings - Fork 807
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
refactor(deploymentmonitor): Configure SpinnakerRetrofitErrorHandler for DeploymentMonitorService #4614
base: master
Are you sure you want to change the base?
refactor(deploymentmonitor): Configure SpinnakerRetrofitErrorHandler for DeploymentMonitorService #4614
Changes from all commits
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 |
---|---|---|
|
@@ -16,18 +16,25 @@ | |
|
||
package com.netflix.spinnaker.orca.clouddriver.tasks.monitoreddeploy | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper | ||
import com.netflix.spectator.api.NoopRegistry | ||
import com.netflix.spinnaker.config.DeploymentMonitorDefinition | ||
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerHttpException | ||
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerServerException | ||
import com.netflix.spinnaker.orca.api.pipeline.models.ExecutionStatus | ||
import com.netflix.spinnaker.orca.api.pipeline.TaskResult | ||
import com.netflix.spinnaker.orca.clouddriver.MortServiceSpec | ||
import com.netflix.spinnaker.orca.deploymentmonitor.DeploymentMonitorService | ||
import com.netflix.spinnaker.orca.deploymentmonitor.models.DeploymentMonitorStageConfig | ||
import com.netflix.spinnaker.orca.deploymentmonitor.models.DeploymentStep | ||
import com.netflix.spinnaker.orca.deploymentmonitor.models.EvaluateHealthResponse | ||
import com.netflix.spinnaker.orca.deploymentmonitor.models.MonitoredDeployInternalStageData | ||
import com.netflix.spinnaker.orca.pipeline.model.PipelineExecutionImpl | ||
import com.netflix.spinnaker.orca.pipeline.model.StageExecutionImpl | ||
import org.springframework.http.HttpStatus | ||
import retrofit.RetrofitError | ||
import retrofit.client.Response | ||
import retrofit.converter.JacksonConverter | ||
import spock.lang.Specification | ||
import com.netflix.spinnaker.orca.deploymentmonitor.DeploymentMonitorServiceProvider | ||
import spock.lang.Unroll | ||
|
@@ -41,11 +48,11 @@ class EvaluateDeploymentHealthTaskSpec extends Specification { | |
PipelineExecutionImpl pipe = pipeline { | ||
} | ||
|
||
def "should retry retrofit errors"() { | ||
def "should retry on SpinnakerServerException"() { | ||
given: | ||
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. though underlying exceptions at present are retrofit, wouldn't it be meaningful to change "retrofit errors" to SpinnakerServerExceptions in the test name? 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. Thats true.. I have modified the test name to : should retry on SpinnakerServerException |
||
def monitorServiceStub = Stub(DeploymentMonitorService) { | ||
evaluateHealth(_) >> { | ||
throw RetrofitError.networkError("url", new IOException()) | ||
throw new SpinnakerServerException(RetrofitError.networkError("url", new IOException())) | ||
} | ||
} | ||
|
||
|
@@ -198,6 +205,49 @@ class EvaluateDeploymentHealthTaskSpec extends Specification { | |
false | null || ExecutionStatus.FAILED_CONTINUE | ||
} | ||
|
||
def "should return status as RUNNING when SpinnakerHttpException is thrown"() { | ||
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. Possible to add this test before the code change so we can see any change in behavior? 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. I think there is no change in the behaviour here. This test case is to verify if the execute() method returns status as RUNNING when SpinnakerHttpException is thrown. This was the same case even with RetrofitError as well. 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. Without having the test before the code change, it's hard to see that. 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. With reference to this comment : #4617 (comment) , moved this test case to a separate commit for a better understanding . |
||
def converter = new JacksonConverter(new ObjectMapper()) | ||
|
||
Response response = | ||
new Response( | ||
"/deployment/evaluateHealth", | ||
HttpStatus.BAD_REQUEST.value(), | ||
"bad-request", | ||
Collections.emptyList(), | ||
new MortServiceSpec.MockTypedInput(converter, [ | ||
accountName: "account", | ||
description: "simple description", | ||
name: "sg1", | ||
region: "region", | ||
type: "openstack" | ||
])) | ||
|
||
given: | ||
def monitorServiceStub = Stub(DeploymentMonitorService) { | ||
evaluateHealth(_) >> { | ||
throw new SpinnakerHttpException(RetrofitError.httpError("https://foo.com/deployment/evaluateHealth", response, converter, null)) | ||
} | ||
} | ||
|
||
def serviceProviderStub = getServiceProviderStub(monitorServiceStub) | ||
|
||
def task = new EvaluateDeploymentHealthTask(serviceProviderStub, new NoopRegistry()) | ||
|
||
MonitoredDeployInternalStageData stageData = new MonitoredDeployInternalStageData() | ||
stageData.deploymentMonitor = new DeploymentMonitorStageConfig() | ||
stageData.deploymentMonitor.id = "LogMonitorId" | ||
|
||
def stage = new StageExecutionImpl(pipe, "evaluateDeploymentHealth", stageData.toContextMap() + [application: pipe.application]) | ||
stage.startTime = Instant.now().toEpochMilli() | ||
|
||
when: 'we can still retry' | ||
TaskResult result = task.execute(stage) | ||
|
||
then: 'should retry' | ||
result.status == ExecutionStatus.RUNNING | ||
result.context.deployMonitorHttpRetryCount == 1 | ||
} | ||
|
||
private getServiceProviderStub(monitorServiceStub) { | ||
return getServiceProviderStub(monitorServiceStub, {}) | ||
} | ||
|
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 somehow nervous about including an empty body when there might not be one. If the response was present, but wasn't json, I'd like to make that clear somehow.
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.
Even before this PR, the code would still return empty body headers and status, in case of any parse/read failures.
If we are planning to change this behaviour, I think we have to add a test case before this modifications to demonstrate the behavioural change.
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.
This isn't about parse/read failures though. This is about a non-json response. We're guaranteed a behavior change here.
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.
A new specific exception handler is introduced to manage JsonProcessing during the serialization of the HTTP error body.
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 talking about something different. With SpinnakerHttpException, getResponseBody is null if the response isn't json whereas RetrofitError provided access to the response body in this case.
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.
Changes added : when the error response body is null, an appropriate error message will be printed in the logger.