Skip to content

Commit 8f746a7

Browse files
committed
server: Introduce ErrorResponse and use it everywhere
When an error is created when processing a client request, return an ErrorResponse JSON object that includes the detailed error message. This standardizes the error response to common data structure. This commit also updates the swagger documentation accordingly. This commit fixes the swagger documentation for trace and experiment regarding error code 209 (conflict) and some missing definitions. Contributes to fix issue: eclipse-cdt-cloud/trace-server-protocol#122 Signed-off-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
1 parent 142809f commit 8f746a7

File tree

14 files changed

+357
-208
lines changed

14 files changed

+357
-208
lines changed

trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/services/DataProviderConfigurationServiceTest.java

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.DataProviderService;
3131
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.EndpointConstants;
32+
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.ErrorResponseImpl;
3233
import org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.stubs.DataProviderDescriptorStub;
3334
import org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.stubs.ExperimentModelStub;
3435
import org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.stubs.TestDataProviderFactory;
@@ -93,29 +94,29 @@ public void testDataProviderConfigTypesErrors() {
9394
try (Response response = configTypesEndpoint.request(MediaType.APPLICATION_JSON).get()) {
9495
assertNotNull(response);
9596
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
96-
assertEquals(EndpointConstants.NO_SUCH_TRACE, response.readEntity(String.class));
97+
assertEquals(EndpointConstants.NO_SUCH_TRACE, response.readEntity(ErrorResponseImpl.class).getMessage());
9798
}
9899

99100
WebTarget singleTypeEndpoint = configTypesEndpoint.path(TestSchemaConfigurationSource.TYPE.getId());
100101
try (Response response = singleTypeEndpoint.request(MediaType.APPLICATION_JSON).get()) {
101102
assertNotNull(response);
102103
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
103-
assertEquals(EndpointConstants.NO_SUCH_TRACE, response.readEntity(String.class));
104+
assertEquals(EndpointConstants.NO_SUCH_TRACE, response.readEntity(ErrorResponseImpl.class).getMessage());
104105
}
105106

106107
// Unknown data provider
107108
configTypesEndpoint = getConfigEndpoint(exp.getUUID().toString(), UNKNOWN_DP_ID);
108109
try (Response response = configTypesEndpoint.request(MediaType.APPLICATION_JSON).get()) {
109110
assertNotNull(response);
110111
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
111-
assertEquals(EndpointConstants.NO_SUCH_PROVIDER, response.readEntity(String.class));
112+
assertEquals(EndpointConstants.NO_SUCH_PROVIDER, response.readEntity(ErrorResponseImpl.class).getMessage());
112113
}
113114

114115
singleTypeEndpoint = configTypesEndpoint.path(TestSchemaConfigurationSource.TYPE.getId());
115116
try (Response response = singleTypeEndpoint.request(MediaType.APPLICATION_JSON).get()) {
116117
assertNotNull(response);
117118
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
118-
assertEquals(EndpointConstants.NO_SUCH_PROVIDER, response.readEntity(String.class));
119+
assertEquals(EndpointConstants.NO_SUCH_PROVIDER, response.readEntity(ErrorResponseImpl.class).getMessage());
119120
}
120121

121122
// Test config type is not applicable for another data provider
@@ -124,15 +125,15 @@ public void testDataProviderConfigTypesErrors() {
124125
try (Response response = singleTypeEndpoint.request(MediaType.APPLICATION_JSON).get()) {
125126
assertNotNull(response);
126127
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
127-
assertEquals(EndpointConstants.NO_SUCH_PROVIDER, response.readEntity(String.class));
128+
assertEquals(EndpointConstants.NO_SUCH_PROVIDER, response.readEntity(ErrorResponseImpl.class).getMessage());
128129
}
129130

130131
configTypesEndpoint = getConfigEndpoint(exp.getUUID().toString(), TestDataProviderFactory.ID);
131132
singleTypeEndpoint = configTypesEndpoint.path(UNKNOWN_TYPE_ID);
132133
try (Response response = singleTypeEndpoint.request(MediaType.APPLICATION_JSON).get()) {
133134
assertNotNull(response);
134135
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
135-
assertEquals(EndpointConstants.NO_SUCH_CONFIGURATION_TYPE, response.readEntity(String.class));
136+
assertEquals(EndpointConstants.NO_SUCH_CONFIGURATION_TYPE, response.readEntity(ErrorResponseImpl.class).getMessage());
136137
}
137138
}
138139

@@ -194,21 +195,21 @@ public void testCreationOfDerivedDataProvidersErrors() throws IOException, URISy
194195
// Unknown experiment
195196
try (Response response = assertDpPostWithErrors(dpCreationEndpoint, configuration)) {
196197
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
197-
assertEquals(EndpointConstants.NO_SUCH_TRACE, response.readEntity(String.class));
198+
assertEquals(EndpointConstants.NO_SUCH_TRACE, response.readEntity(ErrorResponseImpl.class).getMessage());
198199
}
199200

200201
// Unknown data provider
201202
dpCreationEndpoint = getDpCreationEndpoint(exp.getUUID().toString(), UNKNOWN_DP_ID);
202203
try (Response response = assertDpPostWithErrors(dpCreationEndpoint, configuration)) {
203204
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
204-
assertEquals(EndpointConstants.NO_SUCH_PROVIDER + ": " + UNKNOWN_DP_ID, response.readEntity(String.class));
205+
assertEquals(EndpointConstants.NO_SUCH_PROVIDER + ": " + UNKNOWN_DP_ID, response.readEntity(ErrorResponseImpl.class).getMessage());
205206
}
206207

207208
// Test config type is not applicable for another data provider
208209
dpCreationEndpoint = getDpCreationEndpoint(exp.getUUID().toString(), CALL_STACK_DATAPROVIDER_ID);
209210
try (Response response = assertDpPostWithErrors(dpCreationEndpoint, configuration)) {
210211
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
211-
assertEquals(EndpointConstants.NO_SUCH_PROVIDER, response.readEntity(String.class));
212+
assertEquals(EndpointConstants.NO_SUCH_PROVIDER, response.readEntity(ErrorResponseImpl.class).getMessage());
212213
}
213214

214215
// Invalid config type ID
@@ -222,7 +223,7 @@ public void testCreationOfDerivedDataProvidersErrors() throws IOException, URISy
222223
configuration = builder.build();
223224
try (Response response = assertDpPostWithErrors(dpCreationEndpoint, configuration)) {
224225
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
225-
assertEquals(EndpointConstants.NO_SUCH_CONFIGURATION_TYPE, response.readEntity(String.class));
226+
assertEquals(EndpointConstants.NO_SUCH_CONFIGURATION_TYPE, response.readEntity(ErrorResponseImpl.class).getMessage());
226227
}
227228
}
228229

