Skip to content

Commit

Permalink
GraphQL - refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
abhishoya-gs committed Nov 7, 2023
1 parent 891b1de commit b77364e
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@

public interface GraphQLCacheKey
{
String getQueryClassPath();
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,24 @@ public int hashCode()
{
return Objects.hashCode(projectId, workspaceId, queryClassPath, mappingPath, runtimePath, query);
}

public String getQueryClassPath()
{
return queryClassPath;
}

public String getMappingPath()
{
return mappingPath;
}

public String getRuntimePath()
{
return runtimePath;
}

public String getQuery()
{
return query;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,47 +16,21 @@

import com.google.common.base.Objects;

public class GraphQLProdCacheKey implements GraphQLCacheKey
public abstract class GraphQLProdCacheKey implements GraphQLCacheKey
{
private String groupID;
private String artifactId;
private String versionId;
private String mappingPath;
private String runtimePath;
private String queryClassPath;
private String query;
private String dataspacePath;
private String executionContext;
protected String groupID;
protected String artifactId;
protected String versionId;
protected String queryClassPath;
protected String query;

GraphQLProdCacheKey()
public GraphQLProdCacheKey (String groupID, String artifactId, String versionId, String queryClassPath, String 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 static GraphQLProdCacheKey newGraphQLProdCacheKeyWithDataspace(String groupID, String artifactId, String versionId, String dataspacePath, String executionContext, String queryClassPath, String 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;
this.groupID = groupID;
this.artifactId = artifactId;
this.versionId = versionId;
this.queryClassPath = queryClassPath;
this.query = query;
}

@Override
Expand All @@ -74,17 +48,32 @@ public boolean equals(Object 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)
&& Objects.equal(executionContext, that.executionContext);
&& Objects.equal(query, that.query);
}

@Override
public int hashCode()
public String getGroupID()
{
return groupID;
}

public String getArtifactId()
{
return artifactId;
}

public String getVersionId()
{
return versionId;
}

public String getQueryClassPath()
{
return queryClassPath;
}

public String getQuery()
{
return Objects.hashCode(groupID, artifactId, versionId, mappingPath, runtimePath, queryClassPath, query, dataspacePath, executionContext);
return query;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.finos.legend.engine.query.graphQL.api.cache;

import com.google.common.base.Objects;

public class GraphQLProdDataspaceCacheKey extends GraphQLProdCacheKey
{
private String dataspacePath;
private String executionContext;

public GraphQLProdDataspaceCacheKey(String groupID, String artifactId, String versionId, String dataspacePath, String executionContext, String queryClassPath, String query)
{
super(groupID, artifactId, versionId, queryClassPath, query);
this.dataspacePath = dataspacePath;
this.executionContext = executionContext;
}

@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o == null || getClass() != o.getClass())
{
return false;
}
GraphQLProdDataspaceCacheKey that = (GraphQLProdDataspaceCacheKey) o;
return super.equals(that)
&& Objects.equal(dataspacePath, that.dataspacePath)
&& Objects.equal(executionContext, that.executionContext);
}

@Override
public int hashCode()
{
return Objects.hashCode(groupID, artifactId, versionId, dataspacePath, executionContext, queryClassPath, query);
}

public String getDataspacePath()
{
return dataspacePath;
}

public String getExecutionContext()
{
return executionContext;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.finos.legend.engine.query.graphQL.api.cache;

import com.google.common.base.Objects;

public class GraphQLProdMappingRuntimeCacheKey extends GraphQLProdCacheKey
{
private String mappingPath;
private String runtimePath;

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

@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o == null || getClass() != o.getClass())
{
return false;
}
GraphQLProdMappingRuntimeCacheKey that = (GraphQLProdMappingRuntimeCacheKey) o;
return super.equals(that)
&& Objects.equal(mappingPath, that.mappingPath)
&& Objects.equal(runtimePath, that.runtimePath);
}

@Override
public int hashCode()
{
return Objects.hashCode(groupID, artifactId, versionId, mappingPath, runtimePath, queryClassPath, query);
}

public String getMappingPath()
{
return mappingPath;
}

public String getRuntimePath()
{
return runtimePath;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
import org.finos.legend.engine.query.graphQL.api.cache.GraphQLDevCacheKey;
import org.finos.legend.engine.query.graphQL.api.cache.GraphQLPlanCache;
import org.finos.legend.engine.query.graphQL.api.cache.GraphQLProdCacheKey;
import org.finos.legend.engine.query.graphQL.api.cache.GraphQLProdDataspaceCacheKey;
import org.finos.legend.engine.query.graphQL.api.cache.GraphQLProdMappingRuntimeCacheKey;
import org.finos.legend.engine.query.graphQL.api.execute.directives.IGraphQLDirectiveExtension;
import org.finos.legend.engine.query.graphQL.api.execute.model.PlansResult;
import org.finos.legend.engine.query.graphQL.api.execute.model.Query;
Expand Down Expand Up @@ -238,7 +240,7 @@ private Response executeIntrospection(String queryClassPath, Document document,
"}").type(MediaType.TEXT_HTML_TYPE).build();
}

private Response executeGraphQLQueryWithDataspace(String queryClassPath, String dataspacePath, String executionContext, Document document, GraphQLCacheKey graphQLCacheKey, MutableList<CommonProfile> profiles, Callable<PureModel> modelLoader)
private Response executeGraphQLQuery(Document document, GraphQLCacheKey graphQLCacheKey, MutableList<CommonProfile> profiles, Callable<PureModel> modelLoader)
{
List<SerializedNamedPlans> planWithSerialized;
OperationDefinition graphQLQuery = GraphQLExecutionHelper.findQuery(document);
Expand All @@ -248,7 +250,7 @@ private Response executeGraphQLQueryWithDataspace(String queryClassPath, String
if (isQueryIntrospection(graphQLQuery))
{
pureModel = modelLoader.call();
return executeIntrospection(queryClassPath, document, pureModel);
return executeIntrospection(graphQLCacheKey.getQueryClassPath(), document, pureModel);
}
else
{
Expand All @@ -259,7 +261,7 @@ private Response executeGraphQLQueryWithDataspace(String queryClassPath, String
{
LOGGER.debug(new LogInfo(profiles, LoggingEventType.GRAPHQL_EXECUTE, "Cache miss. Generating new plan").toString());
pureModel = modelLoader.call();
planWithSerialized = buildPlanWithParameterUsingDataspace(queryClassPath, dataspacePath, executionContext, document, graphQLQuery, pureModel, graphQLCacheKey);
planWithSerialized = getSerializedNamedPlans(document, graphQLCacheKey, graphQLQuery, pureModel);
graphQLPlanCache.put(graphQLCacheKey, planWithSerialized);
}
else
Expand All @@ -270,7 +272,7 @@ private Response executeGraphQLQueryWithDataspace(String queryClassPath, String
else //no cache so we generate the plan
{
pureModel = modelLoader.call();
planWithSerialized = buildPlanWithParameterUsingDataspace(queryClassPath, dataspacePath, executionContext, document, graphQLQuery, pureModel, graphQLCacheKey);
planWithSerialized = getSerializedNamedPlans(document, graphQLCacheKey, graphQLQuery, pureModel);
}
}
}
Expand All @@ -281,47 +283,29 @@ private Response executeGraphQLQueryWithDataspace(String queryClassPath, String
return execute(profiles, planWithSerialized, graphQLQuery);
}

private Response executeGraphQLQuery(String queryClassPath, String mappingPath, String runtimePath, Document document, GraphQLCacheKey graphQLCacheKey, MutableList<CommonProfile> profiles, Callable<PureModel> modelLoader)
private List<SerializedNamedPlans> getSerializedNamedPlans(Document document, GraphQLCacheKey graphQLCacheKey,OperationDefinition graphQLQuery, PureModel pureModel)
{
List<SerializedNamedPlans> planWithSerialized;
OperationDefinition graphQLQuery = GraphQLExecutionHelper.findQuery(document);
PureModel pureModel = null;
try
if (graphQLCacheKey instanceof GraphQLDevCacheKey)
{
if (isQueryIntrospection(graphQLQuery))
{
pureModel = modelLoader.call();
return executeIntrospection(queryClassPath, document, pureModel);
}
else
{
if (graphQLPlanCache != null)
{
planWithSerialized = graphQLPlanCache.getIfPresent(graphQLCacheKey);
if (planWithSerialized == null) //cache miss, generate the plan and add to the cache
{
LOGGER.debug(new LogInfo(profiles, LoggingEventType.GRAPHQL_EXECUTE, "Cache miss. Generating new plan").toString());
pureModel = modelLoader.call();
planWithSerialized = buildPlanWithParameter(queryClassPath, mappingPath, runtimePath, document, graphQLQuery, pureModel, graphQLCacheKey);
graphQLPlanCache.put(graphQLCacheKey, planWithSerialized);
}
else
{
LOGGER.debug(new LogInfo(profiles, LoggingEventType.GRAPHQL_EXECUTE, "Cache hit. Using previously cached plan").toString());
}
}
else //no cache so we generate the plan
{
pureModel = modelLoader.call();
planWithSerialized = buildPlanWithParameter(queryClassPath, mappingPath, runtimePath, document, graphQLQuery, pureModel, graphQLCacheKey);
}
}
GraphQLDevCacheKey key = (GraphQLDevCacheKey) graphQLCacheKey;
planWithSerialized = buildPlanWithParameter(key.getQueryClassPath(), key.getMappingPath(), key.getRuntimePath(), document, graphQLQuery, pureModel, graphQLCacheKey);
}
catch (Exception e)
else if (graphQLCacheKey instanceof GraphQLProdMappingRuntimeCacheKey)
{
return ExceptionTool.exceptionManager(e, LoggingEventType.EXECUTE_INTERACTIVE_ERROR, profiles);
GraphQLProdMappingRuntimeCacheKey key = (GraphQLProdMappingRuntimeCacheKey) graphQLCacheKey;
planWithSerialized = buildPlanWithParameter(key.getQueryClassPath(), key.getMappingPath(), key.getRuntimePath(), document, graphQLQuery, pureModel, graphQLCacheKey);
}
return execute(profiles, planWithSerialized, graphQLQuery);
else if (graphQLCacheKey instanceof GraphQLProdDataspaceCacheKey)
{
GraphQLProdDataspaceCacheKey key = (GraphQLProdDataspaceCacheKey) graphQLCacheKey;
planWithSerialized = buildPlanWithParameterUsingDataspace(key.getQueryClassPath(), key.getDataspacePath(), key.getExecutionContext(), document, graphQLQuery, pureModel, graphQLCacheKey);
}
else
{
throw new UnsupportedOperationException("Invalid graphql cache key");
}
return planWithSerialized;
}

private Response execute(MutableList<CommonProfile> profiles, List<SerializedNamedPlans> planWithSerialized, OperationDefinition graphQLQuery)
Expand Down Expand Up @@ -534,7 +518,7 @@ private Response executeDevImpl(HttpServletRequest request, String projectId, St
Document document = GraphQLGrammarParser.newInstance().parseDocument(query.query);
Document cachableGraphQLQuery = createCachableGraphQLQuery(document);
GraphQLDevCacheKey key = new GraphQLDevCacheKey(projectId, workspaceId, queryClassPath, mappingPath, runtimePath, objectMapper.writeValueAsString(cachableGraphQLQuery));
return this.executeGraphQLQuery(queryClassPath, mappingPath, runtimePath, document, key, profiles, () -> loadSDLCProjectModel(profiles, request, projectId, workspaceId, isGroupWorkspace));
return this.executeGraphQLQuery(document, key, profiles, () -> loadSDLCProjectModel(profiles, request, projectId, workspaceId, isGroupWorkspace));
}
catch (Exception ex)
{
Expand All @@ -552,9 +536,9 @@ 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 = GraphQLProdCacheKey.newGraphQLProdCacheKey(groupId, artifactId, versionId, mappingPath, runtimePath, queryClassPath, objectMapper.writeValueAsString(createCachableGraphQLQuery(document)));
GraphQLProdMappingRuntimeCacheKey key = new GraphQLProdMappingRuntimeCacheKey(groupId, artifactId, versionId, mappingPath, runtimePath, queryClassPath, objectMapper.writeValueAsString(createCachableGraphQLQuery(document)));

return this.executeGraphQLQuery(queryClassPath, mappingPath, runtimePath, document, key, profiles, () -> loadProjectModel(profiles, groupId, artifactId, versionId));
return this.executeGraphQLQuery(document, key, profiles, () -> loadProjectModel(profiles, groupId, artifactId, versionId));
}
catch (Exception ex)
{
Expand All @@ -572,9 +556,9 @@ public Response executeProdWithDataspace(@Context HttpServletRequest request, @P
try (Scope scope = GlobalTracer.get().buildSpan("GraphQL: Execute").startActive(true))
{
Document document = GraphQLGrammarParser.newInstance().parseDocument(query.query);
GraphQLProdCacheKey key = GraphQLProdCacheKey.newGraphQLProdCacheKeyWithDataspace(groupId, artifactId, versionId, dataspacePath, queryClassPath, executionContext, objectMapper.writeValueAsString(createCachableGraphQLQuery(document)));
GraphQLProdDataspaceCacheKey key = new GraphQLProdDataspaceCacheKey(groupId, artifactId, versionId, dataspacePath, executionContext, queryClassPath, objectMapper.writeValueAsString(createCachableGraphQLQuery(document)));

return this.executeGraphQLQueryWithDataspace(queryClassPath, dataspacePath, executionContext, document, key, profiles, () -> loadProjectModel(profiles, groupId, artifactId, versionId));
return this.executeGraphQLQuery(document, key, profiles, () -> loadProjectModel(profiles, groupId, artifactId, versionId));
}
catch (Exception ex)
{
Expand Down

0 comments on commit b77364e

Please sign in to comment.