Skip to content

Commit 711a6bd

Browse files
Siwei Zhangbhufmann
authored andcommitted
swagger: Fix specification for sampling in xy output
This was incorrectly specified and didn't match the implementation. Signed-off-by: Siwei Zhang <[email protected]>
1 parent 88b0297 commit 711a6bd

File tree

4 files changed

+93
-53
lines changed

4 files changed

+93
-53
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/webapp/SamplingSerializerTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,7 @@ public void testCategoriesRoundTrip() throws JsonProcessingException {
8282

8383
/**
8484
* Test round-trip serialization and deserialization for
85-
* {@link ISampling.Ranges}. The format is a 2D array of timestamp
86-
* ranges, i.e., {@code [[start, end], ...]}.
85+
* {@link ISampling.Ranges}. The format is an array of range json objects.
8786
*
8887
* @throws JsonProcessingException
8988
* if JSON processing fails
@@ -96,6 +95,6 @@ public void testTimeRangesRoundTrip() throws JsonProcessingException {
9695
new Range<>(3L, 4L)
9796
));
9897
String json = fMapper.writeValueAsString(original);
99-
assertEquals("[[1,2],[2,3],[3,4]]", json);
98+
assertEquals("[{\"start\":1,\"end\":2},{\"start\":2,\"end\":3},{\"start\":3,\"end\":4}]", json);
10099
}
101100
}

trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/src/org/eclipse/tracecompass/incubator/internal/trace/server/jersey/rest/core/model/Sampling.java

Lines changed: 54 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111

1212
package org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.model;
1313

14+
import io.swagger.v3.oas.annotations.media.ArraySchema;
1415
import io.swagger.v3.oas.annotations.media.Schema;
15-
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
1616

1717
import java.util.List;
1818

19+
import com.fasterxml.jackson.annotation.JsonValue;
20+
1921
/**
2022
* Describes alternative representations of sampling options.
21-
* Used for OpenAPI generation.
2223
*/
2324
@Schema(oneOf = {
2425
Sampling.TimestampSampling.class,
@@ -30,59 +31,67 @@ public interface Sampling {
3031
/**
3132
* Sampling as list of timestamps.
3233
*/
33-
public static class TimestampSampling {
34-
/**
35-
* The sampling points as timestamp values.
36-
*/
37-
@Schema(
38-
description = "Sampling as list of timestamps",
39-
requiredMode = RequiredMode.REQUIRED
40-
)
41-
public long[] sampling;
34+
@ArraySchema(
35+
arraySchema = @Schema(
36+
description = "Sampling as a flat list of timestamps. Example: [100, 200, 350]"
37+
),
38+
schema = @Schema(type = "integer", format = "int64")
39+
)
40+
class TimestampSampling implements Sampling {
41+
private final long[] timestamps;
42+
43+
public TimestampSampling(long[] timestamps) {
44+
this.timestamps = timestamps;
45+
}
46+
47+
@JsonValue
48+
public long[] getTimestamps() {
49+
return timestamps;
50+
}
4251
}
4352

4453
/**
4554
* Sampling as list of categories.
4655
*/
47-
public static class CategorySampling {
48-
/**
49-
* The sampling points as category names or labels.
50-
*/
51-
@Schema(
52-
description = "Sampling as list of categories",
53-
requiredMode = RequiredMode.REQUIRED
54-
)
55-
public String[] sampling;
56-
}
56+
@ArraySchema(
57+
arraySchema = @Schema(
58+
description = "Sampling as a flat list of categories. Example: [\"READ\", \"WRITE\"]"
59+
),
60+
schema = @Schema(type = "string")
61+
)
62+
class CategorySampling implements Sampling {
63+
private final String[] categories;
5764

58-
/**
59-
* Sampling as a list of [start, end] ranges.
60-
*/
61-
public static class RangeSampling {
62-
/**
63-
* The list of sampling ranges, each with a start and end value.
64-
*/
65-
@Schema(
66-
description = "Sampling as list of [start, end] timestamp ranges",
67-
requiredMode = RequiredMode.REQUIRED
68-
)
69-
public List<StartEndRange> sampling;
65+
public CategorySampling(String[] categories) {
66+
this.categories = categories;
67+
}
68+
69+
@JsonValue
70+
public String[] getCategories() {
71+
return categories;
72+
}
7073
}
7174

7275
/**
73-
* Represents a closed interval [start, end] for a sampling range.
76+
* Sampling as a list of start/end range objects.
7477
*/
75-
public static class StartEndRange {
76-
/**
77-
* Start timestamp of the range (inclusive).
78-
*/
79-
@Schema(description = "Start timestamp of the range", requiredMode = RequiredMode.REQUIRED)
80-
public long start;
78+
@ArraySchema(
79+
arraySchema = @Schema(
80+
description = "Sampling as a list of start/end range objects. Example: [{\"start\": 10, \"end\": 20}, {\"start\": 50, \"end\": 75}]"
81+
),
82+
// This will now correctly reference the StartEndRange object schema
83+
schema = @Schema(implementation = StartEndRange.class)
84+
)
85+
class RangeSampling implements Sampling {
86+
private final List<StartEndRange> ranges;
87+
88+
public RangeSampling(List<StartEndRange> ranges) {
89+
this.ranges = ranges;
90+
}
8191

82-
/**
83-
* End timestamp of the range (inclusive).
84-
*/
85-
@Schema(description = "End timestamp of the range", requiredMode = RequiredMode.REQUIRED)
86-
public long end;
92+
@JsonValue
93+
public List<StartEndRange> getRanges() {
94+
return ranges;
95+
}
8796
}
8897
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.model;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
5+
6+
/**
7+
* Represents a closed interval [start, end] for a sampling range.
8+
*/
9+
@Schema(
10+
name = "StartEndRange",
11+
description = "An object representing a closed interval with a start and end."
12+
)
13+
class StartEndRange {
14+
@Schema(description = "Start of the range (inclusive).", requiredMode = RequiredMode.REQUIRED)
15+
private final long start;
16+
17+
@Schema(description = "End of the range (inclusive).", requiredMode = RequiredMode.REQUIRED)
18+
private final long end;
19+
20+
public StartEndRange(long start, long end) {
21+
this.start = start;
22+
this.end = end;
23+
}
24+
25+
public long getStart() {
26+
return start;
27+
}
28+
29+
public long getEnd() {
30+
return end;
31+
}
32+
}

trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/src/org/eclipse/tracecompass/incubator/internal/trace/server/jersey/rest/core/webapp/SamplingSerializer.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
* Custom serializer for all Sampling subtypes.
2929
* - Timestamps → flat array: [1, 2, 3]
3030
* - Categories → array of strings: ["Read", "Write"]
31-
* - TimeRanges → array of arrays: [[1, 2], [2, 3]]
31+
* - Ranges → array of objects: [{"start": 1, "end": 2}, {"start": 2, "end": 3}]
3232
*/
3333
public class SamplingSerializer extends StdSerializer<ISampling> {
3434

@@ -56,10 +56,10 @@ public void serialize(ISampling value, JsonGenerator gen, SerializerProvider pro
5656
} else if (value instanceof Ranges timeRanges) {
5757
gen.writeStartArray();
5858
for (Range<@NonNull Long> range : timeRanges.ranges()) {
59-
gen.writeStartArray();
60-
gen.writeNumber(range.start());
61-
gen.writeNumber(range.end());
62-
gen.writeEndArray();
59+
gen.writeStartObject();
60+
gen.writeNumberField("start", range.start()); //$NON-NLS-1$
61+
gen.writeNumberField("end", range.end()); //$NON-NLS-1$
62+
gen.writeEndObject();
6363
}
6464
gen.writeEndArray();
6565
} else {

0 commit comments

Comments
 (0)