@@ -244,7 +245,7 @@ public void testDeletionOfDerivedDataProvidersErrors() throws IOException, URISy
244245
try (Response response = dpDeletionEndpoint.request().delete()) {
245246
assertNotNull(response);
246247
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
247-
assertEquals(EndpointConstants.NO_SUCH_TRACE, response.readEntity(String.class));
248+
assertEquals(EndpointConstants.NO_SUCH_TRACE, response.readEntity(ErrorResponseImpl.class).getMessage());
248249
}
249250

250251
// Unknown input data provider
@@ -253,7 +254,7 @@ public void testDeletionOfDerivedDataProvidersErrors() throws IOException, URISy
253254
try (Response response = dpDeletionEndpoint.request().delete()) {
254255
assertNotNull(response);
255256
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
256-
assertEquals(EndpointConstants.NO_SUCH_PROVIDER + ": " + UNKNOWN_DP_ID, response.readEntity(String.class));
257+
assertEquals(EndpointConstants.NO_SUCH_PROVIDER + ": " + UNKNOWN_DP_ID, response.readEntity(ErrorResponseImpl.class).getMessage());
257258
}
258259

259260
// Unknown derived data provider
@@ -262,7 +263,7 @@ public void testDeletionOfDerivedDataProvidersErrors() throws IOException, URISy
262263
try (Response response = dpDeletionEndpoint.request().delete()) {
263264
assertNotNull(response);
264265
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
265-
assertEquals(EndpointConstants.NO_SUCH_DERIVED_PROVIDER + ": " + UNKNOWN_DP_ID, response.readEntity(String.class));
266+
assertEquals(EndpointConstants.NO_SUCH_DERIVED_PROVIDER + ": " + UNKNOWN_DP_ID, response.readEntity(ErrorResponseImpl.class).getMessage());
266267
}
267268

268269
Map<String, Object> params = readParametersFromJson(VALID_JSON_FILENAME);
@@ -283,7 +284,7 @@ public void testDeletionOfDerivedDataProvidersErrors() throws IOException, URISy
283284
try (Response response = dpDeletionEndpoint.request().delete()) {
284285
assertNotNull(response);
285286
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
286-
assertEquals(EndpointConstants.NO_SUCH_PROVIDER, response.readEntity(String.class));
287+
assertEquals(EndpointConstants.NO_SUCH_PROVIDER, response.readEntity(ErrorResponseImpl.class).getMessage());
287288
}
288289

289290
// Successful deletion

trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/services/TimeGraphDataProviderServiceTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.model.views.QueryParameters;
4343
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.DataProviderService;
4444
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.EndpointConstants;
45+
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.ErrorResponseImpl;
4546
import org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.stubs.AnnotationCategoriesOutputResponseStub;
4647
import org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.stubs.AnnotationModelStub;
4748
import org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.stubs.AnnotationResponseStub;
@@ -283,15 +284,15 @@ public void testAnnotationCategoriesErrors() {
283284
try (Response response = endpoint.request(MediaType.APPLICATION_JSON).get()) {
284285
assertNotNull(response);
285286
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
286-
assertEquals(EndpointConstants.NO_SUCH_TRACE, response.readEntity(String.class));
287+
assertEquals(EndpointConstants.NO_SUCH_TRACE, response.readEntity(ErrorResponseImpl.class).getMessage());
287288
}
288289

289290
// Unknown data provider
290291
endpoint = getAnnotationCategoriesEndpoint(exp.getUUID().toString(), UNKNOWN_DP_ID);
291292
try (Response response = endpoint.request(MediaType.APPLICATION_JSON).get()) {
292293
assertNotNull(response);
293294
assertEquals(Status.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatus());
294-
assertEquals(EndpointConstants.NO_PROVIDER, response.readEntity(String.class));
295+
assertEquals(EndpointConstants.NO_PROVIDER, response.readEntity(ErrorResponseImpl.class).getMessage());
295296
}
296297
}
297298

trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/services/TraceManagerServiceTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717

1818
import java.io.IOException;
1919
import java.util.Collections;
20+
import java.util.HashMap;
21+
import java.util.Map;
2022

23+
import javax.ws.rs.client.Entity;
2124
import javax.ws.rs.client.WebTarget;
2225
import javax.ws.rs.core.MediaType;
2326
import javax.ws.rs.core.Response;
@@ -31,6 +34,8 @@
3134
import org.eclipse.core.runtime.FileLocator;
3235
import org.eclipse.core.runtime.IPath;
3336
import org.eclipse.core.runtime.Path;
37+
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.model.views.QueryParameters;
38+
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.ErrorResponseImpl;
3439
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.TraceManagerService;
3540
import org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.stubs.TraceModelStub;
3641
import org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.utils.RestServerTest;
@@ -161,4 +166,22 @@ public void testWorkspaceStructure() throws CoreException, IOException {
161166
// Verify that the trace type is the kernel trace type
162167
assertEquals("org.eclipse.linuxtools.lttng2.kernel.tracetype", traceType);
163168
}
169+
170+
/**
171+
* Test error case if trace does not exist
172+
*/
173+
@Test
174+
public void testTraceNotExist() {
175+
WebTarget traces = getApplicationEndpoint().path(TRACES);
176+
Map<String, Object> parameters = new HashMap<>();
177+
parameters.put(NAME, "trace-does-not-exist");
178+
parameters.put(URI, "/path/does/not/exist");
179+
try (Response response = traces.request().post(Entity.json(new QueryParameters(parameters , Collections.emptyList())))) {
180+
int code = response.getStatus();
181+
assertEquals("Post trace should fail", 404, code);
182+
ErrorResponseImpl result = response.readEntity(ErrorResponseImpl.class);
183+
assertNotNull(result);
184+
assertNotNull(result.getMessage());
185+
}
186+
}
164187
}

trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/utils/RestServerTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.model.views.OutputConfigurationQueryParameters;
4646
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.model.views.QueryParameters;
4747
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.EndpointConstants;
48+
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.ErrorResponseImpl;
4849
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.webapp.TraceServerConfiguration;
4950
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.webapp.WebApplication;
5051
import org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.stubs.DataProviderDescriptorStub;
@@ -908,7 +909,7 @@ protected static void executePostErrorTests (ExperimentModelStub exp, IEndpointR
908909
try (Response response = endpoint.request().post(Entity.json(new QueryParameters(parameters, Collections.emptyList())))) {
909910
assertNotNull(response);
910911
assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
911-
assertEquals(EndpointConstants.NO_SUCH_TRACE, response.readEntity(String.class));
912+
assertEquals(EndpointConstants.NO_SUCH_TRACE, response.readEntity(ErrorResponseImpl.class).getMessage());
912913
}
913914

914915
// Missing parameters
@@ -932,7 +933,7 @@ protected static void executePostErrorTests (ExperimentModelStub exp, IEndpointR
932933
try (Response response = endpoint.request().post(Entity.json(new QueryParameters(parameters, Collections.emptyList())))) {
933934
assertNotNull(response);
934935
assertEquals(Status.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatus());
935-
assertEquals(EndpointConstants.NO_PROVIDER, response.readEntity(String.class));
936+
assertEquals(EndpointConstants.NO_PROVIDER, response.readEntity(ErrorResponseImpl.class).getMessage());
936937
}
937938
}
938939
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**********************************************************************
2+
* Copyright (c) 2025 Ericsson
3+
*
4+
* All rights reserved. This program and the accompanying materials are
5+
* made available under the terms of the Eclipse Public License 2.0 which
6+
* accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
**********************************************************************/
11+
12+
package org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.model;
13+
14+
import io.swagger.v3.oas.annotations.media.Schema;
15+
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
16+
17+
/**
18+
* Contributes to the model used for TSP swagger-core annotations.
19+
*/
20+
@Schema(description = "Error response that includes an detailed description of the error occured")
21+
public interface ErrorResponse {
22+
23+
/**
24+
* @return The error message.
25+
*/
26+
@Schema( requiredMode = RequiredMode.REQUIRED, description = "The detailed error message of the error")
27+
String getMessage();
28+
}

0 commit comments

Comments
 (0)