From c63841b1a58f6f2c8e8e7d84838416f7a2cc6f74 Mon Sep 17 00:00:00 2001 From: Rafael Bey <24432403+rafaelbey@users.noreply.github.com> Date: Mon, 6 Nov 2023 15:18:15 -0500 Subject: [PATCH] Enhance model loader to support fetching pmcd from workspaces (#2437) --- .../pom.xml | 11 ++ .../pure/modelManager/sdlc/SDLCFetcher.java | 113 +++++++++++ .../pure/modelManager/sdlc/SDLCLoader.java | 90 +++------ .../sdlc/workspace/WorkspaceSDLCLoader.java | 182 ++++++++++++++++++ .../modelManager/sdlc/TestSDLCLoader.java | 90 ++++++++- .../pure/modelManager/ModelManager.java | 16 +- .../pure/v1/model/context/AlloySDLC.java | 6 + .../pure/v1/model/context/PureSDLC.java | 6 + .../protocol/pure/v1/model/context/SDLC.java | 9 +- .../pure/v1/model/context/SDLCVisitor.java | 25 +++ .../pure/v1/model/context/WorkspaceSDLC.java | 61 ++++++ .../legend-engine-xt-graphQL-query/pom.xml | 15 -- .../engine/query/graphQL/api/GraphQL.java | 134 ++----------- .../engine/query/graphQL/api/MyCookie.java | 105 ---------- .../graphQL/api/test/TestGraphQLAPI.java | 13 +- .../directives/TestTotalCountDirective.java | 5 +- .../pom.xml | 17 -- .../project/ProjectCoordinateLoader.java | 178 +---------------- 18 files changed, 574 insertions(+), 502 deletions(-) create mode 100644 legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/main/java/org/finos/legend/engine/language/pure/modelManager/sdlc/SDLCFetcher.java create mode 100644 legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/main/java/org/finos/legend/engine/language/pure/modelManager/sdlc/workspace/WorkspaceSDLCLoader.java create mode 100644 legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/SDLCVisitor.java create mode 100644 legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/WorkspaceSDLC.java delete mode 100644 legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/src/main/java/org/finos/legend/engine/query/graphQL/api/MyCookie.java diff --git a/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/pom.xml b/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/pom.xml index 8ee22a2096a..2e78805e043 100644 --- a/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/pom.xml +++ b/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/pom.xml @@ -26,6 +26,17 @@ Legend Engine - Language Pure - Model Manager - SDLC + + org.finos.legend.shared + legend-shared-pac4j-gitlab + + + * + * + + + + org.finos.legend.engine diff --git a/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/main/java/org/finos/legend/engine/language/pure/modelManager/sdlc/SDLCFetcher.java b/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/main/java/org/finos/legend/engine/language/pure/modelManager/sdlc/SDLCFetcher.java new file mode 100644 index 00000000000..1b467eefe74 --- /dev/null +++ b/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/main/java/org/finos/legend/engine/language/pure/modelManager/sdlc/SDLCFetcher.java @@ -0,0 +1,113 @@ +// Copyright 2023 Goldman Sachs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package org.finos.legend.engine.language.pure.modelManager.sdlc; + +import io.opentracing.Scope; +import io.opentracing.Span; +import io.opentracing.util.GlobalTracer; +import java.util.List; +import java.util.function.Function; +import javax.security.auth.Subject; +import org.apache.http.impl.client.CloseableHttpClient; +import org.eclipse.collections.api.list.MutableList; +import org.eclipse.collections.impl.utility.ListIterate; +import org.finos.legend.engine.language.pure.modelManager.sdlc.alloy.AlloySDLCLoader; +import org.finos.legend.engine.language.pure.modelManager.sdlc.pure.PureServerLoader; +import org.finos.legend.engine.language.pure.modelManager.sdlc.workspace.WorkspaceSDLCLoader; +import org.finos.legend.engine.protocol.pure.v1.model.context.AlloySDLC; +import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData; +import org.finos.legend.engine.protocol.pure.v1.model.context.PureSDLC; +import org.finos.legend.engine.protocol.pure.v1.model.context.SDLCVisitor; +import org.finos.legend.engine.protocol.pure.v1.model.context.WorkspaceSDLC; +import org.finos.legend.engine.shared.core.kerberos.SubjectTools; +import org.finos.legend.engine.shared.core.operational.errorManagement.EngineException; +import org.pac4j.core.profile.CommonProfile; + +final class SDLCFetcher implements SDLCVisitor +{ + private final Span parentSpan; + private final String clientVersion; + private final Function, CloseableHttpClient> httpClientProvider; + private final MutableList pm; + private final PureServerLoader pureLoader; + private final AlloySDLCLoader alloyLoader; + private final WorkspaceSDLCLoader workspaceLoader; + + public SDLCFetcher(Span parentSpan, String clientVersion, Function, CloseableHttpClient> httpClientProvider, MutableList pm, PureServerLoader pureLoader, AlloySDLCLoader alloyLoader, WorkspaceSDLCLoader workspaceLoader) + { + this.parentSpan = parentSpan; + this.clientVersion = clientVersion; + this.httpClientProvider = httpClientProvider; + this.pm = pm; + this.pureLoader = pureLoader; + this.alloyLoader = alloyLoader; + this.workspaceLoader = workspaceLoader; + } + + @Override + public PureModelContextData visit(AlloySDLC sdlc) + { + parentSpan.setTag("sdlc", "alloy"); + try (Scope ignore = GlobalTracer.get().buildSpan("Request Alloy Metadata").startActive(true)) + { + PureModelContextData loadedProject = this.alloyLoader.loadAlloyProject(pm, sdlc, clientVersion, this.httpClientProvider); + loadedProject.origin.sdlcInfo.packageableElementPointers = sdlc.packageableElementPointers; + List missingPaths = this.alloyLoader.checkAllPathsExist(loadedProject, sdlc); + if (missingPaths.isEmpty()) + { + return loadedProject; + } + else + { + throw new EngineException("The following entities:" + missingPaths + " do not exist in the project data loaded from the metadata server. " + + "Please make sure the corresponding Gitlab pipeline for version " + (this.alloyLoader.isLatestRevision(sdlc) ? "latest" : sdlc.version) + " has completed and also metadata server has updated with corresponding entities " + + "by confirming the data returned from this API ."); + } + } + } + + @Override + public PureModelContextData visit(PureSDLC pureSDLC) + { + parentSpan.setTag("sdlc", "pure"); + try (Scope ignore = GlobalTracer.get().buildSpan("Request Pure Metadata").startActive(true)) + { + Subject subject = SubjectTools.getCurrentSubject(); + + return ListIterate.injectInto( + new PureModelContextData.Builder(), + pureSDLC.packageableElementPointers, + (builder, pointers) -> builder.withPureModelContextData(this.pureLoader.loadPurePackageableElementPointer(pm, pointers, clientVersion, subject == null ? "" : "?auth=kerberos", pureSDLC.overrideUrl)) + ).distinct().sorted().build(); + } + } + + @Override + public PureModelContextData visit(WorkspaceSDLC sdlc) + { + parentSpan.setTag("sdlc", "workspace"); + parentSpan.setTag("project", sdlc.project); + parentSpan.setTag("workspace", sdlc.getWorkspace()); + parentSpan.setTag("isGroupWorkspace", sdlc.isGroupWorkspace); + + try (Scope scope = GlobalTracer.get().buildSpan("Request Workspace Metadata").startActive(true)) + { + PureModelContextData loadedProject = this.workspaceLoader.loadWorkspace(pm, sdlc, this.httpClientProvider); + PureModelContextData sdlcDependenciesPMCD = this.workspaceLoader.getSDLCDependenciesPMCD(pm, this.clientVersion, sdlc, this.httpClientProvider); + return loadedProject.combine(sdlcDependenciesPMCD); + } + } +} diff --git a/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/main/java/org/finos/legend/engine/language/pure/modelManager/sdlc/SDLCLoader.java b/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/main/java/org/finos/legend/engine/language/pure/modelManager/sdlc/SDLCLoader.java index 33ad3141890..5ffeff7bdaa 100644 --- a/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/main/java/org/finos/legend/engine/language/pure/modelManager/sdlc/SDLCLoader.java +++ b/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/main/java/org/finos/legend/engine/language/pure/modelManager/sdlc/SDLCLoader.java @@ -19,6 +19,11 @@ import io.opentracing.Span; import io.opentracing.tag.Tags; import io.opentracing.util.GlobalTracer; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; +import java.util.function.Supplier; +import javax.security.auth.Subject; import org.apache.http.HttpEntity; import org.apache.http.HttpStatus; import org.apache.http.client.methods.CloseableHttpResponse; @@ -31,12 +36,12 @@ import org.eclipse.collections.api.list.MutableList; import org.eclipse.collections.api.set.primitive.IntSet; import org.eclipse.collections.impl.factory.primitive.IntSets; -import org.eclipse.collections.impl.utility.ListIterate; import org.finos.legend.engine.language.pure.modelManager.ModelLoader; import org.finos.legend.engine.language.pure.modelManager.ModelManager; import org.finos.legend.engine.language.pure.modelManager.sdlc.alloy.AlloySDLCLoader; import org.finos.legend.engine.language.pure.modelManager.sdlc.configuration.MetaDataServerConfiguration; import org.finos.legend.engine.language.pure.modelManager.sdlc.pure.PureServerLoader; +import org.finos.legend.engine.language.pure.modelManager.sdlc.workspace.WorkspaceSDLCLoader; import org.finos.legend.engine.protocol.pure.v1.model.context.AlloySDLC; import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContext; import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData; @@ -54,13 +59,6 @@ import org.pac4j.core.profile.CommonProfile; import org.slf4j.Logger; -import javax.security.auth.Subject; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.function.Supplier; - import static io.opentracing.propagation.Format.Builtin.HTTP_HEADERS; import static org.finos.legend.engine.shared.core.kerberos.ExecSubject.exec; @@ -72,6 +70,7 @@ public class SDLCLoader implements ModelLoader private final Supplier subjectProvider; private final PureServerLoader pureLoader; private final AlloySDLCLoader alloyLoader; + private final WorkspaceSDLCLoader workspaceLoader; private final Function, CloseableHttpClient> httpClientProvider; public SDLCLoader(MetaDataServerConfiguration metaDataServerConfiguration, Supplier subjectProvider) @@ -91,18 +90,21 @@ public SDLCLoader(MetaDataServerConfiguration metaDataServerConfiguration, Suppl public SDLCLoader(MetaDataServerConfiguration metaDataServerConfiguration, Supplier subjectProvider, PureServerLoader pureLoader, Function, CloseableHttpClient> httpClientProvider) { - this.subjectProvider = subjectProvider; - this.pureLoader = pureLoader; - this.alloyLoader = new AlloySDLCLoader(metaDataServerConfiguration); - this.httpClientProvider = httpClientProvider; + this(metaDataServerConfiguration, subjectProvider, pureLoader, httpClientProvider, new AlloySDLCLoader(metaDataServerConfiguration)); } public SDLCLoader(MetaDataServerConfiguration metaDataServerConfiguration, Supplier subjectProvider, PureServerLoader pureLoader, Function, CloseableHttpClient> httpClientProvider, AlloySDLCLoader alloyLoader) + { + this(subjectProvider, pureLoader, httpClientProvider, alloyLoader, new WorkspaceSDLCLoader(metaDataServerConfiguration.sdlc)); + } + + public SDLCLoader(Supplier subjectProvider, PureServerLoader pureLoader, Function, CloseableHttpClient> httpClientProvider, AlloySDLCLoader alloyLoader, WorkspaceSDLCLoader workspaceLoader) { this.subjectProvider = subjectProvider; this.pureLoader = pureLoader; this.alloyLoader = alloyLoader; this.httpClientProvider = httpClientProvider; + this.workspaceLoader = workspaceLoader; } private Subject getSubject() @@ -121,6 +123,7 @@ private Subject getSubject() @Override public void setModelManager(ModelManager modelManager) { + this.workspaceLoader.setModelManager(modelManager); } @Override @@ -170,55 +173,18 @@ public PureModelContextData load(MutableList pm, PureModelContext PureModelContextPointer context = (PureModelContextPointer) ctx; Assert.assertTrue(clientVersion != null, () -> "Client version should be set when pulling metadata from the metadata repository"); - Function0 fetchMetadata; - - final Subject subject = getSubject(); - - if (context.sdlcInfo instanceof PureSDLC) - { - fetchMetadata = () -> - { - parentSpan.setTag("sdlc", "pure"); - try (Scope scope = GlobalTracer.get().buildSpan("Request Pure Metadata").startActive(true)) - { - return ListIterate.injectInto( - new PureModelContextData.Builder(), - context.sdlcInfo.packageableElementPointers, - (builder, pointers) -> builder.withPureModelContextData(this.pureLoader.loadPurePackageableElementPointer(pm, pointers, clientVersion, subject == null ? "" : "?auth=kerberos", ((PureSDLC) context.sdlcInfo).overrideUrl)) - ).distinct().sorted().build(); - } - }; - } - else if (context.sdlcInfo instanceof AlloySDLC) - { - fetchMetadata = () -> - { - parentSpan.setTag("sdlc", "alloy"); - try (Scope scope = GlobalTracer.get().buildSpan("Request Alloy Metadata").startActive(true)) - { - AlloySDLC sdlc = (AlloySDLC) context.sdlcInfo; - PureModelContextData loadedProject = this.alloyLoader.loadAlloyProject(pm, sdlc, clientVersion, this.httpClientProvider); - loadedProject.origin.sdlcInfo.packageableElementPointers = sdlc.packageableElementPointers; - List missingPaths = this.alloyLoader.checkAllPathsExist(loadedProject, sdlc); - if (missingPaths.isEmpty()) - { - return loadedProject; - } - else - { - throw new EngineException("The following entities:" + missingPaths + " do not exist in the project data loaded from the metadata server. " + - "Please make sure the corresponding Gitlab pipeline for version " + (this.alloyLoader.isLatestRevision(sdlc) ? "latest" : sdlc.version) + " has completed and also metadata server has updated with corresponding entities " + - "by confirming the data returned from this API ."); - } - } - }; - } - else - { - throw new UnsupportedOperationException("To Code"); - } + SDLCFetcher fetcher = new SDLCFetcher( + parentSpan, + clientVersion, + this.httpClientProvider, + pm, + this.pureLoader, + this.alloyLoader, + this.workspaceLoader + ); - PureModelContextData metaData = subject == null ? fetchMetadata.value() : exec(subject, fetchMetadata::value); + Subject subject = getSubject(); + PureModelContextData metaData = subject == null ? context.sdlcInfo.accept(fetcher) : exec(subject, () -> context.sdlcInfo.accept(fetcher)); if (metaData.origin != null) { @@ -314,7 +280,7 @@ public static PureModelContextData loadMetadataFromHTTPURL(MutableList= 300) { - String msg = EntityUtils.toString(entity); + String msg = entity != null ? EntityUtils.toString(entity) : response.getStatusLine().getReasonPhrase(); response.close(); throw new EngineException("Error response from " + httpRequest.getURI() + ", HTTP" + statusCode + "\n" + msg); } diff --git a/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/main/java/org/finos/legend/engine/language/pure/modelManager/sdlc/workspace/WorkspaceSDLCLoader.java b/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/main/java/org/finos/legend/engine/language/pure/modelManager/sdlc/workspace/WorkspaceSDLCLoader.java new file mode 100644 index 00000000000..950238c6aeb --- /dev/null +++ b/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/main/java/org/finos/legend/engine/language/pure/modelManager/sdlc/workspace/WorkspaceSDLCLoader.java @@ -0,0 +1,182 @@ +// Copyright 2023 Goldman Sachs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package org.finos.legend.engine.language.pure.modelManager.sdlc.workspace; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.opentracing.Scope; +import io.opentracing.Span; +import io.opentracing.util.GlobalTracer; +import java.io.InputStream; +import java.util.List; +import java.util.function.Function; +import javax.security.auth.Subject; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.BasicCookieStore; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.message.BasicHeader; +import org.eclipse.collections.api.list.MutableList; +import org.finos.legend.engine.language.pure.modelManager.ModelManager; +import org.finos.legend.engine.language.pure.modelManager.sdlc.SDLCLoader; +import org.finos.legend.engine.language.pure.modelManager.sdlc.configuration.MetadataServerPrivateAccessTokenConfiguration; +import org.finos.legend.engine.language.pure.modelManager.sdlc.configuration.ServerConnectionConfiguration; +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 org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextPointer; +import org.finos.legend.engine.protocol.pure.v1.model.context.WorkspaceSDLC; +import org.finos.legend.engine.shared.core.ObjectMapperFactory; +import org.finos.legend.engine.shared.core.kerberos.ExecSubject; +import org.finos.legend.engine.shared.core.kerberos.HttpClientBuilder; +import org.finos.legend.engine.shared.core.kerberos.ProfileManagerHelper; +import org.finos.legend.engine.shared.core.operational.logs.LoggingEventType; +import org.finos.legend.server.pac4j.gitlab.GitlabPersonalAccessTokenProfile; +import org.pac4j.core.profile.CommonProfile; + +public class WorkspaceSDLCLoader +{ + private static final TypeReference> SDLC_PROJECT_DEPENDENCY_TYPE = new TypeReference>() + { + }; + + private final ServerConnectionConfiguration sdlcServerConnectionConfig; + private final ObjectMapper mapper; + private ModelManager modelManager; + + public WorkspaceSDLCLoader(ServerConnectionConfiguration sdlcServerConnectionConfig) + { + this.sdlcServerConnectionConfig = sdlcServerConnectionConfig; + this.mapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports(); + } + + public PureModelContextData loadWorkspace(MutableList pm, WorkspaceSDLC sdlc, Function, CloseableHttpClient> httpClientProvider) + { + String url = sdlcServerConnectionConfig.getBaseUrl() + "/api/projects/" + sdlc.project + (sdlc.isGroupWorkspace ? "/groupWorkspaces/" : "/workspaces/") + sdlc.getWorkspace() + "/pureModelContextData"; + return SDLCLoader.loadMetadataFromHTTPURL(pm, LoggingEventType.METADATA_REQUEST_ALLOY_PROJECT_START, LoggingEventType.METADATA_REQUEST_ALLOY_PROJECT_STOP, url, httpClientProvider, x -> prepareHttpRequest(pm, x)); + } + + public void setModelManager(ModelManager modelManager) + { + this.modelManager = modelManager; + } + + public PureModelContextData getSDLCDependenciesPMCD(MutableList pm, String clientVersion, WorkspaceSDLC sdlc, Function, CloseableHttpClient> httpClientProvider) + { + CloseableHttpClient httpclient; + + if (httpClientProvider != null) + { + httpclient = httpClientProvider.apply(pm); + } + else + { + httpclient = (CloseableHttpClient) HttpClientBuilder.getHttpClient(new BasicCookieStore()); + } + + try ( + CloseableHttpClient client = httpclient; + Scope scope = GlobalTracer.get().buildSpan("Load project upstream dependencies").startActive(true) + ) + { + String url = String.format("%s/api/projects/%s/%s/%s/revisions/HEAD/upstreamProjects", + sdlcServerConnectionConfig.getBaseUrl(), + sdlc.project, + sdlc.isGroupWorkspace ? "groupWorkspaces" : "workspaces", + sdlc.getWorkspace()); + + HttpGet httpRequest = this.prepareHttpRequest(pm, url); + HttpEntity entity = SDLCLoader.execHttpRequest(scope.span(), client, httpRequest); + + try (InputStream content = entity.getContent()) + { + List dependencies = mapper.readValue(content, SDLC_PROJECT_DEPENDENCY_TYPE); + + PureModelContextData.Builder builder = PureModelContextData.newBuilder(); + + dependencies.forEach(dependency -> + { + builder.addPureModelContextData(this.loadDependencyData(pm, clientVersion, dependency)); + }); + + builder.removeDuplicates(); + return builder.build(); + } + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + private HttpGet prepareHttpRequest(MutableList pm, String url) + { + HttpGet httpRequest = null; + + if (this.sdlcServerConnectionConfig.pac4j != null && this.sdlcServerConnectionConfig.pac4j instanceof MetadataServerPrivateAccessTokenConfiguration) + { + String patHeaderName = ((MetadataServerPrivateAccessTokenConfiguration) this.sdlcServerConnectionConfig.pac4j).accessTokenHeaderName; + MutableList patProfiles = pm.selectInstancesOf(GitlabPersonalAccessTokenProfile.class); + if (patProfiles.getFirst() != null) + { + httpRequest = new HttpGet(String.format("%s?client_name=%s", url, patProfiles.getFirst().getClientName())); + httpRequest.addHeader(new BasicHeader(patHeaderName, patProfiles.getFirst().getPersonalAccessToken())); + } + } + + if (httpRequest == null) + { + httpRequest = new HttpGet(url); + } + + return httpRequest; + } + + private PureModelContextData loadDependencyData(MutableList profiles, String clientVersion, SDLCProjectDependency dependency) + { + Subject subject = ProfileManagerHelper.extractSubject(profiles); + PureModelContextPointer pointer = new PureModelContextPointer(); + AlloySDLC sdlcInfo = new AlloySDLC(); + sdlcInfo.groupId = dependency.getGroupId(); + sdlcInfo.artifactId = dependency.getArtifactId(); + sdlcInfo.version = dependency.getVersionId(); + pointer.sdlcInfo = sdlcInfo; + return subject == null ? + this.modelManager.loadData(pointer, PureClientVersions.production, profiles) : + ExecSubject.exec(subject, () -> this.modelManager.loadData(pointer, clientVersion, profiles)); + } + + private static class SDLCProjectDependency + { + public String projectId; + public String versionId; + + public String getGroupId() + { + return projectId.split(":")[0]; + } + + public String getArtifactId() + { + return projectId.split(":")[1]; + } + + public String getVersionId() + { + return versionId; + } + } +} diff --git a/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/test/java/org/finos/legend/engine/language/pure/modelManager/sdlc/TestSDLCLoader.java b/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/test/java/org/finos/legend/engine/language/pure/modelManager/sdlc/TestSDLCLoader.java index 41f8e0a7981..69259cf3dc2 100644 --- a/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/test/java/org/finos/legend/engine/language/pure/modelManager/sdlc/TestSDLCLoader.java +++ b/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager-sdlc/src/test/java/org/finos/legend/engine/language/pure/modelManager/sdlc/TestSDLCLoader.java @@ -16,21 +16,29 @@ package org.finos.legend.engine.language.pure.modelManager.sdlc; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.github.tomakehurst.wiremock.client.WireMock; import com.github.tomakehurst.wiremock.junit.WireMockClassRule; import com.github.tomakehurst.wiremock.stubbing.Scenario; import io.opentracing.mock.MockSpan; import io.opentracing.mock.MockTracer; import io.opentracing.util.GlobalTracer; +import java.util.List; +import java.util.stream.Collectors; import javax.security.auth.Subject; import org.eclipse.collections.api.factory.Lists; +import org.finos.legend.engine.language.pure.modelManager.ModelManager; import org.finos.legend.engine.language.pure.modelManager.sdlc.configuration.MetaDataServerConfiguration; import org.finos.legend.engine.language.pure.modelManager.sdlc.configuration.ServerConnectionConfiguration; import org.finos.legend.engine.protocol.Protocol; import org.finos.legend.engine.protocol.pure.v1.model.context.AlloySDLC; 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.context.WorkspaceSDLC; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.PackageableElement; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Class; import org.finos.legend.engine.shared.core.ObjectMapperFactory; +import org.finos.legend.engine.shared.core.deployment.DeploymentMode; import org.finos.legend.engine.shared.core.operational.errorManagement.EngineException; import org.junit.After; import org.junit.Assert; @@ -110,6 +118,51 @@ public void testSdlcLoaderDoesNotRetryOnHardFailures() throws Exception } } + @Test + public void testSdlcLoaderForWorkspacesWithoutDependency() throws Exception + { + WorkspaceSDLC sdlcInfo = new WorkspaceSDLC(); + sdlcInfo.project = "proj-1234"; + sdlcInfo.isGroupWorkspace = true; + sdlcInfo.version = "workspaceAbc"; + + PureModelContextPointer pointer = new PureModelContextPointer(); + pointer.sdlcInfo = sdlcInfo; + + configureWireMockForRetries(); + SDLCLoader sdlcLoader = createSDLCLoader(); + PureModelContextData pmcdLoaded = sdlcLoader.load(Lists.fixedSize.empty(), pointer, "v1_32_0", tracer.activeSpan()); + Assert.assertNotNull(pmcdLoaded); + Assert.assertEquals(1, pmcdLoaded.getElements().size()); + Assert.assertEquals("pkg::pkg::myClass", pmcdLoaded.getElements().get(0).getPath()); + } + + @Test + public void testSdlcLoaderForWorkspacesWithDependency() throws Exception + { + WorkspaceSDLC sdlcInfo = new WorkspaceSDLC(); + sdlcInfo.project = "proj-1235"; + sdlcInfo.isGroupWorkspace = false; + sdlcInfo.version = "workspaceAbc"; + + PureModelContextPointer pointer = new PureModelContextPointer(); + pointer.sdlcInfo = sdlcInfo; + + configureWireMockForRetries(); + SDLCLoader sdlcLoader = createSDLCLoader(); + + ModelManager modelManager = new ModelManager(DeploymentMode.TEST, tracer, sdlcLoader); + + PureModelContextData pmcdLoaded = modelManager.loadData(pointer, "v1_32_0", Lists.fixedSize.empty()); + + Assert.assertNotNull(pmcdLoaded); + Assert.assertEquals(2, pmcdLoaded.getElements().size()); + + List paths = pmcdLoaded.getElements().stream().map(PackageableElement::getPath).sorted().collect(Collectors.toList()); + Assert.assertEquals("pkg::pkg::myAnotherClass", paths.get(0)); + Assert.assertEquals("pkg::pkg::myClass", paths.get(1)); + } + private static PureModelContextPointer getPureModelContextPointer() { AlloySDLC sdlcInfo = new AlloySDLC(); @@ -127,6 +180,7 @@ private SDLCLoader createSDLCLoader() MetaDataServerConfiguration serverConfiguration = new MetaDataServerConfiguration(); serverConfiguration.alloy = new ServerConnectionConfiguration(); serverConfiguration.pure = new ServerConnectionConfiguration(); + serverConfiguration.sdlc = new ServerConnectionConfiguration(); serverConfiguration.alloy.host = "localhost"; serverConfiguration.alloy.port = rule.port(); @@ -136,13 +190,19 @@ private SDLCLoader createSDLCLoader() serverConfiguration.pure.port = rule.port(); serverConfiguration.pure.prefix = "/pure"; + serverConfiguration.sdlc.host = "localhost"; + serverConfiguration.sdlc.port = rule.port(); + serverConfiguration.sdlc.prefix = "/sdlc"; + return new SDLCLoader(serverConfiguration, Subject::new); } private static void configureWireMockForRetries() throws JsonProcessingException { + ObjectMapper objectMapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports(); + PureModelContextData data = PureModelContextData.newPureModelContextData(new Protocol(), new PureModelContextPointer(), Lists.fixedSize.empty()); - String pmcdJson = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports().writeValueAsString(data); + String pmcdJson = objectMapper.writeValueAsString(data); WireMock.stubFor(WireMock.get("/alloy/projects/groupId/artifactId/versions/1.0.0/pureModelContextData?clientVersion=v1_32_0") .inScenario("RETRY_FAILURES") @@ -161,6 +221,34 @@ private static void configureWireMockForRetries() throws JsonProcessingException .whenScenarioStateIs("FAILED_2") .willReturn(WireMock.okJson(pmcdJson)) .willSetStateTo("FAILED_3")); + + + Class t = new Class(); + t.name = "myClass"; + t._package = "pkg::pkg"; + PureModelContextData data2 = PureModelContextData.newPureModelContextData(new Protocol(), new PureModelContextPointer(), Lists.fixedSize.with(t)); + String pmcdJson2 = objectMapper.writeValueAsString(data2); + + Class t2 = new Class(); + t2.name = "myAnotherClass"; + t2._package = "pkg::pkg"; + PureModelContextData dataDep = PureModelContextData.newPureModelContextData(new Protocol(), new PureModelContextPointer(), Lists.fixedSize.with(t2)); + String pmcdJsonDep = objectMapper.writeValueAsString(dataDep); + + WireMock.stubFor(WireMock.get("/sdlc/api/projects/proj-1234/groupWorkspaces/workspaceAbc/pureModelContextData") + .willReturn(WireMock.okJson(pmcdJson2))); + + WireMock.stubFor(WireMock.get("/sdlc/api/projects/proj-1234/groupWorkspaces/workspaceAbc/revisions/HEAD/upstreamProjects") + .willReturn(WireMock.okJson("[]"))); + + WireMock.stubFor(WireMock.get("/sdlc/api/projects/proj-1235/workspaces/workspaceAbc/pureModelContextData") + .willReturn(WireMock.okJson(pmcdJson2))); + + WireMock.stubFor(WireMock.get("/sdlc/api/projects/proj-1235/workspaces/workspaceAbc/revisions/HEAD/upstreamProjects") + .willReturn(WireMock.okJson("[{\"projectId\": \"org.finos.legend.dependency:models\",\"versionId\": \"2.0.1\"}]"))); + + WireMock.stubFor(WireMock.get("/alloy/projects/org.finos.legend.dependency/models/versions/2.0.1/pureModelContextData?clientVersion=v1_32_0") + .willReturn(WireMock.okJson(pmcdJsonDep))); } private static void configureWireMockForNoRetries() throws JsonProcessingException diff --git a/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager/src/main/java/org/finos/legend/engine/language/pure/modelManager/ModelManager.java b/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager/src/main/java/org/finos/legend/engine/language/pure/modelManager/ModelManager.java index 6b188225374..123dc45665c 100644 --- a/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager/src/main/java/org/finos/legend/engine/language/pure/modelManager/ModelManager.java +++ b/legend-engine-core/legend-engine-core-language-pure/legend-engine-language-pure-modelManager/src/main/java/org/finos/legend/engine/language/pure/modelManager/ModelManager.java @@ -18,7 +18,10 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import io.opentracing.Scope; +import io.opentracing.Tracer; import io.opentracing.util.GlobalTracer; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import org.eclipse.collections.api.block.procedure.Procedure; import org.eclipse.collections.api.list.MutableList; import org.eclipse.collections.api.tuple.Pair; @@ -36,10 +39,6 @@ import org.finos.legend.engine.shared.core.operational.Assert; import org.finos.legend.engine.shared.core.operational.errorManagement.EngineException; import org.pac4j.core.profile.CommonProfile; -import org.slf4j.Logger; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; public class ModelManager { @@ -57,9 +56,16 @@ public class ModelManager public final Cache pureModelCache = CacheBuilder.newBuilder().recordStats().softValues().expireAfterAccess(30, TimeUnit.MINUTES).build(); private final DeploymentMode deploymentMode; private final MutableList modelLoaders; + private final Tracer tracer; public ModelManager(DeploymentMode mode, ModelLoader... modelLoaders) { + this(mode, GlobalTracer.get(), modelLoaders); + } + + public ModelManager(DeploymentMode mode, Tracer tracer, ModelLoader... modelLoaders) + { + this.tracer = tracer; this.modelLoaders = Lists.mutable.of(modelLoaders); this.modelLoaders.forEach((Procedure) loader -> loader.setModelManager(this)); this.deploymentMode = mode; @@ -104,7 +110,7 @@ public String getLambdaReturnType(Lambda lambda, PureModelContext context, Strin // Remove clientVersion public PureModelContextData loadData(PureModelContext context, String clientVersion, MutableList pm) { - try (Scope scope = GlobalTracer.get().buildSpan("Load Model").startActive(true)) + try (Scope scope = tracer.buildSpan("Load Model").startActive(true)) { scope.span().setTag("context", context.getClass().getSimpleName()); if (context instanceof PureModelContextData) diff --git a/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/AlloySDLC.java b/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/AlloySDLC.java index b261bff20d9..9e8456e87c5 100644 --- a/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/AlloySDLC.java +++ b/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/AlloySDLC.java @@ -50,4 +50,10 @@ public int hashCode() { return Objects.hashCode(this.project) + 89 * Objects.hashCode(this.version) + 17 * Objects.hashCode(this.groupId) + 17 * Objects.hashCode(artifactId); } + + @Override + public T accept(SDLCVisitor visitor) + { + return visitor.visit(this); + } } diff --git a/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/PureSDLC.java b/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/PureSDLC.java index 1de16fb4977..a5c3fbacc9a 100644 --- a/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/PureSDLC.java +++ b/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/PureSDLC.java @@ -40,4 +40,10 @@ public int hashCode() { return Objects.hash(this.overrideUrl, this.version, this.baseVersion, this.packageableElementPointers); } + + @Override + public T accept(SDLCVisitor visitor) + { + return visitor.visit(this); + } } diff --git a/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/SDLC.java b/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/SDLC.java index 88ca3ab4a84..d4034434c1f 100644 --- a/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/SDLC.java +++ b/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/SDLC.java @@ -16,7 +16,6 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; - import java.util.Collections; import java.util.List; import java.util.Objects; @@ -24,7 +23,8 @@ @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "_type") @JsonSubTypes({ @JsonSubTypes.Type(value = PureSDLC.class, name = "pure"), - @JsonSubTypes.Type(value = AlloySDLC.class, name = "alloy") + @JsonSubTypes.Type(value = AlloySDLC.class, name = "alloy"), + @JsonSubTypes.Type(value = WorkspaceSDLC.class, name = "workspace") }) public abstract class SDLC { @@ -52,4 +52,9 @@ public int hashCode() { return Objects.hash(version, packageableElementPointers); } + + public T accept(SDLCVisitor visitor) + { + throw new UnsupportedOperationException("Not implemented"); + } } diff --git a/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/SDLCVisitor.java b/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/SDLCVisitor.java new file mode 100644 index 00000000000..f0712e8e930 --- /dev/null +++ b/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/SDLCVisitor.java @@ -0,0 +1,25 @@ +// Copyright 2023 Goldman Sachs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package org.finos.legend.engine.protocol.pure.v1.model.context; + +public interface SDLCVisitor +{ + T visit(AlloySDLC alloySDLC); + + T visit(PureSDLC pureSDLC); + + T visit(WorkspaceSDLC workspaceSDLC); +} diff --git a/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/WorkspaceSDLC.java b/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/WorkspaceSDLC.java new file mode 100644 index 00000000000..fd2ea504951 --- /dev/null +++ b/legend-engine-core/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/context/WorkspaceSDLC.java @@ -0,0 +1,61 @@ +// Copyright 2020 Goldman Sachs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package org.finos.legend.engine.protocol.pure.v1.model.context; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Objects; + +public class WorkspaceSDLC extends SDLC +{ + @JsonProperty(value = "project") + public String project; + + @JsonProperty(value = "isGroupWorkspace") + public boolean isGroupWorkspace; + + @JsonIgnore + public String getWorkspace() + { + return this.version; + } + + @Override + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if ((o == null) || (o.getClass() != this.getClass())) + { + return false; + } + WorkspaceSDLC that = (WorkspaceSDLC) o; + return Objects.equals(this.project, that.project) && Objects.equals(this.version, that.version) && Objects.equals(this.isGroupWorkspace, that.isGroupWorkspace); + } + + @Override + public int hashCode() + { + return Objects.hashCode(this.project) + 89 * Objects.hashCode(this.version) + 17 * Objects.hashCode(this.isGroupWorkspace); + } + + @Override + public T accept(SDLCVisitor visitor) + { + return visitor.visit(this); + } +} diff --git a/legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/pom.xml b/legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/pom.xml index 87baf707ac8..d00c433bc79 100644 --- a/legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/pom.xml +++ b/legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/pom.xml @@ -192,21 +192,6 @@ jackson-databind - - org.apache.httpcomponents - httpclient - - - commons-codec - commons-codec - - - - - org.apache.httpcomponents - httpcore - - com.google.guava diff --git a/legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/src/main/java/org/finos/legend/engine/query/graphQL/api/GraphQL.java b/legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/src/main/java/org/finos/legend/engine/query/graphQL/api/GraphQL.java index fb7c116a500..529a3af8af7 100644 --- a/legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/src/main/java/org/finos/legend/engine/query/graphQL/api/GraphQL.java +++ b/legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/src/main/java/org/finos/legend/engine/query/graphQL/api/GraphQL.java @@ -14,51 +14,30 @@ package org.finos.legend.engine.query.graphQL.api; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.CookieStore; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.util.EntityUtils; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import javax.security.auth.Subject; +import javax.servlet.http.HttpServletRequest; import org.eclipse.collections.api.list.MutableList; -import org.eclipse.collections.impl.utility.ArrayIterate; import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModel; import org.finos.legend.engine.language.pure.modelManager.ModelManager; import org.finos.legend.engine.language.pure.modelManager.sdlc.configuration.MetaDataServerConfiguration; -import org.finos.legend.engine.plan.execution.result.ConstantResult; -import org.finos.legend.engine.plan.execution.result.Result; import org.finos.legend.engine.protocol.graphQL.metamodel.Document; import org.finos.legend.engine.protocol.graphQL.metamodel.ProtocolToMetamodelTranslator; -import org.finos.legend.engine.protocol.graphQL.metamodel.executable.OperationDefinition; 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 org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextPointer; -import org.finos.legend.engine.shared.core.ObjectMapperFactory; -import org.finos.legend.engine.shared.core.kerberos.HttpClientBuilder; +import org.finos.legend.engine.protocol.pure.v1.model.context.WorkspaceSDLC; import org.finos.legend.engine.shared.core.kerberos.ProfileManagerHelper; -import org.finos.legend.engine.shared.core.operational.errorManagement.EngineException; import org.pac4j.core.profile.CommonProfile; -import javax.security.auth.Subject; -import javax.servlet.http.HttpServletRequest; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.List; - public abstract class GraphQL { protected ModelManager modelManager; - protected MetaDataServerConfiguration metadataserver; public GraphQL(ModelManager modelManager, MetaDataServerConfiguration metadataserver) { this.modelManager = modelManager; - this.metadataserver = metadataserver; } public static org.finos.legend.pure.generated.Root_meta_external_query_graphQL_metamodel_sdl_Document toPureModel(Document document, PureModel pureModel) @@ -68,106 +47,21 @@ public static org.finos.legend.pure.generated.Root_meta_external_query_graphQL_m protected PureModel loadSDLCProjectModel(MutableList profiles, HttpServletRequest request, String projectId, String workspaceId, boolean isGroupWorkspace) throws PrivilegedActionException { - Subject subject = ProfileManagerHelper.extractSubject(profiles); - return subject == null ? - getSDLCProjectPureModel(profiles, request, projectId, workspaceId, isGroupWorkspace) : - Subject.doAs(subject, (PrivilegedExceptionAction) () -> getSDLCProjectPureModel(profiles, request, projectId, workspaceId, isGroupWorkspace)); - } - - private static class SDLCProjectDependency - { - public String projectId; - public String versionId; - - public String getGroupId() - { - return projectId.split(":")[0]; - } - - public String getArtifactId() - { - return projectId.split(":")[1]; - } - - public String getVersionId() - { - return versionId; - } - } - - private PureModelContextData getSDLCDependenciesPMCD(MutableList profiles, CookieStore cookieStore, String projectId, String workspaceId, boolean isGroupWorkspace) - { - try (CloseableHttpClient client = (CloseableHttpClient) HttpClientBuilder.getHttpClient(cookieStore)) - { - HttpGet req = new HttpGet("http://" + metadataserver.getSdlc().host + ":" + metadataserver.getSdlc().port + "/api/projects/" + projectId + (isGroupWorkspace ? "/groupWorkspaces/" : "/workspaces/") + workspaceId + "/revisions/" + "HEAD" + "/upstreamProjects"); - try (CloseableHttpResponse res = client.execute(req)) - { - ObjectMapper mapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports(); - List dependencies = mapper.readValue(EntityUtils.toString(res.getEntity()), new TypeReference>() {}); - PureModelContextData.Builder builder = PureModelContextData.newBuilder(); - dependencies.forEach(dependency -> - { - try - { - builder.addPureModelContextData(loadProjectData(profiles, dependency.getGroupId(), dependency.getArtifactId(), dependency.versionId)); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - }); - builder.removeDuplicates(); - return builder.build(); - } - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - - private PureModel getSDLCProjectPureModel(MutableList profiles, HttpServletRequest request, String projectId, String workspaceId, boolean isGroupWorkspace) - { - CookieStore cookieStore = new BasicCookieStore(); - ArrayIterate.forEach(request.getCookies(), c -> cookieStore.addCookie(new MyCookie(c))); - + WorkspaceSDLC sdlcInfo = new WorkspaceSDLC(); + sdlcInfo.project = projectId; + sdlcInfo.version = workspaceId; + sdlcInfo.isGroupWorkspace = isGroupWorkspace; - try (CloseableHttpClient client = (CloseableHttpClient) HttpClientBuilder.getHttpClient(cookieStore)) - { - if (metadataserver == null || metadataserver.getSdlc() == null) - { - throw new EngineException("Please specify the metadataserver.sdlc information in the server configuration"); - } - HttpGet req = new HttpGet("http://" + metadataserver.getSdlc().host + ":" + metadataserver.getSdlc().port + "/api/projects/" + projectId + (isGroupWorkspace ? "/groupWorkspaces/" : "/workspaces/") + workspaceId + "/pureModelContextData"); - try (CloseableHttpResponse res = client.execute(req)) - { - ObjectMapper mapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports(); - PureModelContextData pureModelContextData = mapper.readValue(res.getEntity().getContent(), PureModelContextData.class); - PureModelContextData dependenciesPMCD = getSDLCDependenciesPMCD(profiles, cookieStore, projectId, workspaceId, isGroupWorkspace); - return this.modelManager.loadModel(pureModelContextData.combine(dependenciesPMCD), PureClientVersions.production, profiles, ""); - } - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - - protected PureModel loadProjectModel(MutableList profiles, String groupId, String artifactId, String versionId) throws PrivilegedActionException - { - Subject subject = ProfileManagerHelper.extractSubject(profiles); PureModelContextPointer pointer = new PureModelContextPointer(); - AlloySDLC sdlcInfo = new AlloySDLC(); - sdlcInfo.groupId = groupId; - sdlcInfo.artifactId = artifactId; - sdlcInfo.version = versionId; pointer.sdlcInfo = sdlcInfo; + + Subject subject = ProfileManagerHelper.extractSubject(profiles); return subject == null ? this.modelManager.loadModel(pointer, PureClientVersions.production, profiles, "") : Subject.doAs(subject, (PrivilegedExceptionAction) () -> this.modelManager.loadModel(pointer, PureClientVersions.production, profiles, "")); } - protected PureModelContextData loadProjectData(MutableList profiles, String groupId, String artifactId, String versionId) throws PrivilegedActionException + protected PureModel loadProjectModel(MutableList profiles, String groupId, String artifactId, String versionId) throws PrivilegedActionException { Subject subject = ProfileManagerHelper.extractSubject(profiles); PureModelContextPointer pointer = new PureModelContextPointer(); @@ -177,7 +71,7 @@ protected PureModelContextData loadProjectData(MutableList profil sdlcInfo.version = versionId; pointer.sdlcInfo = sdlcInfo; return subject == null ? - this.modelManager.loadData(pointer, PureClientVersions.production, profiles) : - Subject.doAs(subject, (PrivilegedExceptionAction) () -> this.modelManager.loadData(pointer, PureClientVersions.production, profiles)); + this.modelManager.loadModel(pointer, PureClientVersions.production, profiles, "") : + Subject.doAs(subject, (PrivilegedExceptionAction) () -> this.modelManager.loadModel(pointer, PureClientVersions.production, profiles, "")); } } diff --git a/legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/src/main/java/org/finos/legend/engine/query/graphQL/api/MyCookie.java b/legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/src/main/java/org/finos/legend/engine/query/graphQL/api/MyCookie.java deleted file mode 100644 index 93152da1e14..00000000000 --- a/legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/src/main/java/org/finos/legend/engine/query/graphQL/api/MyCookie.java +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2022 Goldman Sachs -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package org.finos.legend.engine.query.graphQL.api; - -import org.apache.http.cookie.Cookie; - -import java.util.Date; - -public class MyCookie implements Cookie -{ - private javax.servlet.http.Cookie cookie; - - public MyCookie(javax.servlet.http.Cookie cookie) - { - this.cookie = cookie; - } - - @Override - public String getName() - { - return this.cookie.getName(); - } - - @Override - public String getValue() - { - return this.cookie.getValue(); - } - - @Override - public String getComment() - { - return this.cookie.getComment(); - } - - @Override - public String getCommentURL() - { - return ""; - } - - @Override - public Date getExpiryDate() - { - if (this.cookie.getMaxAge() >= 0) - { - return new Date(System.currentTimeMillis() + this.cookie.getMaxAge() * 1000L); - } - throw new RuntimeException(""); - } - - @Override - public boolean isPersistent() - { - return true; - } - - @Override - public String getDomain() - { - return "localhost"; - } - - @Override - public String getPath() - { - return "/"; - } - - @Override - public int[] getPorts() - { - return new int[]{}; - } - - @Override - public boolean isSecure() - { - return false; - } - - @Override - public int getVersion() - { - return this.cookie.getVersion(); - } - - @Override - public boolean isExpired(Date date) - { - return false; - } -} diff --git a/legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/src/test/java/org/finos/legend/engine/query/graphQL/api/test/TestGraphQLAPI.java b/legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/src/test/java/org/finos/legend/engine/query/graphQL/api/test/TestGraphQLAPI.java index 5990eef55c4..04c39c60111 100644 --- a/legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/src/test/java/org/finos/legend/engine/query/graphQL/api/test/TestGraphQLAPI.java +++ b/legend-engine-xts-graphQL/legend-engine-xt-graphQL-query/src/test/java/org/finos/legend/engine/query/graphQL/api/test/TestGraphQLAPI.java @@ -128,7 +128,7 @@ private GraphQLExecute getGraphQLExecute() private GraphQLExecute getGraphQLExecuteWithCache(GraphQLPlanCache cache) { - ModelManager modelManager = new ModelManager(DeploymentMode.TEST); + ModelManager modelManager = createModelManager(); PlanExecutor executor = PlanExecutor.newPlanExecutorWithAvailableStoreExecutors(); MutableList generatorExtensions = Lists.mutable.withAll(ServiceLoader.load(PlanGeneratorExtension.class)); GraphQLExecute graphQLExecute = new GraphQLExecute(modelManager, executor, metaDataServerConfiguration, (pm) -> PureCoreExtensionLoader.extensions().flatCollect(g -> g.extraPureCoreExtensions(pm.getExecutionSupport())), generatorExtensions.flatCollect(PlanGeneratorExtension::getExtraPlanTransformers), cache); @@ -222,7 +222,7 @@ public void testGraphQLExecuteDevAPI_ProcessingTemporalMilestoning_Root() throws @Test public void testGraphQLExecuteDevAPI_Relational_WithDependencies() throws Exception { - ModelManager modelManager = new ModelManager(DeploymentMode.TEST, new SDLCLoader(metaDataServerConfiguration, null)); + ModelManager modelManager = createModelManager(); PlanExecutor executor = PlanExecutor.newPlanExecutorWithAvailableStoreExecutors(); MutableList generatorExtensions = Lists.mutable.withAll(ServiceLoader.load(PlanGeneratorExtension.class)); GraphQLExecute graphQLExecute = new GraphQLExecute(modelManager, executor, metaDataServerConfiguration, (pm) -> PureCoreExtensionLoader.extensions().flatCollect(g -> g.extraPureCoreExtensions(pm.getExecutionSupport())), generatorExtensions.flatCollect(PlanGeneratorExtension::getExtraPlanTransformers)); @@ -252,6 +252,11 @@ public void testGraphQLExecuteDevAPI_Relational_WithDependencies() throws Except Assert.assertEquals(expected, responseAsString(response)); } + private static ModelManager createModelManager() + { + return new ModelManager(DeploymentMode.TEST, new SDLCLoader(metaDataServerConfiguration, null)); + } + @Test public void testGraphQLExecuteDevAPI_RelationalWithParameter() throws Exception @@ -483,7 +488,7 @@ public void testGraphQLExecuteGeneratePlansDevAPI_Relational() @Test public void testGraphQLDebugGenerateGraphFetchDevAPI() { - ModelManager modelManager = new ModelManager(DeploymentMode.TEST); + ModelManager modelManager = createModelManager(); MutableList generatorExtensions = Lists.mutable.withAll(ServiceLoader.load(PlanGeneratorExtension.class)); GraphQLDebug graphQLDebug = new GraphQLDebug(modelManager, metaDataServerConfiguration, (pm) -> PureCoreExtensionLoader.extensions().flatCollect(g -> g.extraPureCoreExtensions(pm.getExecutionSupport()))); HttpServletRequest mockRequest = Mockito.mock(HttpServletRequest.class); @@ -674,7 +679,7 @@ public void testGraphQLExecuteDevAPI_EchoDirective() throws Exception private static Handler buildPMCDMetadataHandler(String path, String resourcePath) throws Exception { - return buildPMCDMetadataHandler(path, resourcePath, null, null); + return buildPMCDMetadataHandler(path, resourcePath, new Protocol("pure", PureClientVersions.production), new PureModelContextPointer()); } private static Handler buildPMCDMetadataHandler(String path, String resourcePath, Protocol serializer, PureModelContextPointer pointer) throws Exception diff --git a/legend-engine-xts-graphQL/legend-engine-xt-graphQL-relational-extension/src/test/java/org/finos/legend/engine/query/graphQL/extension/relational/directives/TestTotalCountDirective.java b/legend-engine-xts-graphQL/legend-engine-xt-graphQL-relational-extension/src/test/java/org/finos/legend/engine/query/graphQL/extension/relational/directives/TestTotalCountDirective.java index 08145f9f25b..f194834514e 100644 --- a/legend-engine-xts-graphQL/legend-engine-xt-graphQL-relational-extension/src/test/java/org/finos/legend/engine/query/graphQL/extension/relational/directives/TestTotalCountDirective.java +++ b/legend-engine-xts-graphQL/legend-engine-xt-graphQL-relational-extension/src/test/java/org/finos/legend/engine/query/graphQL/extension/relational/directives/TestTotalCountDirective.java @@ -27,6 +27,7 @@ import org.finos.legend.engine.language.graphQL.grammar.from.GraphQLGrammarParser; import org.finos.legend.engine.language.pure.grammar.from.PureGrammarParser; import org.finos.legend.engine.language.pure.modelManager.ModelManager; +import org.finos.legend.engine.language.pure.modelManager.sdlc.SDLCLoader; import org.finos.legend.engine.language.pure.modelManager.sdlc.configuration.MetaDataServerConfiguration; import org.finos.legend.engine.language.pure.modelManager.sdlc.configuration.ServerConnectionConfiguration; import org.finos.legend.engine.plan.execution.PlanExecutor; @@ -112,7 +113,7 @@ private GraphQLExecute getGraphQLExecute() private GraphQLExecute getGraphQLExecuteWithCache(GraphQLPlanCache cache) { - ModelManager modelManager = new ModelManager(DeploymentMode.TEST); + ModelManager modelManager = new ModelManager(DeploymentMode.TEST, new SDLCLoader(metaDataServerConfiguration, null)); PlanExecutor executor = PlanExecutor.newPlanExecutorWithAvailableStoreExecutors(); MutableList generatorExtensions = Lists.mutable.withAll(ServiceLoader.load(PlanGeneratorExtension.class)); GraphQLExecute graphQLExecute = new GraphQLExecute(modelManager, executor, metaDataServerConfiguration, (pm) -> PureCoreExtensionLoader.extensions().flatCollect(g -> g.extraPureCoreExtensions(pm.getExecutionSupport())), generatorExtensions.flatCollect(PlanGeneratorExtension::getExtraPlanTransformers), cache); @@ -242,7 +243,7 @@ public void testGraphQLExecuteDevAPI_TotalCountDirective_Caching() throws Except private static Handler buildPMCDMetadataHandler(String path, String resourcePath) throws Exception { - return buildPMCDMetadataHandler(path, resourcePath, null, null); + return buildPMCDMetadataHandler(path, resourcePath, new Protocol(), new PureModelContextPointer()); } private static Handler buildPMCDMetadataHandler(String path, String resourcePath, Protocol serializer, PureModelContextPointer pointer) throws Exception diff --git a/legend-engine-xts-sql/legend-engine-xt-sql-providers/legend-engine-xt-sql-providers-shared/pom.xml b/legend-engine-xts-sql/legend-engine-xt-sql-providers/legend-engine-xt-sql-providers-shared/pom.xml index 5f14306fe7f..d19fd34b368 100644 --- a/legend-engine-xts-sql/legend-engine-xt-sql-providers/legend-engine-xt-sql-providers-shared/pom.xml +++ b/legend-engine-xts-sql/legend-engine-xt-sql-providers/legend-engine-xt-sql-providers-shared/pom.xml @@ -45,11 +45,6 @@ - - javax.ws.rs - javax.ws.rs-api - - org.finos.legend.engine @@ -94,10 +89,6 @@ org.apache.httpcomponents httpclient - - org.apache.httpcomponents - httpcore - @@ -116,10 +107,6 @@ com.fasterxml.jackson.core jackson-databind - - com.fasterxml.jackson.core - jackson-annotations - @@ -154,10 +141,6 @@ commons-io test - - org.finos.legend.shared - legend-shared-pac4j-gitlab - \ No newline at end of file diff --git a/legend-engine-xts-sql/legend-engine-xt-sql-providers/legend-engine-xt-sql-providers-shared/src/main/java/org/finos/legend/engine/query/sql/providers/shared/project/ProjectCoordinateLoader.java b/legend-engine-xts-sql/legend-engine-xt-sql-providers/legend-engine-xt-sql-providers-shared/src/main/java/org/finos/legend/engine/query/sql/providers/shared/project/ProjectCoordinateLoader.java index 507692770eb..6e85e4667cd 100644 --- a/legend-engine-xts-sql/legend-engine-xt-sql-providers/legend-engine-xt-sql-providers-shared/src/main/java/org/finos/legend/engine/query/sql/providers/shared/project/ProjectCoordinateLoader.java +++ b/legend-engine-xts-sql/legend-engine-xt-sql-providers/legend-engine-xt-sql-providers-shared/src/main/java/org/finos/legend/engine/query/sql/providers/shared/project/ProjectCoordinateLoader.java @@ -15,51 +15,25 @@ package org.finos.legend.engine.query.sql.providers.shared.project; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.http.HttpRequest; -import org.apache.http.StatusLine; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; +import java.util.Optional; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.message.BasicHeader; -import org.apache.http.util.EntityUtils; import org.eclipse.collections.api.block.function.Function; import org.eclipse.collections.api.list.MutableList; import org.finos.legend.engine.language.pure.modelManager.ModelManager; -import org.finos.legend.engine.language.pure.modelManager.sdlc.SDLCLoader; -import org.finos.legend.engine.language.pure.modelManager.sdlc.configuration.MetadataServerPrivateAccessTokenConfiguration; import org.finos.legend.engine.language.pure.modelManager.sdlc.configuration.ServerConnectionConfiguration; 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 org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextPointer; -import org.finos.legend.engine.query.sql.providers.shared.utils.TraceUtils; -import org.finos.legend.engine.shared.core.ObjectMapperFactory; +import org.finos.legend.engine.protocol.pure.v1.model.context.WorkspaceSDLC; import org.finos.legend.engine.shared.core.kerberos.HttpClientBuilder; -import org.finos.legend.engine.shared.core.kerberos.ProfileManagerHelper; import org.finos.legend.engine.shared.core.operational.errorManagement.EngineException; -import org.finos.legend.engine.shared.core.operational.logs.LoggingEventType; -import org.finos.legend.server.pac4j.gitlab.GitlabPersonalAccessTokenProfile; import org.pac4j.core.profile.CommonProfile; -import javax.security.auth.Subject; -import javax.ws.rs.core.Response; -import java.net.URI; -import java.security.PrivilegedAction; -import java.util.List; -import java.util.Optional; - public class ProjectCoordinateLoader { - private static final ObjectMapper OBJECT_MAPPER = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports(); - private final ModelManager modelManager; - private final ServerConnectionConfiguration sdlcServerConfig; - private final Function, CloseableHttpClient> httpClientProvider; public ProjectCoordinateLoader(ModelManager modelManager, ServerConnectionConfiguration sdlcServerConfig) { @@ -69,8 +43,6 @@ public ProjectCoordinateLoader(ModelManager modelManager, ServerConnectionConfig public ProjectCoordinateLoader(ModelManager modelManager, ServerConnectionConfiguration sdlcServerConfig, Function, CloseableHttpClient> httpClientProvider) { this.modelManager = modelManager; - this.sdlcServerConfig = sdlcServerConfig; - this.httpClientProvider = httpClientProvider; } public ProjectResolvedContext resolve(ProjectCoordinateWrapper projectCoordinateWrapper, MutableList profiles) @@ -135,146 +107,14 @@ private void enrichCoordinates(AlloySDLC alloySDLC, String coordinates) private PureModelContextData loadProjectPureModelContextData(String project, String workspace, boolean isGroup, MutableList profiles) { - return doAs(ProfileManagerHelper.extractSubject(profiles), () -> - { - String url = String.format("%s/api/projects/%s/%s/%s/pureModelContextData", sdlcServerConfig.getBaseUrl(), project, isGroup ? "groupWorkspaces" : "workspaces", workspace); - PureModelContextData projectPMCD = SDLCLoader.loadMetadataFromHTTPURL(profiles, LoggingEventType.METADATA_REQUEST_ALLOY_PROJECT_START, LoggingEventType.METADATA_REQUEST_ALLOY_PROJECT_STOP, url, httpClientProvider, (String _url) -> - { - HttpGet httpRequest = new HttpGet(_url); - if (this.sdlcServerConfig.pac4j != null && this.sdlcServerConfig.pac4j instanceof MetadataServerPrivateAccessTokenConfiguration) - { - String patHeaderName = ((MetadataServerPrivateAccessTokenConfiguration) this.sdlcServerConfig.pac4j).accessTokenHeaderName; - MutableList patProfiles = profiles.selectInstancesOf(GitlabPersonalAccessTokenProfile.class); - if (patProfiles.getFirst() != null) - { - httpRequest = new HttpGet(String.format("%s?client_name=%s", _url, patProfiles.getFirst().getClientName())); - httpRequest.addHeader(new BasicHeader(patHeaderName, patProfiles.getFirst().getPersonalAccessToken())); - } - } - return httpRequest; - }); - PureModelContextData dependencyPMCD = getSDLCDependenciesPMCD(project, workspace, isGroup, profiles); - - return projectPMCD.combine(dependencyPMCD); - }); - } - - private PureModelContextData getSDLCDependenciesPMCD(String project, String workspace, boolean isGroup, MutableList profiles) - { - return TraceUtils.trace("Get SDLC Dependencies", span -> - { - - span.setTag("project", project); - span.setTag("workspace", workspace); - span.setTag("group", isGroup); - - if (sdlcServerConfig == null) - { - throw new EngineException("SDLC Server configuration must be supplied"); - } - try (CloseableHttpClient client = this.httpClientProvider.apply(profiles)) - { - String url = String.format("%s/api/projects/%s/%s/%s/revisions/HEAD/upstreamProjects", - sdlcServerConfig.getBaseUrl(), - project, - isGroup ? "groupWorkspaces" : "workspaces", - workspace); - - HttpGet httpRequest = new HttpGet(url); - String patHeaderName = ((MetadataServerPrivateAccessTokenConfiguration) this.sdlcServerConfig.pac4j).accessTokenHeaderName; - MutableList patProfiles = profiles.selectInstancesOf(GitlabPersonalAccessTokenProfile.class); - if (patProfiles.getFirst() != null) - { - httpRequest = new HttpGet(String.format("%s?client_name=%s", url, patProfiles.getFirst().getClientName())); - httpRequest.addHeader(new BasicHeader(patHeaderName, patProfiles.getFirst().getPersonalAccessToken())); - } - - try (CloseableHttpResponse response = client.execute(httpRequest)) - { - StatusLine status = response.getStatusLine(); - if (!Response.Status.Family.familyOf(status.getStatusCode()).equals(Response.Status.Family.SUCCESSFUL)) - { - throw new RuntimeException(String.format("Status Code: %s\nReason: %s\nMessage: %s", - status.getStatusCode(), status.getReasonPhrase(), "Error fetching from " + url)); - } - - List dependencies = OBJECT_MAPPER.readValue(EntityUtils.toString(response.getEntity()), new TypeReference>() - { - }); - PureModelContextData.Builder builder = PureModelContextData.newBuilder(); - dependencies.forEach(dependency -> - { - try - { - builder.addPureModelContextData(loadProjectData(profiles, dependency.getGroupId(), dependency.getArtifactId(), dependency.versionId)); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - }); - builder.removeDuplicates(); - return builder.build(); - } - } - catch (Exception e) - { - throw new RuntimeException(e); - } - }); - } - - private PureModelContextData loadProjectData(MutableList profiles, String groupId, String artifactId, String versionId) - { - return TraceUtils.trace("Loading Project Data", span -> - { - - span.setTag("groupId", groupId); - span.setTag("artifactId", artifactId); - span.setTag("versionId", versionId); + WorkspaceSDLC sdlcInfo = new WorkspaceSDLC(); + sdlcInfo.project = project; + sdlcInfo.version = workspace; + sdlcInfo.isGroupWorkspace = isGroup; - Subject subject = ProfileManagerHelper.extractSubject(profiles); - PureModelContextPointer pointer = new PureModelContextPointer(); - AlloySDLC sdlcInfo = new AlloySDLC(); - sdlcInfo.groupId = groupId; - sdlcInfo.artifactId = artifactId; - sdlcInfo.version = versionId; - pointer.sdlcInfo = sdlcInfo; - - return doAs(subject, () -> this.modelManager.loadData(pointer, PureClientVersions.production, profiles)); - }); - } - - private T doAs(Subject subject, PrivilegedAction action) - { - return subject != null ? Subject.doAs(subject, action) : action.run(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - private static class SDLCProjectDependency - { - private final String projectId; - private final String versionId; - - public SDLCProjectDependency(@JsonProperty("projectId") String projectId, @JsonProperty("versionId") String versionId) - { - this.projectId = projectId; - this.versionId = versionId; - } - - public String getGroupId() - { - return projectId.split(":")[0]; - } - - public String getArtifactId() - { - return projectId.split(":")[1]; - } + PureModelContextPointer pointer = new PureModelContextPointer(); + pointer.sdlcInfo = sdlcInfo; - public String getVersionId() - { - return versionId; - } + return this.modelManager.loadData(pointer, PureClientVersions.production, profiles); } } \ No newline at end of file