Skip to content

Commit

Permalink
Optional executionContext
Browse files Browse the repository at this point in the history
  • Loading branch information
abhishoya-gs committed Nov 7, 2023
1 parent 4d695da commit 891b1de
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,37 @@ public class GraphQLProdCacheKey implements GraphQLCacheKey
private String queryClassPath;
private String query;
private String dataspacePath;
private String executionContext;

public GraphQLProdCacheKey(String groupID, String artifactId, String versionId, String mappingPath, String runtimePath, String queryClassPath, String query)
GraphQLProdCacheKey()
{
this.groupID = groupID;
this.artifactId = artifactId;
this.versionId = versionId;
this.mappingPath = mappingPath;
this.runtimePath = runtimePath;
this.queryClassPath = queryClassPath;
this.query = query;

}

public static GraphQLProdCacheKey newGraphQLProdCacheKey(String groupID, String artifactId, String versionId, String mappingPath, String runtimePath, String queryClassPath, String query)
{
GraphQLProdCacheKey graphQLProdCacheKey = new GraphQLProdCacheKey();
graphQLProdCacheKey.groupID = groupID;
graphQLProdCacheKey.artifactId = artifactId;
graphQLProdCacheKey.versionId = versionId;
graphQLProdCacheKey.mappingPath = mappingPath;
graphQLProdCacheKey.runtimePath = runtimePath;
graphQLProdCacheKey.queryClassPath = queryClassPath;
graphQLProdCacheKey.query = query;
return graphQLProdCacheKey;
}

public GraphQLProdCacheKey(String groupID, String artifactId, String versionId, String dataspacePath, String queryClassPath, String query)
public static GraphQLProdCacheKey newGraphQLProdCacheKeyWithDataspace(String groupID, String artifactId, String versionId, String dataspacePath, String executionContext, String queryClassPath, String query)
{
this.groupID = groupID;
this.artifactId = artifactId;
this.versionId = versionId;
this.dataspacePath = dataspacePath;
this.queryClassPath = queryClassPath;
this.query = query;
GraphQLProdCacheKey graphQLProdCacheKey = new GraphQLProdCacheKey();
graphQLProdCacheKey.groupID = groupID;
graphQLProdCacheKey.artifactId = artifactId;
graphQLProdCacheKey.versionId = versionId;
graphQLProdCacheKey.dataspacePath = dataspacePath;
graphQLProdCacheKey.executionContext = executionContext;
graphQLProdCacheKey.queryClassPath = queryClassPath;
graphQLProdCacheKey.query = query;
return graphQLProdCacheKey;
}

@Override
Expand All @@ -60,12 +71,20 @@ public boolean equals(Object o)
return false;
}
GraphQLProdCacheKey that = (GraphQLProdCacheKey) o;
return Objects.equal(groupID, that.groupID) && Objects.equal(artifactId, that.artifactId) && Objects.equal(versionId, that.versionId) && Objects.equal(mappingPath, that.mappingPath) && Objects.equal(runtimePath, that.runtimePath) && Objects.equal(queryClassPath, that.queryClassPath) && Objects.equal(query, that.query) && Objects.equal(dataspacePath, that.dataspacePath);
return Objects.equal(groupID, that.groupID)
&& Objects.equal(artifactId, that.artifactId)
&& Objects.equal(versionId, that.versionId)
&& Objects.equal(mappingPath, that.mappingPath)
&& Objects.equal(runtimePath, that.runtimePath)
&& Objects.equal(queryClassPath, that.queryClassPath)
&& Objects.equal(query, that.query)
&& Objects.equal(dataspacePath, that.dataspacePath)
&& Objects.equal(executionContext, that.executionContext);
}

@Override
public int hashCode()
{
return Objects.hashCode(groupID, artifactId, versionId, mappingPath, runtimePath, queryClassPath, query, dataspacePath);
return Objects.hashCode(groupID, artifactId, versionId, mappingPath, runtimePath, queryClassPath, query, dataspacePath, executionContext);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,12 @@
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
Expand Down Expand Up @@ -236,7 +238,7 @@ private Response executeIntrospection(String queryClassPath, Document document,
"}").type(MediaType.TEXT_HTML_TYPE).build();
}

