@finos/legend-application-marketplace
Version:
Legend Marketplace application core
284 lines • 15.1 kB
JavaScript
/**
* Copyright (c) 2020-present, 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.
*/
import { ActionState, assertErrorThrown, isNonNullable, LogEvent, UserSearchService, } from '@finos/legend-shared';
import { LegendApplicationTelemetryHelper, APPLICATION_EVENT, DEFAULT_TAB_SIZE, } from '@finos/legend-application';
import { action, flow, makeObservable, observable } from 'mobx';
import { DepotServerClient, StoreProjectData, } from '@finos/legend-server-depot';
import { MarketplaceServerClient, RegistryServerClient, TerminalAccessServerClient, } from '@finos/legend-server-marketplace';
import { getCurrentUserIDFromEngineServer, V1_entitlementsDataProductDetailsResponseToDataProductDetails, V1_PureGraphManager, V1_RemoteEngine, } from '@finos/legend-graph';
import { LegendMarketplaceEventHelper } from '../__lib__/LegendMarketplaceEventHelper.js';
import { LakehouseContractServerClient, LakehouseIngestServerClient, LakehousePlatformServerClient, LakehouseWorkflowServerClient, PermitWorkflowServerClient, } from '@finos/legend-server-lakehouse';
import { CartStore } from './cart/CartStore.js';
import { PendingTasksCache } from './lakehouse/PendingTasksCache.js';
import { parseGAVCoordinates } from '@finos/legend-storage';
import { V1_deserializeDataSpace } from '@finos/legend-extension-dsl-data-space/graph';
import { DevelopmentLegendMarketplaceEnvState, LegendMarketplaceEnv, ProdLegendMarketplaceEnvState, ProdParallelLegendMarketplaceEnvState, } from './LegendMarketplaceEnvState.js';
import { ProductCardState } from './lakehouse/dataProducts/ProductCardState.js';
import { convertEntitlementsDataProductDetailsToSearchResult, convertLegacyDataProductToSearchResult, convertTrendingEntryToSearchResult, } from '../utils/SearchUtils.js';
import { LakehouseDataProductService } from './lakehouse/LakehouseDataProductService.js';
export class LegendMarketplaceBaseStore {
applicationStore;
envState;
adjacentEnvState;
marketplaceServerClient;
depotServerClient;
lakehouseContractServerClient;
lakehousePlatformServerClient;
lakehouseIngestServerClient;
engineServerClient;
registryServerClient;
pluginManager;
remoteEngine;
userSearchService;
lakehouseWorkflowServerClient;
permitWorkflowServerClient;
lakehouseDataProductService;
cartStore;
terminalAccessServerClient;
pendingTasksCache;
initState = ActionState.create();
showDemoModal = false;
constructor(applicationStore) {
makeObservable(this, {
showDemoModal: observable,
setDemoModal: action,
initialize: flow,
});
this.applicationStore = applicationStore;
this.pluginManager = applicationStore.pluginManager;
// marketplace
this.envState =
applicationStore.config.dataProductEnv === LegendMarketplaceEnv.PRODUCTION
? new ProdLegendMarketplaceEnvState()
: applicationStore.config.dataProductEnv ===
LegendMarketplaceEnv.PRODUCTION_PARALLEL
? new ProdParallelLegendMarketplaceEnvState()
: new DevelopmentLegendMarketplaceEnvState();
this.adjacentEnvState = this.buildAdjacentEnvState();
this.marketplaceServerClient = new MarketplaceServerClient({
serverUrl: this.applicationStore.config.marketplaceServerUrl,
subscriptionUrl: this.applicationStore.config.marketplaceSubscriptionUrl,
});
this.marketplaceServerClient.setTracerService(this.applicationStore.tracerService);
// registry
if (this.applicationStore.config.registryUrl) {
this.registryServerClient = new RegistryServerClient({
baseUrl: this.applicationStore.config.registryUrl,
});
this.registryServerClient.setTracerService(this.applicationStore.tracerService);
}
// depot
this.depotServerClient = new DepotServerClient({
serverUrl: this.applicationStore.config.depotServerUrl,
});
this.depotServerClient.setTracerService(this.applicationStore.tracerService);
// lakehouse contract
this.lakehouseContractServerClient = new LakehouseContractServerClient({
baseUrl: this.applicationStore.config.lakehouseServerUrl,
});
this.lakehouseContractServerClient.setTracerService(this.applicationStore.tracerService);
// terminal
this.terminalAccessServerClient = new TerminalAccessServerClient({
baseUrl: this.applicationStore.config.terminalServerUrl,
});
this.terminalAccessServerClient.setTracerService(this.applicationStore.tracerService);
// lakehouse platform
this.lakehousePlatformServerClient = new LakehousePlatformServerClient(this.applicationStore.config.lakehousePlatformUrl);
this.lakehousePlatformServerClient.setTracerService(this.applicationStore.tracerService);
// lakehouse workflow
this.lakehouseWorkflowServerClient = new LakehouseWorkflowServerClient({
baseUrl: this.applicationStore.config.lakehouseWorkflowServerUrl,
});
this.lakehouseWorkflowServerClient.setTracerService(this.applicationStore.tracerService);
// permit + eTask workflow
if (this.applicationStore.config.lakehousePermitWorkflowServerUrl) {
this.permitWorkflowServerClient = new PermitWorkflowServerClient({
authBaseUrl: this.applicationStore.config.lakehouseServerUrl,
workflowBaseUrl: this.applicationStore.config.lakehousePermitWorkflowServerUrl,
});
this.permitWorkflowServerClient.setTracerService(this.applicationStore.tracerService);
}
else {
this.permitWorkflowServerClient = undefined;
}
// lakehouse ingest
this.lakehouseIngestServerClient = new LakehouseIngestServerClient(undefined);
this.lakehouseIngestServerClient.setTracerService(this.applicationStore.tracerService);
this.remoteEngine = new V1_RemoteEngine({
baseUrl: this.applicationStore.config.engineServerUrl,
}, applicationStore.logService);
this.engineServerClient = this.remoteEngine.getEngineServerClient();
this.engineServerClient.setTracerService(applicationStore.tracerService);
// User search
if (this.pluginManager.getUserPlugins().length > 0) {
this.pluginManager
.getUserPlugins()
.forEach((plugin) => plugin.setup(this.applicationStore.config.marketplaceUserSearchUrl));
this.userSearchService = new UserSearchService({
userProfileImageUrl: this.applicationStore.config.marketplaceUserProfileImageUrl,
applicationDirectoryUrl: this.applicationStore.config.lakehouseEntitlementsConfig
?.applicationDirectoryUrl,
});
this.userSearchService.registerPlugins(this.pluginManager.getUserPlugins());
}
// Data Product service
this.lakehouseDataProductService = new LakehouseDataProductService(this, this.lakehousePlatformServerClient, this.lakehouseContractServerClient);
// Initialize cart store
this.cartStore = new CartStore(this);
// Shared cache + in-flight dedupe for /datacontracts/tasks/pending
this.pendingTasksCache = new PendingTasksCache(this.lakehouseContractServerClient);
}
buildAdjacentEnvState() {
const adjacentEnv = this.envState.adjacentEnv;
if (adjacentEnv) {
return adjacentEnv === LegendMarketplaceEnv.PRODUCTION
? new ProdLegendMarketplaceEnvState()
: new ProdParallelLegendMarketplaceEnvState();
}
return undefined;
}
buildVendorImageMap() {
const vendorImageMap = new Map();
const assetsBaseUrl = this.applicationStore.config.assetsBaseUrl;
for (const [vendorName, filename] of Object.entries(this.applicationStore.config.assetsProductImageMap)) {
vendorImageMap.set(vendorName, `${assetsBaseUrl}/${filename}`);
}
return vendorImageMap;
}
async createInitializedGraphManager() {
const graphManager = new V1_PureGraphManager(this.applicationStore.pluginManager, this.applicationStore.logService, this.remoteEngine);
await graphManager.initialize({
env: this.applicationStore.config.env,
tabSize: DEFAULT_TAB_SIZE,
clientConfig: {
baseUrl: this.applicationStore.config.engineServerUrl,
},
}, { engine: this.remoteEngine });
return graphManager;
}
parseDataProductEntries(entriesString) {
return entriesString
.split(',')
.map((entry) => {
const vals = entry.split('/');
if (vals[0] === undefined || vals[1] === undefined) {
return undefined;
}
const id = vals[0];
const secondPart = vals[1];
if (Number.isInteger(Number(secondPart))) {
return {
dataProductId: id,
deploymentId: parseInt(secondPart),
};
}
else {
return { dataProductId: id, gav: secondPart };
}
})
.filter(isNonNullable);
}
async initHighlightedDataProducts(token) {
const highlightedConfig = this.applicationStore.config.options.highlightedDataProducts;
if (!highlightedConfig) {
return undefined;
}
const sectionEntries = Object.entries(highlightedConfig);
if (sectionEntries.length === 0) {
return undefined;
}
const vendorImageMap = this.buildVendorImageMap();
const getDataProductState = async (dataProductId, deploymentId, graphManager) => {
const rawResponse = await this.lakehouseContractServerClient.getDataProductByIdAndDID(dataProductId, deploymentId, token);
const dataProductDetail = V1_entitlementsDataProductDetailsResponseToDataProductDetails(rawResponse)[0];
if (dataProductDetail) {
const searchResult = convertEntitlementsDataProductDetailsToSearchResult(dataProductDetail);
return new ProductCardState(this, searchResult, graphManager, vendorImageMap);
}
else {
return undefined;
}
};
const getLegacyDataProductState = async (dataProductId, gav, graphManager) => {
const coordinates = parseGAVCoordinates(gav);
const storeProject = new StoreProjectData();
storeProject.groupId = coordinates.groupId;
storeProject.artifactId = coordinates.artifactId;
const legacyDataProuct = await this.depotServerClient.getEntity(storeProject, coordinates.versionId, dataProductId);
const dataSpace = V1_deserializeDataSpace(legacyDataProuct.content);
const searchResult = convertLegacyDataProductToSearchResult(dataSpace, coordinates.groupId, coordinates.artifactId, coordinates.versionId);
return new ProductCardState(this, searchResult, graphManager, vendorImageMap);
};
const graphManager = await this.createInitializedGraphManager();
const result = {};
await Promise.all(sectionEntries.map(async ([sectionName, entriesString]) => {
const entries = this.parseDataProductEntries(entriesString);
const states = (await Promise.all(entries.map(async (dataProduct) => dataProduct.deploymentId !== undefined
? getDataProductState(dataProduct.dataProductId, dataProduct.deploymentId, graphManager)
: getLegacyDataProductState(dataProduct.dataProductId, dataProduct.gav, graphManager)))).filter(isNonNullable);
states.forEach((state) => state.init(token));
result[sectionName] = states;
}));
return result;
}
async fetchTrendingDataProducts(token) {
const vendorImageMap = this.buildVendorImageMap();
const graphManager = await this.createInitializedGraphManager();
const trendingEntries = await this.marketplaceServerClient.getTrendingDataProducts(this.envState.lakehouseEnvironment);
const states = trendingEntries.slice(0, 4).map((entry) => {
const searchResult = convertTrendingEntryToSearchResult(entry);
return new ProductCardState(this, searchResult, graphManager, vendorImageMap);
});
states.forEach((state) => state.init(token));
return { Trending: states };
}
setDemoModal(val) {
this.showDemoModal = val;
}
*initialize() {
if (!this.initState.isInInitialState) {
this.applicationStore.notificationService.notifyIllegalState('Base store is re-initialized');
return;
}
this.initState.inProgress();
// retrieved the user identity is not already configured
if (this.applicationStore.identityService.isAnonymous) {
try {
this.applicationStore.identityService.setCurrentUser((yield getCurrentUserIDFromEngineServer(this.applicationStore.config.engineServerUrl)));
}
catch (error) {
assertErrorThrown(error);
this.applicationStore.logService.error(LogEvent.create(APPLICATION_EVENT.IDENTITY_AUTO_FETCH__FAILURE), error);
this.applicationStore.notificationService.notifyWarning(error.message);
}
}
// setup telemetry service
this.applicationStore.telemetryService.setup();
LegendApplicationTelemetryHelper.logEvent_ApplicationInitializationSucceeded(this.applicationStore.telemetryService, this.applicationStore);
LegendMarketplaceEventHelper.notify_ApplicationLoadSucceeded(this.applicationStore.eventService);
// Initialize cart store to load existing items
try {
yield* this.cartStore.initialize();
}
catch (error) {
assertErrorThrown(error);
this.applicationStore.logService.warn(LogEvent.create(APPLICATION_EVENT.IDENTITY_AUTO_FETCH__FAILURE), 'Failed to initialize cart store', error);
// Don't show notification as cart initialization failure shouldn't block app startup
}
this.initState.complete();
}
}
//# sourceMappingURL=LegendMarketplaceBaseStore.js.map