Skip to content

Commit 5d6e7c1

Browse files
committed
Show appropriate error message when specified agent status report page is not found
1 parent 7fd5bb3 commit 5d6e7c1

File tree

3 files changed

+109
-18
lines changed

3 files changed

+109
-18
lines changed

src/main/java/cd/go/contrib/elasticagent/executors/AgentStatusReportExecutor.java

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,30 @@ public GoPluginApiResponse execute() throws Exception {
4242
LOG.info(String.format("[status-report] Generating status report for agent: %s with job: %s", elasticAgentId, jobIdentifier));
4343
KubernetesClient client = factory.kubernetes(pluginRequest.getPluginSettings());
4444

45-
Pod pod;
46-
if (StringUtils.isNotBlank(elasticAgentId)) {
47-
pod = findPodUsingElasticAgentId(elasticAgentId, client);
48-
} else {
49-
pod = findPodUsingJobIdentifier(jobIdentifier, client);
50-
}
45+
try {
46+
Pod pod;
47+
if (StringUtils.isNotBlank(elasticAgentId)) {
48+
pod = findPodUsingElasticAgentId(elasticAgentId, client);
49+
} else {
50+
pod = findPodUsingJobIdentifier(jobIdentifier, client);
51+
}
5152

52-
KubernetesElasticAgent elasticAgent = KubernetesElasticAgent.fromPod(client, pod, elasticAgentId, jobIdentifier);
53+
KubernetesElasticAgent elasticAgent = KubernetesElasticAgent.fromPod(client, pod, elasticAgentId, jobIdentifier);
5354

54-
final Template template = statusReportViewBuilder.getTemplate("agent-status-report.template.ftlh");
55-
final String statusReportView = statusReportViewBuilder.build(template, elasticAgent);
55+
final String statusReportView = statusReportViewBuilder.build(statusReportViewBuilder.getTemplate("agent-status-report.template.ftlh"), elasticAgent);
5656

57-
JsonObject responseJSON = new JsonObject();
58-
responseJSON.addProperty("view", statusReportView);
57+
JsonObject responseJSON = new JsonObject();
58+
responseJSON.addProperty("view", statusReportView);
5959

60-
return DefaultGoPluginApiResponse.success(responseJSON.toString());
60+
return DefaultGoPluginApiResponse.success(responseJSON.toString());
61+
} catch (Exception e) {
62+
final String statusReportView = statusReportViewBuilder.build(statusReportViewBuilder.getTemplate("error.template.ftlh"), e);
63+
64+
JsonObject responseJSON = new JsonObject();
65+
responseJSON.addProperty("view", statusReportView);
66+
67+
return DefaultGoPluginApiResponse.success(responseJSON.toString());
68+
}
6169
}
6270

6371
private Pod findPodUsingJobIdentifier(JobIdentifier jobIdentifier, KubernetesClient client) {
@@ -66,8 +74,7 @@ private Pod findPodUsingJobIdentifier(JobIdentifier jobIdentifier, KubernetesCli
6674
.withLabel(Constants.JOB_ID_LABEL_KEY, String.valueOf(jobIdentifier.getJobId()))
6775
.list().getItems().get(0);
6876
} catch (Exception e) {
69-
//todo: returning null is evil.. how about showing a fancy not found page?
70-
return null;
77+
throw new RuntimeException(String.format("Can not find a running Pod for the provided job identifier '%s'", jobIdentifier));
7178
}
7279
}
7380

@@ -79,7 +86,6 @@ private Pod findPodUsingElasticAgentId(String elasticAgentId, KubernetesClient c
7986
}
8087
}
8188

82-
//todo: returning null is evil.. how about showing a fancy not found page?
83-
return null;
89+
throw new RuntimeException(String.format("Can not find a running Pod for the provided elastic agent id '%s'", elasticAgentId));
8490
}
8591
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<style>
2+
[data-plugin-style-id="kubernetes-plugin"] .outer-container {
3+
display: table;
4+
position: absolute;
5+
height: calc(100vh - 119px);
6+
width: 100%;
7+
}
8+
9+
[data-plugin-style-id="kubernetes-plugin"] .container {
10+
display: table-cell;
11+
vertical-align: middle;
12+
}
13+
14+
[data-plugin-style-id="kubernetes-plugin"] .message {
15+
margin-left: auto;
16+
margin-right: auto;
17+
18+
background: #FFF;
19+
padding: 20px;
20+
color: #991A00;
21+
font-size: large;
22+
text-align: center;
23+
vertical-align: middle;
24+
}
25+
</style>
26+
27+
<div data-plugin-style-id="kubernetes-plugin">
28+
<div class="outer-container">
29+
<div class="container">
30+
<div class="message">
31+
${ message! }
32+
</div>
33+
</div>
34+
</div>
35+
</div>