private Response executeGraphQLQuery(String queryClassPath, String dataspacePath, Document document, GraphQLCacheKey graphQLCacheKey, MutableList<CommonProfile> profiles, Callable<PureModel> modelLoader)
private Response executeGraphQLQueryWithDataspace(String queryClassPath, String dataspacePath, String executionContext, Document document, GraphQLCacheKey graphQLCacheKey, MutableList<CommonProfile> profiles, Callable<PureModel> modelLoader)
{
List<SerializedNamedPlans> planWithSerialized;
OperationDefinition graphQLQuery = GraphQLExecutionHelper.findQuery(document);
Expand All @@ -257,7 +259,7 @@ private Response executeGraphQLQuery(String queryClassPath, String dataspacePath
{
LOGGER.debug(new LogInfo(profiles, LoggingEventType.GRAPHQL_EXECUTE, "Cache miss. Generating new plan").toString());
pureModel = modelLoader.call();
planWithSerialized = buildPlanWithParameter(queryClassPath, dataspacePath, document, graphQLQuery, pureModel, graphQLCacheKey);
planWithSerialized = buildPlanWithParameterUsingDataspace(queryClassPath, dataspacePath, executionContext, document, graphQLQuery, pureModel, graphQLCacheKey);
graphQLPlanCache.put(graphQLCacheKey, planWithSerialized);
}
else
Expand All @@ -268,7 +270,7 @@ private Response executeGraphQLQuery(String queryClassPath, String dataspacePath
else //no cache so we generate the plan
{
pureModel = modelLoader.call();
planWithSerialized = buildPlanWithParameter(queryClassPath, dataspacePath, document, graphQLQuery, pureModel, graphQLCacheKey);
planWithSerialized = buildPlanWithParameterUsingDataspace(queryClassPath, dataspacePath, executionContext, document, graphQLQuery, pureModel, graphQLCacheKey);
}
}
}
Expand Down Expand Up @@ -426,22 +428,36 @@ private List<SerializedNamedPlans> buildExtensionsPlanWithParameter(String rootF
return serializedNamedPlans;
}

private Root_meta_pure_metamodel_dataSpace_DataSpaceExecutionContext getDataspaceDefaultExecutionContext(String dataspacePath, PureModel pureModel)
private Root_meta_pure_metamodel_dataSpace_DataSpaceExecutionContext getDataspaceExecutionContext(String dataspacePath, String executionContext, PureModel pureModel)
{
PackageableElement packageableElement = pureModel.getPackageableElement(dataspacePath);
Assert.assertTrue(packageableElement instanceof Root_meta_pure_metamodel_dataSpace_DataSpace, () -> "Can't find data space '" + dataspacePath + "'");
return ((Root_meta_pure_metamodel_dataSpace_DataSpace) packageableElement)._executionContexts().select(dataSpaceExecutionContext -> dataSpaceExecutionContext._name().equals(((Root_meta_pure_metamodel_dataSpace_DataSpace) packageableElement)._defaultExecutionContext()._name())).toList().get(0);
if (executionContext.equals("defaultExecutionContext"))
{
return ((Root_meta_pure_metamodel_dataSpace_DataSpace) packageableElement)._executionContexts().select(dataSpaceExecutionContext -> dataSpaceExecutionContext._name().equals(((Root_meta_pure_metamodel_dataSpace_DataSpace) packageableElement)._defaultExecutionContext()._name())).toList().get(0);
}
else
{
try
{
return ((Root_meta_pure_metamodel_dataSpace_DataSpace) packageableElement)._executionContexts().select(dataSpaceExecutionContext -> dataSpaceExecutionContext._name().equals(executionContext)).toList().get(0);
}
catch (Exception e)
{
throw new RuntimeException("Invalid execution context " + executionContext, e);
}
}
}

private List<SerializedNamedPlans> buildPlanWithParameter(String queryClassPath, String dataspacePath, Document document, OperationDefinition query, PureModel pureModel, GraphQLCacheKey graphQLCacheKey)
private List<SerializedNamedPlans> buildPlanWithParameterUsingDataspace(String queryClassPath, String dataspacePath, String executionContext, Document document, OperationDefinition query, PureModel pureModel, GraphQLCacheKey graphQLCacheKey)
{
RichIterable<? extends Root_meta_pure_extension_Extension> extensions = this.extensionsFunc.apply(pureModel);
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Class<?> _class = pureModel.getClass(queryClassPath);
org.finos.legend.pure.generated.Root_meta_external_query_graphQL_metamodel_sdl_Document queryDoc = toPureModel(document, pureModel);

Root_meta_pure_metamodel_dataSpace_DataSpaceExecutionContext executionContext = getDataspaceDefaultExecutionContext(dataspacePath, pureModel);
Mapping mapping = executionContext._mapping();
Root_meta_core_runtime_Runtime runtime = executionContext._defaultRuntime()._runtimeValue();
Root_meta_pure_metamodel_dataSpace_DataSpaceExecutionContext executionContextPureElement = getDataspaceExecutionContext(dataspacePath, executionContext, pureModel);
Mapping mapping = executionContextPureElement._mapping();
Root_meta_core_runtime_Runtime runtime = executionContextPureElement._defaultRuntime()._runtimeValue();
return getSerializedNamedPlans(pureModel, extensions, _class, mapping, runtime, document, query, queryDoc, graphQLCacheKey);
}

Expand Down Expand Up @@ -536,7 +552,7 @@ public Response executeProd(@Context HttpServletRequest request, @PathParam("gro
try (Scope scope = GlobalTracer.get().buildSpan("GraphQL: Execute").startActive(true))
{
Document document = GraphQLGrammarParser.newInstance().parseDocument(query.query);
GraphQLProdCacheKey key = new GraphQLProdCacheKey(groupId, artifactId, versionId, mappingPath, runtimePath, queryClassPath, objectMapper.writeValueAsString(createCachableGraphQLQuery(document)));
GraphQLProdCacheKey key = GraphQLProdCacheKey.newGraphQLProdCacheKey(groupId, artifactId, versionId, mappingPath, runtimePath, queryClassPath, objectMapper.writeValueAsString(createCachableGraphQLQuery(document)));

return this.executeGraphQLQuery(queryClassPath, mappingPath, runtimePath, document, key, profiles, () -> loadProjectModel(profiles, groupId, artifactId, versionId));
}
Expand All @@ -550,15 +566,15 @@ public Response executeProd(@Context HttpServletRequest request, @PathParam("gro
@ApiOperation(value = "Execute a GraphQL query in the context of a mapping and a runtime")
@Path("execute/prod/{groupId}/{artifactId}/{versionId}/query/{queryClassPath}/dataspace/{dataspacePath}")
@Consumes({MediaType.APPLICATION_JSON, APPLICATION_ZLIB})
public Response executeProd(@Context HttpServletRequest request, @PathParam("groupId") String groupId, @PathParam("artifactId") String artifactId, @PathParam("versionId") String versionId, @PathParam("dataspacePath") String dataspacePath, @PathParam("queryClassPath") String queryClassPath, Query query, @ApiParam(hidden = true) @Pac4JProfileManager ProfileManager<CommonProfile> pm)
public Response executeProdWithDataspace(@Context HttpServletRequest request, @PathParam("groupId") String groupId, @PathParam("artifactId") String artifactId, @PathParam("versionId") String versionId, @PathParam("dataspacePath") String dataspacePath, @QueryParam("executionContext") @DefaultValue("defaultExecutionContext") String executionContext, @PathParam("queryClassPath") String queryClassPath, Query query, @ApiParam(hidden = true) @Pac4JProfileManager ProfileManager<CommonProfile> pm)
{
MutableList<CommonProfile> profiles = ProfileManagerHelper.extractProfiles(pm);
try (Scope scope = GlobalTracer.get().buildSpan("GraphQL: Execute").startActive(true))
{
Document document = GraphQLGrammarParser.newInstance().parseDocument(query.query);
GraphQLProdCacheKey key = new GraphQLProdCacheKey(groupId, artifactId, versionId, dataspacePath, queryClassPath, objectMapper.writeValueAsString(createCachableGraphQLQuery(document)));
GraphQLProdCacheKey key = GraphQLProdCacheKey.newGraphQLProdCacheKeyWithDataspace(groupId, artifactId, versionId, dataspacePath, queryClassPath, executionContext, objectMapper.writeValueAsString(createCachableGraphQLQuery(document)));

return this.executeGraphQLQuery(queryClassPath, dataspacePath, document, key, profiles, () -> loadProjectModel(profiles, groupId, artifactId, versionId));
return this.executeGraphQLQueryWithDataspace(queryClassPath, dataspacePath, executionContext, document, key, profiles, () -> loadProjectModel(profiles, groupId, artifactId, versionId));
}
catch (Exception ex)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public void testGraphQLExecuteProdAPI_Relational_With_Dataspace() throws Excepti
" }\n" +
" }\n" +
" }";
Response response = graphQLExecute.executeProd(mockRequest, "org.finos.legend.graphql", "model.one", "1.0.0", "simple::dataspace", "simple::model::Query", query, null);
Response response = graphQLExecute.executeProdWithDataspace(mockRequest, "org.finos.legend.graphql", "model.one", "1.0.0", "simple::dataspace", "defaultExecutionContext", "simple::model::Query", query, null);

String expected = "{" +
"\"data\":{" +
Expand Down Expand Up @@ -214,7 +214,7 @@ public void testGraphQLExecuteProdAPI_Relational_With_Dataspace_With_Caching() t
" }\n" +
" }\n" +
" }";
Response response = graphQLExecute.executeProd(mockRequest, "org.finos.legend.graphql", "model.one", "1.0.0", "simple::dataspace", "simple::model::Query", query, null);
Response response = graphQLExecute.executeProdWithDataspace(mockRequest, "org.finos.legend.graphql", "model.one", "1.0.0", "simple::dataspace", "defaultExecutionContext", "simple::model::Query", query, null);

String expected = "{" +
"\"data\":{" +
Expand All @@ -229,7 +229,7 @@ public void testGraphQLExecuteProdAPI_Relational_With_Dataspace_With_Caching() t
Assert.assertEquals(0, cache.getCache().stats().hitCount(), 0);
Assert.assertEquals(1, cache.getCache().stats().missCount(), 0);

response = graphQLExecute.executeProd(mockRequest, "org.finos.legend.graphql", "model.one", "1.0.0", "simple::dataspace", "simple::model::Query", query, null);
response = graphQLExecute.executeProdWithDataspace(mockRequest, "org.finos.legend.graphql", "model.one", "1.0.0", "simple::dataspace", "defaultExecutionContext", "simple::model::Query", query, null);
Assert.assertEquals(expected, responseAsString(response));
Assert.assertEquals(1, cache.getCache().stats().hitCount(), 0);
Assert.assertEquals(1, cache.getCache().stats().missCount(), 0);
Expand Down

0 comments on commit 891b1de

Please sign in to comment.