Skip to content

Commit c33aca9

Browse files
Enhancements/blob clob query (#1483)
Add blob-id or clob-id query parameter, respectively, to all required methods, so ones with invalid path characters can be referenced. This is required for HydrologicEngineeringCenter/cwms-cli#72
1 parent 73796ac commit c33aca9

2 files changed

Lines changed: 171 additions & 121 deletions

File tree

cwms-data-api/src/main/java/cwms/cda/api/BlobController.java

Lines changed: 79 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -63,32 +63,32 @@ protected DSLContext getDslContext(Context ctx) {
6363
}
6464

6565
@OpenApi(
66-
queryParams = {
67-
@OpenApiParam(name = OFFICE,
68-
description = "Specifies the owning office. If this field is not "
69-
+ "specified, matching information from all offices shall be "
70-
+ "returned."),
71-
@OpenApiParam(name = PAGE,
72-
description = "This end point can return a lot of data, this "
73-
+ "identifies where in the request you are. This is an opaque"
74-
+ " value, and can be obtained from the 'next-page' value in "
75-
+ "the response."),
76-
@OpenApiParam(name = PAGE_SIZE,
77-
type = Integer.class,
78-
description = "How many entries per page returned. Default "
79-
+ DEFAULT_PAGE_SIZE + "."),
80-
@OpenApiParam(name = LIKE,
81-
description = "Posix <a href=\"regexp.html\">regular expression</a> "
82-
+ "describing the blob id's you want")
83-
},
84-
responses = {@OpenApiResponse(status = STATUS_200,
85-
description = "A list of blobs.",
86-
content = {
87-
@OpenApiContent(type = Formats.JSON, from = Blobs.class),
88-
@OpenApiContent(type = Formats.JSONV2, from = Blobs.class),
89-
})
90-
},
91-
tags = {TAG}
66+
queryParams = {
67+
@OpenApiParam(name = OFFICE,
68+
description = "Specifies the owning office. If this field is not "
69+
+ "specified, matching information from all offices shall be "
70+
+ "returned."),
71+
@OpenApiParam(name = PAGE,
72+
description = "This end point can return a lot of data, this "
73+
+ "identifies where in the request you are. This is an opaque"
74+
+ " value, and can be obtained from the 'next-page' value in "
75+
+ "the response."),
76+
@OpenApiParam(name = PAGE_SIZE,
77+
type = Integer.class,
78+
description = "How many entries per page returned. Default "
79+
+ DEFAULT_PAGE_SIZE + "."),
80+
@OpenApiParam(name = LIKE,
81+
description = "Posix <a href=\"regexp.html\">regular expression</a> "
82+
+ "describing the blob id's you want")
83+
},
84+
responses = {@OpenApiResponse(status = STATUS_200,
85+
description = "A list of blobs.",
86+
content = {
87+
@OpenApiContent(type = Formats.JSON, from = Blobs.class),
88+
@OpenApiContent(type = Formats.JSONV2, from = Blobs.class),
89+
})
90+
},
91+
tags = {TAG}
9292
)
9393
@Override
9494
public void getAll(@NotNull Context ctx) {
@@ -130,21 +130,31 @@ public void getAll(@NotNull Context ctx) {
130130
description = "Returns the binary value of the requested blob as a seekable stream with the "
131131
+ "appropriate media type.",
132132
queryParams = {
133-
@OpenApiParam(name = OFFICE, description = "Specifies the owning office."),
133+
@OpenApiParam(name = OFFICE, description = "Specifies the owning office."),
134+
@OpenApiParam(name = BLOB_ID, description = "If this _query_ parameter is provided the id _path_ parameter "
135+
+ "is ignored and the value of the query parameter is used. "
136+
+ "Note: this query parameter is necessary for id's that contain '/' or other special "
137+
+ "characters. This is due to limitations in path pattern matching. "
138+
+ "We will likely add support for encoding the ID in the path in the future. For now use the id field for those IDs. "
139+
+ "Client libraries should detect slashes and choose the appropriate field. \"ignored\" is suggested for the path endpoint."),
134140
},
135141
responses = {
136-
@OpenApiResponse(status = STATUS_200,
137-
description = "Returns requested blob.",
138-
content = {
139-
@OpenApiContent(type = "application/octet-stream")
140-
})
142+
@OpenApiResponse(status = STATUS_200,
143+
description = "Returns requested blob.",
144+
content = {
145+
@OpenApiContent(type = "application/octet-stream")
146+
})
141147
},
142148
tags = {TAG}
143149
)
144150
@Override
145151
public void getOne(@NotNull Context ctx, @NotNull String blobId) {
146152

147153
try (final Timer.Context ignored = markAndTime(GET_ONE)) {
154+
String idQueryParam = ctx.queryParam(CLOB_ID);
155+
if (idQueryParam != null) {
156+
blobId = idQueryParam;
157+
}
148158
DSLContext dsl = getDslContext(ctx);
149159
BlobDao dao = new BlobDao(dsl);
150160
String officeQP = ctx.queryParam(OFFICE);
@@ -175,13 +185,13 @@ public void getOne(@NotNull Context ctx, @NotNull String blobId) {
175185
@OpenApi(
176186
description = "Create new Blob",
177187
requestBody = @OpenApiRequestBody(
178-
content = {
179-
@OpenApiContent(from = Blob.class, type = Formats.JSONV2)
180-
},
181-
required = true),
188+
content = {
189+
@OpenApiContent(from = Blob.class, type = Formats.JSONV2)
190+
},
191+
required = true),
182192
queryParams = {
183-
@OpenApiParam(name = FAIL_IF_EXISTS, type = Boolean.class,
184-
description = "Create will fail if provided ID already exists. Default: true")
193+
@OpenApiParam(name = FAIL_IF_EXISTS, type = Boolean.class,
194+
description = "Create will fail if provided ID already exists. Default: true")
185195
},
186196
method = HttpMethod.POST,
187197
tags = {TAG}
@@ -203,20 +213,32 @@ public void create(@NotNull Context ctx) {
203213
@OpenApi(
204214
description = "Update an existing Blob",
205215
pathParams = {
206-
@OpenApiParam(name = BLOB_ID, description = "The blob identifier to be deleted"),
216+
@OpenApiParam(name = BLOB_ID, description = "The blob identifier to be deleted"),
207217
},
208218
requestBody = @OpenApiRequestBody(
209-
content = {
210-
@OpenApiContent(from = Blob.class, type = Formats.JSONV2),
211-
@OpenApiContent(from = Blob.class, type = Formats.JSON)
212-
},
213-
required = true),
219+
content = {
220+
@OpenApiContent(from = Blob.class, type = Formats.JSONV2),
221+
@OpenApiContent(from = Blob.class, type = Formats.JSON)
222+
},
223+
required = true),
224+
queryParams = {
225+
@OpenApiParam(name = BLOB_ID, description = "If this _query_ parameter is provided the id _path_ parameter "
226+
+ "is ignored and the value of the query parameter is used. "
227+
+ "Note: this query parameter is necessary for id's that contain '/' or other special "
228+
+ "characters. This is due to limitations in path pattern matching. "
229+
+ "We will likely add support for encoding the ID in the path in the future. For now use the id field for those IDs. "
230+
+ "Client libraries should detect slashes and choose the appropriate field. \"ignored\" is suggested for the path endpoint."),
231+
},
214232
method = HttpMethod.PATCH,
215233
tags = {TAG}
216234
)
217235
@Override
218236
public void update(@NotNull Context ctx, @NotNull String blobId) {
219237
try (final Timer.Context ignored = markAndTime(UPDATE)) {
238+
String idQueryParam = ctx.queryParam(CLOB_ID);
239+
if (idQueryParam != null) {
240+
blobId = idQueryParam;
241+
}
220242
DSLContext dsl = getDslContext(ctx);
221243

222244
String reqContentType = ctx.req.getContentType();
@@ -247,18 +269,28 @@ public void update(@NotNull Context ctx, @NotNull String blobId) {
247269
@OpenApi(
248270
description = "Deletes requested blob",
249271
pathParams = {
250-
@OpenApiParam(name = BLOB_ID, description = "The blob identifier to be deleted"),
272+
@OpenApiParam(name = BLOB_ID, description = "The blob identifier to be deleted"),
251273
},
252274
queryParams = {
253-
@OpenApiParam(name = OFFICE, required = true, description = "Specifies the "
254-
+ "owning office of the blob to be deleted"),
275+
@OpenApiParam(name = OFFICE, required = true, description = "Specifies the "
276+
+ "owning office of the blob to be deleted"),
277+
@OpenApiParam(name = BLOB_ID, description = "If this _query_ parameter is provided the id _path_ parameter "
278+
+ "is ignored and the value of the query parameter is used. "
279+
+ "Note: this query parameter is necessary for id's that contain '/' or other special "
280+
+ "characters. This is due to limitations in path pattern matching. "
281+
+ "We will likely add support for encoding the ID in the path in the future. For now use the id field for those IDs. "
282+
+ "Client libraries should detect slashes and choose the appropriate field. \"ignored\" is suggested for the path endpoint."),
255283
},
256284
method = HttpMethod.DELETE,
257285
tags = {TAG}
258286
)
259287
@Override
260288
public void delete(@NotNull Context ctx, @NotNull String blobId) {
261289
try (Timer.Context ignored = markAndTime(DELETE)) {
290+
String idQueryParam = ctx.queryParam(CLOB_ID);
291+
if (idQueryParam != null) {
292+
blobId = idQueryParam;
293+
}
262294
DSLContext dsl = getDslContext(ctx);
263295
String office = requiredParam(ctx, OFFICE);
264296
BlobDao dao = new BlobDao(dsl);

0 commit comments

Comments
 (0)