src/test/java/cd/go/contrib/elasticagent/executors/AgentStatusReportExecutorTest.java

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
import cd.go.contrib.elasticagent.PluginRequest;
66
import cd.go.contrib.elasticagent.PluginSettings;
77
import cd.go.contrib.elasticagent.builders.PluginStatusReportViewBuilder;
8+
import cd.go.contrib.elasticagent.model.JobIdentifier;
9+
import cd.go.contrib.elasticagent.model.reports.agent.KubernetesElasticAgent;
810
import cd.go.contrib.elasticagent.requests.AgentStatusReportRequest;
911
import com.thoughtworks.go.plugin.api.response.GoPluginApiResponse;
12+
import freemarker.template.Template;
1013
import io.fabric8.kubernetes.api.model.*;
1114
import io.fabric8.kubernetes.client.KubernetesClient;
1215
import io.fabric8.kubernetes.client.dsl.MixedOperation;
@@ -23,6 +26,7 @@
2326
import static org.hamcrest.Matchers.is;
2427
import static org.junit.Assert.assertThat;
2528
import static org.mockito.ArgumentMatchers.any;
29+
import static org.mockito.ArgumentMatchers.eq;
2630
import static org.mockito.Mockito.when;
2731
import static org.mockito.MockitoAnnotations.initMocks;
2832

@@ -68,6 +72,9 @@ public class AgentStatusReportExecutorTest {
6872
@Mock
6973
private PodResource<Pod, DoneablePod> podresource;
7074

75+
@Mock
76+
private Template template;
77+
7178
@Before
7279
public void setUp() throws Exception {
7380
initMocks(this);
@@ -91,7 +98,6 @@ public void setUp() throws Exception {
9198

9299
@Test
93100
public void shouldReturnAgentStatusReportBasedOnProvidedElasticAgentId() throws Exception {
94-
95101
when(statusReportRequest.getJobIdentifier()).thenReturn(null);
96102
when(statusReportRequest.getElasticAgentId()).thenReturn(elasticAgentId);
97103

@@ -100,14 +106,58 @@ public void shouldReturnAgentStatusReportBasedOnProvidedElasticAgentId() throws
100106
when(pluginRequest.getPluginSettings()).thenReturn(pluginSettings);
101107
when(kubernetesClientFactory.kubernetes(pluginSettings)).thenReturn(client);
102108

103-
when(builder.build(any(), any())).thenReturn("my-view");
109+
when(builder.getTemplate("agent-status-report.template.ftlh")).thenReturn(template);
110+
when(builder.build(eq(template), any(KubernetesElasticAgent.class))).thenReturn("my-view");
104111

105112
GoPluginApiResponse response = executor.execute();
106113

107114
assertThat(response.responseCode(), is(200));
108115
assertThat(response.responseBody(), is("{\"view\":\"my-view\"}"));
109116
}
110117

118+
@Test
119+
public void shouldReturnErrorWhenPodForSpecifiedElasticAgentIdNotFound() throws Exception {
120+
when(podList.getItems()).thenReturn(new ArrayList<>()); // no matching pod for the specified elastic agent id
121+
122+
when(statusReportRequest.getJobIdentifier()).thenReturn(null);
123+
when(statusReportRequest.getElasticAgentId()).thenReturn(elasticAgentId);
124+
125+
PluginSettings pluginSettings = new PluginSettings();
126+
127+
when(pluginRequest.getPluginSettings()).thenReturn(pluginSettings);
128+
when(kubernetesClientFactory.kubernetes(pluginSettings)).thenReturn(client);
129+
130+
when(builder.getTemplate("error.template.ftlh")).thenReturn(template);
131+
when(builder.build(eq(template), any(RuntimeException.class))).thenReturn("my-error-view");
132+
133+
GoPluginApiResponse response = executor.execute();
134+
135+
assertThat(response.responseCode(), is(200));
136+
assertThat(response.responseBody(), is("{\"view\":\"my-error-view\"}"));
137+
}
138+
139+
@Test
140+
public void shouldReturnErrorWhenPodForSpecifiedJobIdentifierNotFound() throws Exception {
141+
when(client.pods()).thenThrow(new RuntimeException("Boom!")); //can not find pod for specified job identitier
142+
143+
JobIdentifier jobIdentifier = new JobIdentifier("up42", 1L, "1", "up42_stage", "1", "job_name", 1L);
144+
when(statusReportRequest.getJobIdentifier()).thenReturn(jobIdentifier);
145+
when(statusReportRequest.getElasticAgentId()).thenReturn(null);
146+
147+
PluginSettings pluginSettings = new PluginSettings();
148+
149+
when(pluginRequest.getPluginSettings()).thenReturn(pluginSettings);
150+
when(kubernetesClientFactory.kubernetes(pluginSettings)).thenReturn(client);
151+
152+
when(builder.getTemplate("error.template.ftlh")).thenReturn(template);
153+
when(builder.build(eq(template), any(RuntimeException.class))).thenReturn("my-error-view");
154+
155+
GoPluginApiResponse response = executor.execute();
156+
157+
assertThat(response.responseCode(), is(200));
158+
assertThat(response.responseBody(), is("{\"view\":\"my-error-view\"}"));
159+
}
160+
111161
private Pod creatdDefaultPod() {
112162
Pod pod = new Pod();
113163
pod.setMetadata(new ObjectMeta());

0 commit comments

Comments
 (0)