Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialize the data as found on entities rather than read it into protocol classes #496

Merged
merged 3 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,7 @@
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.finos.legend.depot.domain.project.ProjectVersion;
import org.finos.legend.depot.domain.version.VersionValidator;
import org.finos.legend.depot.services.api.pure.model.context.PureModelContextService;
import org.finos.legend.depot.core.services.tracing.resources.TracingResource;
import org.finos.legend.depot.services.api.EtagBuilder;

import java.util.List;
import javax.inject.Inject;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
Expand All @@ -36,11 +31,13 @@
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;

import java.util.List;

import static org.finos.legend.depot.core.services.tracing.ResourceLoggingAndTracing.GET_VERSIONS_DEPENDENCY_ENTITIES_AS_PMCD;
import static org.finos.legend.depot.core.services.tracing.ResourceLoggingAndTracing.GET_VERSION_ENTITIES_AS_PMCD;
import org.finos.legend.depot.core.services.tracing.resources.TracingResource;
import org.finos.legend.depot.domain.project.ProjectVersion;
import org.finos.legend.depot.domain.version.VersionValidator;
import org.finos.legend.depot.services.api.EtagBuilder;
import org.finos.legend.depot.services.api.pure.model.context.PureModelContextService;

@Path("")
@Api("Pure Model Context Data")
Expand All @@ -59,28 +56,44 @@ public PureModelContextResource(PureModelContextService service)
@Path("projects/{groupId}/{artifactId}/versions/{versionId}/pureModelContextData")
@ApiOperation(GET_VERSION_ENTITIES_AS_PMCD)
@Produces(MediaType.APPLICATION_JSON)
public Response getPureModelContextData(@PathParam("groupId") String groupId,
@PathParam("artifactId") String artifactId,
@PathParam("versionId") @ApiParam(value = VersionValidator.VALID_VERSION_ID_TXT) String versionId,
@QueryParam("clientVersion") String clientVersion,
public Response getPureModelContextData(@PathParam("groupId")
String groupId,
@PathParam("artifactId")
String artifactId,
@PathParam("versionId") @ApiParam(value = VersionValidator.VALID_VERSION_ID_TXT)
String versionId,
@QueryParam("clientVersion")
String clientVersion,
@QueryParam("getDependencies")
@DefaultValue("true")
@ApiParam("Whether to include entities from dependencies") boolean transitive,
@Context Request request)
@DefaultValue("true")
@ApiParam("Whether to include entities from dependencies")
boolean transitive,
@QueryParam("convertToNewProtocol")
@DefaultValue("true")
@ApiParam("Whether to convert the protocol to latest or return the protocol as initially published")
boolean convertToNewProtocol,
@Context Request request)
{
return handle(GET_VERSION_ENTITIES_AS_PMCD, () -> service.getPureModelContextData(groupId, artifactId, versionId, clientVersion, transitive), request, () -> EtagBuilder.create().withGAV(groupId, artifactId, versionId).withProtocolVersion(clientVersion).build());
return handle(GET_VERSION_ENTITIES_AS_PMCD, () -> service.getPureModelContextData(groupId, artifactId, versionId, clientVersion, transitive, convertToNewProtocol), request, () -> EtagBuilder.create().withGAV(groupId, artifactId, versionId).withProtocolVersion(clientVersion).build());
}

