Skip to content

Commit 70ab71e

Browse files
aklishAaron Klish
andauthored
Elide 5- Unify request ids (#1423)
* Unified request ID for elide 5 * Fixing issues * Fixed some tests * Fixed build * Removed Data Store Transaction changes for request ID * Inspection rework Co-authored-by: Aaron Klish <[email protected]>
1 parent 99bef6f commit 70ab71e

File tree

39 files changed

+170
-121
lines changed

39 files changed

+170
-121
lines changed

elide-async/src/main/java/com/yahoo/elide/async/models/AsyncQuery.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ public class AsyncQuery extends AsyncBase implements PrincipalOwned {
5454
@ComputedAttribute
5555
private Integer asyncAfterSeconds = 10;
5656

57-
private String requestId; //Client provided
57+
@Exclude
58+
private String requestId = UUID.randomUUID().toString();
5859

5960
@UpdatePermission(expression = "Principal is Owner AND value is Cancelled")
6061
@CreatePermission(expression = "value is Queued")

elide-async/src/main/java/com/yahoo/elide/async/service/AsyncQueryThread.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import java.net.URISyntaxException;
2525
import java.util.Date;
26+
import java.util.UUID;
2627
import java.util.concurrent.Callable;
2728

2829
import javax.ws.rs.core.MultivaluedHashMap;
@@ -70,18 +71,19 @@ public AsyncQueryThread(AsyncQuery queryObj, User user, Elide elide, QueryRunner
7071
* @throws NoHttpResponseException
7172
*/
7273
protected AsyncQueryResult processQuery() throws URISyntaxException, NoHttpResponseException {
74+
UUID requestId = UUID.fromString(queryObj.getRequestId());
7375

7476
ElideResponse response = null;
7577
log.debug("AsyncQuery Object from request: {}", queryObj);
7678
if (queryObj.getQueryType().equals(QueryType.JSONAPI_V1_0)) {
7779
MultivaluedMap<String, String> queryParams = getQueryParams(queryObj.getQuery());
7880
log.debug("Extracted QueryParams from AsyncQuery Object: {}", queryParams);
79-
response = elide.get(getPath(queryObj.getQuery()), queryParams, user, apiVersion);
81+
response = elide.get(getPath(queryObj.getQuery()), queryParams, user, apiVersion, requestId);
8082
log.debug("JSONAPI_V1_0 getResponseCode: {}, JSONAPI_V1_0 getBody: {}",
8183
response.getResponseCode(), response.getBody());
8284
}
8385
else if (queryObj.getQueryType().equals(QueryType.GRAPHQL_V1_0)) {
84-
response = runner.run(queryObj.getQuery(), user);
86+
response = runner.run(queryObj.getQuery(), user, requestId);
8587
log.debug("GRAPHQL_V1_0 getResponseCode: {}, GRAPHQL_V1_0 getBody: {}",
8688
response.getResponseCode(), response.getBody());
8789
}

elide-async/src/main/java/com/yahoo/elide/async/service/DefaultAsyncQueryDAO.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.io.IOException;
2929
import java.util.Collection;
3030
import java.util.Iterator;
31+
import java.util.UUID;
3132

3233
import javax.inject.Singleton;
3334
import javax.ws.rs.core.MultivaluedHashMap;
@@ -184,7 +185,7 @@ protected Object executeInTransaction(DataStore dataStore, Transactional action)
184185
JsonApiDocument jsonApiDoc = new JsonApiDocument();
185186
MultivaluedMap<String, String> queryParams = new MultivaluedHashMap<String, String>();
186187
RequestScope scope = new RequestScope("query", NO_VERSION, jsonApiDoc,
187-
tx, null, queryParams, elide.getElideSettings());
188+
tx, null, queryParams, UUID.randomUUID(), elide.getElideSettings());
188189
result = action.execute(tx, scope);
189190
tx.flush(scope);
190191
tx.commit(scope);

elide-async/src/test/java/com/yahoo/elide/async/service/AsyncExecutorServiceTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ public void testExecuteQueryComplete() throws InterruptedException {
8787
String id = "edc4a871-dff2-4054-804e-d80075cf827d";
8888
when(queryObj.getQuery()).thenReturn(query);
8989
when(queryObj.getId()).thenReturn(id);
90+
when(queryObj.getRequestId()).thenReturn(id);
9091
when(queryObj.getQueryType()).thenReturn(QueryType.JSONAPI_V1_0);
9192
when(queryObj.getAsyncAfterSeconds()).thenReturn(10);
9293
service.executeQuery(queryObj, testUser, NO_VERSION);

elide-async/src/test/java/com/yahoo/elide/async/service/AsyncQueryThreadTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import static org.junit.jupiter.api.Assertions.assertEquals;
99
import static org.mockito.ArgumentMatchers.any;
1010
import static org.mockito.ArgumentMatchers.anyString;
11+
import static org.mockito.ArgumentMatchers.eq;
1112
import static org.mockito.Mockito.mock;
1213
import static org.mockito.Mockito.when;
1314

@@ -52,7 +53,7 @@ public void testProcessQueryJsonApi() throws NoHttpResponseException, URISyntaxE
5253
queryObj.setId(id);
5354
queryObj.setQuery(query);
5455
queryObj.setQueryType(QueryType.JSONAPI_V1_0);
55-
when(elide.get(anyString(), any(), any(), anyString())).thenReturn(response);
56+
when(elide.get(anyString(), any(), any(), anyString(), any())).thenReturn(response);
5657
AsyncQueryThread queryThread = new AsyncQueryThread(queryObj, user, elide, runner, asyncQueryDao, "v1");
5758
queryResultObj = queryThread.processQuery();
5859
assertEquals(queryResultObj.getResponseBody(), "ResponseBody");
@@ -68,7 +69,7 @@ public void testProcessQueryGraphQl() throws NoHttpResponseException, URISyntaxE
6869
queryObj.setId(id);
6970
queryObj.setQuery(query);
7071
queryObj.setQueryType(QueryType.GRAPHQL_V1_0);
71-
when(runner.run(query, user)).thenReturn(response);
72+
when(runner.run(eq(query), eq(user), any())).thenReturn(response);
7273
AsyncQueryThread queryThread = new AsyncQueryThread(queryObj, user, elide, runner, asyncQueryDao, "v1");
7374
queryResultObj = queryThread.processQuery();
7475
assertEquals(queryResultObj.getResponseBody(), "ResponseBody");

elide-core/src/main/java/com/yahoo/elide/Elide.java

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -165,16 +165,30 @@ protected Set<Class<?>> registerCustomSerdeScan() {
165165
*/
166166
public ElideResponse get(String path, MultivaluedMap<String, String> queryParams,
167167
User opaqueUser, String apiVersion) {
168-
return handleRequest(true, opaqueUser, dataStore::beginReadTransaction, (tx, user) -> {
168+
return get(path, queryParams, opaqueUser, apiVersion, UUID.randomUUID());
169+
}
170+
171+
/**
172+
* Handle GET.
173+
*
174+
* @param path the path
175+
* @param queryParams the query params
176+
* @param opaqueUser the opaque user
177+
* @param apiVersion the API version
178+
* @param requestId the request ID
179+
* @return Elide response object
180+
*/
181+
public ElideResponse get(String path, MultivaluedMap<String, String> queryParams,
182+
User opaqueUser, String apiVersion, UUID requestId) {
183+
return handleRequest(true, opaqueUser, dataStore::beginReadTransaction, requestId, (tx, user) -> {
169184
JsonApiDocument jsonApiDoc = new JsonApiDocument();
170185
RequestScope requestScope = new RequestScope(path, apiVersion, jsonApiDoc,
171-
tx, user, queryParams, elideSettings);
186+
tx, user, queryParams, requestId, elideSettings);
172187
requestScope.setEntityProjection(new EntityProjectionMaker(elideSettings.getDictionary(),
173188
requestScope).parsePath(path));
174189
BaseVisitor visitor = new GetVisitor(requestScope);
175190
return visit(path, requestScope, visitor);
176191
});
177-
178192
}
179193

180194
/**
@@ -183,13 +197,28 @@ public ElideResponse get(String path, MultivaluedMap<String, String> queryParams
183197
* @param path the path
184198
* @param jsonApiDocument the json api document
185199
* @param opaqueUser the opaque user
200+
* @param apiVersion the API version
186201
* @return Elide response object
187202
*/
188203
public ElideResponse post(String path, String jsonApiDocument, User opaqueUser, String apiVersion) {
189-
return handleRequest(false, opaqueUser, dataStore::beginTransaction, (tx, user) -> {
204+
return post(path, jsonApiDocument, opaqueUser, apiVersion, UUID.randomUUID());
205+
}
206+
207+
/**
208+
* Handle POST.
209+
*
210+
* @param path the path
211+
* @param jsonApiDocument the json api document
212+
* @param opaqueUser the opaque user
213+
* @param apiVersion the API version
214+
* @param requestId the request ID
215+
* @return Elide response object
216+
*/
217+
public ElideResponse post(String path, String jsonApiDocument, User opaqueUser, String apiVersion, UUID requestId) {
218+
return handleRequest(false, opaqueUser, dataStore::beginTransaction, requestId, (tx, user) -> {
190219
JsonApiDocument jsonApiDoc = mapper.readJsonApiDocument(jsonApiDocument);
191220
RequestScope requestScope = new RequestScope(path, apiVersion,
192-
jsonApiDoc, tx, user, null, elideSettings);
221+
jsonApiDoc, tx, user, null, requestId, elideSettings);
193222
requestScope.setEntityProjection(new EntityProjectionMaker(elideSettings.getDictionary(),
194223
requestScope).parsePath(path));
195224
BaseVisitor visitor = new PostVisitor(requestScope);
@@ -205,15 +234,36 @@ public ElideResponse post(String path, String jsonApiDocument, User opaqueUser,
205234
* @param path the path
206235
* @param jsonApiDocument the json api document
207236
* @param opaqueUser the opaque user
237+
* @param apiVersion the API version
238+
* @return Elide response object
239+
*/
240+
public ElideResponse patch(String contentType, String accept,
241+
String path, String jsonApiDocument,
242+
User opaqueUser, String apiVersion) {
243+
return patch(contentType, accept, path, jsonApiDocument, opaqueUser, apiVersion, UUID.randomUUID());
244+
}
245+
246+
/**
247+
* Handle PATCH.
248+
*
249+
* @param contentType the content type
250+
* @param accept the accept
251+
* @param path the path
252+
* @param jsonApiDocument the json api document
253+
* @param opaqueUser the opaque user
254+
* @param apiVersion the API version
255+
* @param requestId the request ID
208256
* @return Elide response object
209257
*/
210258
public ElideResponse patch(String contentType, String accept,
211-
String path, String jsonApiDocument, User opaqueUser, String apiVersion) {
259+
String path, String jsonApiDocument,
260+
User opaqueUser, String apiVersion, UUID requestId) {
212261

213262
Handler<DataStoreTransaction, User, HandlerResult> handler;
214263
if (JsonApiPatch.isPatchExtension(contentType) && JsonApiPatch.isPatchExtension(accept)) {
215264
handler = (tx, user) -> {
216-
PatchRequestScope requestScope = new PatchRequestScope(path, apiVersion, tx, user, elideSettings);
265+
PatchRequestScope requestScope = new PatchRequestScope(path, apiVersion, tx,
266+
user, requestId, elideSettings);
217267
try {
218268
Supplier<Pair<Integer, JsonNode>> responder =
219269
JsonApiPatch.processJsonPatch(dataStore, path, jsonApiDocument, requestScope);
@@ -226,15 +276,29 @@ public ElideResponse patch(String contentType, String accept,
226276
handler = (tx, user) -> {
227277
JsonApiDocument jsonApiDoc = mapper.readJsonApiDocument(jsonApiDocument);
228278
RequestScope requestScope = new RequestScope(path, apiVersion, jsonApiDoc,
229-
tx, user, null, elideSettings);
279+
tx, user, null, requestId, elideSettings);
230280
requestScope.setEntityProjection(new EntityProjectionMaker(elideSettings.getDictionary(),
231281
requestScope).parsePath(path));
232282
BaseVisitor visitor = new PatchVisitor(requestScope);
233283
return visit(path, requestScope, visitor);
234284
};
235285
}
236286

237-
return handleRequest(false, opaqueUser, dataStore::beginTransaction, handler);
287+
return handleRequest(false, opaqueUser, dataStore::beginTransaction, requestId, handler);
288+
}
289+
290+
/**
291+
* Handle DELETE.
292+
*
293+
* @param path the path
294+
* @param jsonApiDocument the json api document
295+
* @param opaqueUser the opaque user
296+
* @param apiVersion the API version
297+
* @return Elide response object
298+
*/
299+
public ElideResponse delete(String path, String jsonApiDocument,
300+
User opaqueUser, String apiVersion) {
301+
return delete(path, jsonApiDocument, opaqueUser, apiVersion, UUID.randomUUID());
238302
}
239303

240304
/**
@@ -243,15 +307,18 @@ public ElideResponse patch(String contentType, String accept,
243307
* @param path the path
244308
* @param jsonApiDocument the json api document
245309
* @param opaqueUser the opaque user
310+
* @param apiVersion the API version
311+
* @param requestId the request ID
246312
* @return Elide response object
247313
*/
248-
public ElideResponse delete(String path, String jsonApiDocument, User opaqueUser, String apiVersion) {
249-
return handleRequest(false, opaqueUser, dataStore::beginTransaction, (tx, user) -> {
314+
public ElideResponse delete(String path, String jsonApiDocument,
315+
User opaqueUser, String apiVersion, UUID requestId) {
316+
return handleRequest(false, opaqueUser, dataStore::beginTransaction, requestId, (tx, user) -> {
250317
JsonApiDocument jsonApiDoc = StringUtils.isEmpty(jsonApiDocument)
251318
? new JsonApiDocument()
252319
: mapper.readJsonApiDocument(jsonApiDocument);
253320
RequestScope requestScope = new RequestScope(path, apiVersion, jsonApiDoc,
254-
tx, user, null, elideSettings);
321+
tx, user, null, requestId, elideSettings);
255322
requestScope.setEntityProjection(new EntityProjectionMaker(elideSettings.getDictionary(),
256323
requestScope).parsePath(path));
257324
BaseVisitor visitor = new DeleteVisitor(requestScope);
@@ -274,16 +341,15 @@ public HandlerResult visit(String path, RequestScope requestScope, BaseVisitor v
274341
* @param isReadOnly if the transaction is read only
275342
* @param user the user object from the container
276343
* @param transaction a transaction supplier
344+
* @param requestId the Request ID
277345
* @param handler a function that creates the request scope and request handler
278346
* @return the response
279347
*/
280348
protected ElideResponse handleRequest(boolean isReadOnly, User user,
281-
Supplier<DataStoreTransaction> transaction,
349+
Supplier<DataStoreTransaction> transaction, UUID requestId,
282350
Handler<DataStoreTransaction, User, HandlerResult> handler) {
283351
boolean isVerbose = false;
284-
UUID requestId = null;
285352
try (DataStoreTransaction tx = transaction.get()) {
286-
requestId = tx.getRequestId();
287353
transactionRegistry.addRunningTransaction(requestId, tx);
288354
HandlerResult result = handler.handle(tx, user);
289355
RequestScope requestScope = result.getRequestScope();
@@ -313,29 +379,23 @@ protected ElideResponse handleRequest(boolean isReadOnly, User user,
313379

314380
} catch (WebApplicationException e) {
315381
throw e;
316-
317382
} catch (ForbiddenAccessException e) {
318383
if (log.isDebugEnabled()) {
319384
log.debug("{}", e.getLoggedMessage());
320385
}
321386
return buildErrorResponse(e, isVerbose);
322-
323387
} catch (JsonPatchExtensionException e) {
324388
log.debug("JSON patch extension exception caught", e);
325389
return buildErrorResponse(e, isVerbose);
326-
327390
} catch (HttpStatusException e) {
328391
log.debug("Caught HTTP status exception", e);
329392
return buildErrorResponse(e, isVerbose);
330-
331393
} catch (IOException e) {
332394
log.error("IO Exception uncaught by Elide", e);
333395
return buildErrorResponse(new TransactionException(e), isVerbose);
334-
335396
} catch (ParseCancellationException e) {
336397
log.debug("Parse cancellation exception uncaught by Elide (i.e. invalid URL)", e);
337398
return buildErrorResponse(new InvalidURLException(e), isVerbose);
338-
339399
} catch (ConstraintViolationException e) {
340400
log.debug("Constraint violation exception caught", e);
341401
String message = "Constraint violation";
@@ -351,7 +411,6 @@ protected ElideResponse handleRequest(boolean isReadOnly, User user,
351411
}
352412
log.error("Error or exception uncaught by Elide", e);
353413
throw e;
354-
355414
} finally {
356415
transactionRegistry.removeRunningTransaction(requestId);
357416
auditLogger.clear();

elide-core/src/main/java/com/yahoo/elide/core/DataStoreTransaction.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import java.io.Serializable;
1818
import java.util.Iterator;
1919
import java.util.Set;
20-
import java.util.UUID;
2120
/**
2221
* Wraps the Database Transaction type.
2322
*/
@@ -262,11 +261,6 @@ default boolean supportsSorting(Class<?> entityClass, Sorting sorting) {
262261
default boolean supportsPagination(Class<?> entityClass, FilterExpression expression) {
263262
return true;
264263
}
265-
/**
266-
* Transaction ID for each transaction
267-
* @return UUID id
268-
*/
269-
UUID getRequestId();
270264

271265
/**
272266
* Cancel running transaction.

elide-core/src/main/java/com/yahoo/elide/core/DataStoreTransactionImplementation.java

Lines changed: 0 additions & 22 deletions
This file was deleted.

elide-core/src/main/java/com/yahoo/elide/core/RequestScope.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public class RequestScope implements com.yahoo.elide.security.RequestScope {
6767

6868
//TODO - this ought to be read only and set in the constructor.
6969
@Getter @Setter private EntityProjection entityProjection;
70-
private final String requestId;
70+
private final UUID requestId;
7171
private final Map<String, FilterExpression> expressionsByType;
7272

7373
private PublishSubject<CRUDEvent> lifecycleEvents;
@@ -94,6 +94,7 @@ public RequestScope(String path,
9494
DataStoreTransaction transaction,
9595
User user,
9696
MultivaluedMap<String, String> queryParams,
97+
UUID requestId,
9798
ElideSettings elideSettings) {
9899
this.apiVersion = apiVersion;
99100
this.lifecycleEvents = PublishSubject.create();
@@ -119,7 +120,7 @@ public RequestScope(String path,
119120
this.newPersistentResources = new LinkedHashSet<>();
120121
this.dirtyResources = new LinkedHashSet<>();
121122
this.deletedResources = new LinkedHashSet<>();
122-
this.requestId = UUID.randomUUID().toString();
123+
this.requestId = requestId;
123124

124125
Function<RequestScope, PermissionExecutor> permissionExecutorGenerator = elideSettings.getPermissionExecutor();
125126
this.permissionExecutor = (permissionExecutorGenerator == null)

elide-core/src/main/java/com/yahoo/elide/core/datastore/inmemory/HashMapStoreTransaction.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
package com.yahoo.elide.core.datastore.inmemory;
77

88
import com.yahoo.elide.core.DataStoreTransaction;
9-
import com.yahoo.elide.core.DataStoreTransactionImplementation;
109
import com.yahoo.elide.core.EntityDictionary;
1110
import com.yahoo.elide.core.RequestScope;
1211
import com.yahoo.elide.core.exceptions.TransactionException;
@@ -28,7 +27,7 @@
2827
/**
2928
* HashMapDataStore transaction handler.
3029
*/
31-
public class HashMapStoreTransaction extends DataStoreTransactionImplementation {
30+
public class HashMapStoreTransaction implements DataStoreTransaction {
3231
private final Map<Class<?>, Map<String, Object>> dataStore;
3332
private final List<Operation> operations;
3433
private final EntityDictionary dictionary;

0 commit comments

Comments
 (0)