Skip to content

Commit

Permalink
add lambdaRelationType (finos#3125)
Browse files Browse the repository at this point in the history
  • Loading branch information
MauricioUyaguari authored Sep 26, 2024
1 parent 0402379 commit 071d8c6
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@
import javax.servlet.FilterRegistration;
import javax.ws.rs.container.DynamicFeature;
import java.io.FileInputStream;
import java.util.concurrent.ForkJoinPool;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@
<artifactId>jackson-databind</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<!-- JACKSON -->

<!-- TEST -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@
import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModel;
import org.finos.legend.engine.language.pure.compiler.toPureGraph.extension.CompilerExtensions;
import org.finos.legend.engine.language.pure.modelManager.ModelManager;
import org.finos.legend.engine.protocol.pure.PureClientVersions;
import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContext;
import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData;
import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextPointer;
import org.finos.legend.engine.protocol.pure.v1.model.relationType.RelationType;
import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.Lambda;
import org.finos.legend.engine.shared.core.identity.Identity;
import org.finos.legend.engine.shared.core.kerberos.ProfileManagerHelper;
Expand Down Expand Up @@ -123,6 +125,31 @@ public Response lambdaReturnType(LambdaReturnTypeInput lambdaReturnTypeInput, @A
}
}

@POST
@Path("lambdaRelationType")
@ApiOperation(value = "Loads a given model and lambda. Returns the lambda relation type")
@Consumes({MediaType.APPLICATION_JSON, APPLICATION_ZLIB})
@Prometheus(name = "lambda relation type")
public Response lambdaRelationType(LambdaReturnTypeInput lambdaReturnTypeInput, @ApiParam(hidden = true) @Pac4JProfileManager ProfileManager<CommonProfile> pm, @Context UriInfo uriInfo)
{
MutableList<CommonProfile> profiles = ProfileManagerHelper.extractProfiles(pm);
Identity identity = Identity.makeIdentity(profiles);
long start = System.currentTimeMillis();
try
{
PureModelContext model = lambdaReturnTypeInput.model;
Lambda lambda = lambdaReturnTypeInput.lambda;
PureModel pureModel = this.modelManager.loadModel(model, PureClientVersions.production, identity, null);
RelationType relationType = org.finos.legend.engine.language.pure.compiler.Compiler.getLambdaRelationType(lambda, pureModel);
return Response.ok(relationType, MediaType.APPLICATION_JSON_TYPE).build();
}
catch (Exception ex)
{
MetricsHandler.observeError(LoggingEventType.LAMBDA_RETURN_TYPE_ERROR, ex, null);
return handleException(uriInfo, identity, start, ex);
}
}

private Response handleException(UriInfo uriInfo, Identity identity, long start, Exception ex)
{
Response.Status status = ex instanceof EngineException ? Response.Status.BAD_REQUEST : Response.Status.INTERNAL_SERVER_ERROR;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,23 @@

package org.finos.legend.engine.language.pure.compiler.api.test;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.javacrumbs.jsonunit.JsonAssert;
import org.finos.legend.engine.language.pure.compiler.Compiler;
import org.finos.legend.engine.language.pure.compiler.api.Compile;
import org.finos.legend.engine.language.pure.compiler.api.LambdaReturnTypeInput;
import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModel;
import org.finos.legend.engine.language.pure.grammar.from.PureGrammarParser;
import org.finos.legend.engine.language.pure.modelManager.ModelManager;
import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData;
import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextText;
import org.finos.legend.engine.protocol.pure.v1.model.relationType.RelationType;
import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.Lambda;
import org.finos.legend.engine.shared.core.ObjectMapperFactory;
import org.finos.legend.engine.shared.core.deployment.DeploymentMode;
import org.finos.legend.engine.shared.core.identity.Identity;
import org.junit.Assert;
import org.junit.Test;

import java.util.Objects;
Expand Down Expand Up @@ -89,4 +99,25 @@ public void testWithJson(String pureModelContextDataJsonStr, String compilationR
throw new RuntimeException(e);
}
}

@Test
public void testRelationType() throws JsonProcessingException
{
String model = "Class model::Person {\n" +
"name: String[1];\n" +
"}\n";
PureModelContextText text = new PureModelContextText();
text.code = model;
Lambda lambda = PureGrammarParser.newInstance().parseLambda("|model::Person.all()->project(~['Person Name':x|$x.name])", "", 0, 0, false);
LambdaReturnTypeInput lambdaReturnTypeInput = new LambdaReturnTypeInput();
lambdaReturnTypeInput.model = text;
lambdaReturnTypeInput.lambda = lambda;
String stringResult = objectMapper.writeValueAsString(compileApi.lambdaRelationType(lambdaReturnTypeInput, null, null).getEntity());
org.finos.legend.engine.protocol.pure.v1.model.relationType.RelationType relationType = objectMapper.readValue(stringResult, RelationType.class);
Assert.assertEquals(1, relationType.columns.size());
org.finos.legend.engine.protocol.pure.v1.model.relationType.Column column = relationType.columns.get(0);
Assert.assertEquals("Person Name", column.name);
Assert.assertEquals("String", column.type);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@
import org.finos.legend.engine.language.pure.compiler.toPureGraph.ProcessingContext;
import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModel;
import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModelProcessParameter;
import org.finos.legend.engine.language.pure.compiler.toPureGraph.RelationTypeHelper;
import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData;
import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.Lambda;
import org.finos.legend.engine.shared.core.deployment.DeploymentMode;
import org.finos.legend.engine.shared.core.operational.Assert;
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.relation.RelationType;
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecification;
import org.finos.legend.pure.runtime.java.compiled.metadata.Metadata;
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Type;

public class Compiler
{
Expand All @@ -49,9 +53,27 @@ public static PureModel compile(PureModelContextData model, DeploymentMode deplo
return new PureModel(model, user, deploymentMode, pureModelProcessParameter, metaData);
}

public static ValueSpecification getLambdaRawType(Lambda lambda, PureModel pureModel)
{
return HelperValueSpecificationBuilder.buildLambdaWithContext(lambda.body, lambda.parameters, new CompileContext.Builder(pureModel).build(), new ProcessingContext("Processing return type for lambda"))._expressionSequence().getLast();
}

public static org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.relation.RelationType<?> buildLambdaRelationType(Lambda lambda, PureModel pureModel)
{
ValueSpecification valueSpecification = getLambdaRawType(lambda, pureModel);
Type type = valueSpecification._genericType()._typeArguments().getFirst()._rawType();
Assert.assertTrue(type instanceof RelationType, () -> "Relation type expected in lambda");
return (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.relation.RelationType<?>) type;
}

public static org.finos.legend.engine.protocol.pure.v1.model.relationType.RelationType getLambdaRelationType(Lambda lambda, PureModel pureModel)
{
return RelationTypeHelper.convert(buildLambdaRelationType(lambda, pureModel));
}

public static String getLambdaReturnType(Lambda lambda, PureModel pureModel)
{
ValueSpecification valueSpecification = HelperValueSpecificationBuilder.buildLambdaWithContext(lambda.body, lambda.parameters, new CompileContext.Builder(pureModel).build(), new ProcessingContext("Processing return type for lambda"))._expressionSequence().getLast();
ValueSpecification valueSpecification = getLambdaRawType(lambda, pureModel);
return HelperModelBuilder.getTypeFullPath(valueSpecification._genericType()._rawType(), pureModel.getExecutionSupport());
}
}

0 comments on commit 071d8c6

Please sign in to comment.