@POST
@Path("projects/dependencies/pureModelContextData")
@ApiOperation(GET_VERSIONS_DEPENDENCY_ENTITIES_AS_PMCD)
@Produces(MediaType.APPLICATION_JSON)
public Response getPureModelContextData(@ApiParam("projectDependencies") List<ProjectVersion> projectDependencies,
@QueryParam("clientVersion") String clientVersion,
public Response getPureModelContextData(@ApiParam("projectDependencies")
List<ProjectVersion> projectDependencies,
@QueryParam("clientVersion")
String clientVersion,
@QueryParam("transitive") @DefaultValue("true")
@ApiParam("Whether to return transitive dependencies") boolean transitive,
@ApiParam("Whether to return transitive dependencies")
boolean transitive,
@QueryParam("convertToNewProtocol")
@DefaultValue("true")
@ApiParam("Whether to convert the protocol to latest or return the protocol as initially published")
boolean convertToNewProtocol,
@Context Request request)
{
return handleResponse(GET_VERSIONS_DEPENDENCY_ENTITIES_AS_PMCD, () -> service.getPureModelContextData(projectDependencies, clientVersion, transitive));
return handleResponse(GET_VERSIONS_DEPENDENCY_ENTITIES_AS_PMCD, () -> service.getPureModelContextData(projectDependencies, clientVersion, transitive, convertToNewProtocol));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

public interface PureModelContextService
{
PureModelContextData getPureModelContextData(String groupId, String artifactId, String versionId, String clientVersion, boolean transitive);
PureModelContextData getPureModelContextData(String groupId, String artifactId, String versionId, String clientVersion, boolean transitive, boolean convertToNewProtocol);

PureModelContextData getPureModelContextData(List<ProjectVersion> projectDependencies, String clientVersion, boolean transitive);
PureModelContextData getPureModelContextData(List<ProjectVersion> projectDependencies, String clientVersion, boolean transitive, boolean convertToNewProtocol);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@

package org.finos.legend.depot.services.pure.model.context;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializable;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
import javax.inject.Inject;
import org.finos.legend.depot.core.services.tracing.TracerFactory;
import org.finos.legend.depot.domain.entity.ProjectVersionEntities;
import org.finos.legend.depot.domain.project.ProjectVersion;
Expand All @@ -24,41 +34,39 @@
import org.finos.legend.engine.protocol.pure.PureClientVersions;
import org.finos.legend.engine.protocol.pure.v1.model.context.AlloySDLC;
import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData;
import static org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData.newBuilder;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.PackageableElement;
import org.finos.legend.sdlc.domain.model.entity.Entity;
import org.finos.legend.sdlc.protocol.pure.v1.EntityToPureConverter;
import org.finos.legend.sdlc.protocol.pure.v1.PureModelContextDataBuilder;

import javax.inject.Inject;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

import static org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData.newBuilder;

public class PureModelContextServiceImpl implements PureModelContextService
{
private static final String PURE = "pure";
private static final String CALCULATE_COMBINED_PMCD = "calculate combined PMCD";
private static final String GA_SEPARATOR = ":";
private static final TracerFactory tracer = TracerFactory.get();
private final EntitiesService entitiesService;
private final EntitiesService<?> entitiesService;
private final ProjectsService projectsService;
private final EntityToPureConverter entityToPureConverter = new EntityToPureConverter();
private final EntityToRawPureConverter entityToRawPureConverter = new EntityToRawPureConverter();

@Inject
public PureModelContextServiceImpl(EntitiesService entitiesService, ProjectsService projectsService)
public PureModelContextServiceImpl(EntitiesService<?> entitiesService, ProjectsService projectsService)
{
this.entitiesService = entitiesService;
this.projectsService = projectsService;
}

@Override
public PureModelContextData getPureModelContextData(String groupId, String artifactId, String versionId, String clientVersion, boolean transitive)
public PureModelContextData getPureModelContextData(String groupId, String artifactId, String versionId, String clientVersion, boolean transitive, boolean convertToNewProtocol)
{
String resolvedClientVersion = resolveAndValidateClientVersion(clientVersion);
String version = this.projectsService.resolveAliasesAndCheckVersionExists(groupId, artifactId, versionId);

List<Entity> entities = this.entitiesService.getEntities(groupId, artifactId, version);

PureModelContextData pureModelContextData = buildPureModelContextData(entities.stream(), groupId, artifactId, version, resolvedClientVersion);
PureModelContextData pureModelContextData = buildPureModelContextData(entities.stream(), groupId, artifactId, version, resolvedClientVersion, convertToNewProtocol);
if (!transitive)
{
return pureModelContextData;
Expand All @@ -67,17 +75,17 @@ public PureModelContextData getPureModelContextData(String groupId, String artif
List<ProjectVersionEntities> dependenciesEntities = this.entitiesService.getDependenciesEntities(groupId, artifactId, version, true, false);
return tracer.executeWithTrace(CALCULATE_COMBINED_PMCD, () ->
{
PureModelContextData dependenciesPMCD = buildPureModelContextData(dependenciesEntities.stream().flatMap(dep -> dep.getEntities().stream()),groupId,artifactId,version,resolvedClientVersion);
return combinePureModelContextData(pureModelContextData,dependenciesPMCD);
PureModelContextData dependenciesPMCD = buildPureModelContextData(dependenciesEntities.stream().flatMap(dep -> dep.getEntities().stream()), groupId, artifactId, version, resolvedClientVersion, convertToNewProtocol);
return combinePureModelContextData(pureModelContextData, dependenciesPMCD);
});
}

@Override
public PureModelContextData getPureModelContextData(List<ProjectVersion> projectDependencies, String clientVersion, boolean transitive)
public PureModelContextData getPureModelContextData(List<ProjectVersion> projectDependencies, String clientVersion, boolean transitive, boolean convertToNewProtocol)
{
String resolvedClientVersion = resolveAndValidateClientVersion(clientVersion);
List<ProjectVersionEntities> dependenciesEntities = (List<ProjectVersionEntities>) entitiesService.getDependenciesEntities(projectDependencies, transitive, true);
return buildPureModelContextData(dependenciesEntities.stream().flatMap(dep -> dep.getEntities().stream()), new AlloySDLC(), resolvedClientVersion);
List<ProjectVersionEntities> dependenciesEntities = entitiesService.getDependenciesEntities(projectDependencies, transitive, true);
return buildPureModelContextData(dependenciesEntities.stream().flatMap(dep -> dep.getEntities().stream()), new AlloySDLC(), resolvedClientVersion, convertToNewProtocol);
}

protected String resolveAndValidateClientVersion(String clientVersion)
Expand All @@ -89,15 +97,17 @@ protected String resolveAndValidateClientVersion(String clientVersion)
return clientVersion == null ? PureClientVersions.production : clientVersion;
}

protected PureModelContextData buildPureModelContextData(Stream<Entity> entities, String groupId, String artifactId, String versionId, String clientVersion)
protected PureModelContextData buildPureModelContextData(Stream<Entity> entities, String groupId, String artifactId, String versionId, String clientVersion, boolean convertToNewProtocol)
{
return buildPureModelContextData(entities, buildAlloySDLC(groupId, artifactId, versionId), clientVersion);
return buildPureModelContextData(entities, buildAlloySDLC(groupId, artifactId, versionId), clientVersion, convertToNewProtocol);
}

protected PureModelContextData buildPureModelContextData(Stream<Entity> entities, AlloySDLC alloySDLC, String clientVersion)
protected PureModelContextData buildPureModelContextData(Stream<Entity> entities, AlloySDLC alloySDLC, String clientVersion, boolean convertToNewProtocol)
{
EntityToPureConverter converter = convertToNewProtocol ? this.entityToPureConverter : this.entityToRawPureConverter;

return PureModelContextDataBuilder
.newBuilder()
.newBuilder(converter)
.withProtocol(PURE, clientVersion)
.withSDLC(alloySDLC)
.withEntitiesIfPossible(entities)
Expand All @@ -115,8 +125,45 @@ protected PureModelContextData combinePureModelContextData(PureModelContextData
protected AlloySDLC buildAlloySDLC(String groupId, String artifactId, String versionId)
{
AlloySDLC sdlc = new AlloySDLC();
sdlc.project = String.join(GA_SEPARATOR,groupId,artifactId);
sdlc.project = String.join(GA_SEPARATOR, groupId, artifactId);
sdlc.baseVersion = versionId;
return sdlc;
}

private static class EntityToRawPureConverter extends EntityToPureConverter
{
@Override
public PackageableElement fromEntity(Entity entity)
{
return new EntityPackageableElement(entity);
}

@Override
public Optional<PackageableElement> fromEntityIfPossible(Entity entity)
{
return Optional.of(this.fromEntity(entity));
}

private static class EntityPackageableElement extends PackageableElement implements JsonSerializable
{
private final Entity entity;

public EntityPackageableElement(Entity entity)
{
this.entity = entity;
}

@Override
public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException
{
gen.writeObject(this.entity.getContent());
}

@Override
public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException
{
gen.writeObject(this.entity.getContent());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public void setUpData()
@Test
public void loadPMCD()
{
Response data = resource.getPureModelContextData("test.legend", "blank-prod", "2.0.0", null, false,null);
Response data = resource.getPureModelContextData("test.legend", "blank-prod", "2.0.0", null, false,true, null);
Assert.assertFalse(((PureModelContextData)data.getEntity()).getElements().isEmpty());
Assert.assertEquals(((PureModelContextData)data.getEntity()).getElements().size(), 2);

Expand All @@ -77,7 +77,7 @@ public void loadPMCD()
@Test
public void loadDependenciesPMCD()
{
Response data = resource.getPureModelContextData(List.of(new ProjectVersion("org.finos.legend","second-project","1.0.1"), new ProjectVersion("org.finos.legend","first-project","1.0.2")), null, true, null);
Response data = resource.getPureModelContextData(List.of(new ProjectVersion("org.finos.legend","second-project","1.0.1"), new ProjectVersion("org.finos.legend","first-project","1.0.2")), null, true, true, null);
Assert.assertFalse(((PureModelContextData)data.getEntity()).getElements().isEmpty());
Assert.assertEquals(6, ((PureModelContextData)data.getEntity()).getElements().size());
Optional<Class> optionalPersonClass = ((PureModelContextData)data.getEntity())
Expand Down
Loading
Loading