UNPKG

@finos/legend-studio

Version:
207 lines 10.3 kB
/** * 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 { action, computed, makeAutoObservable } from 'mobx'; import { MINIMUM_SERVICE_OWNERS, } from '../../../editor-state/element-editor-state/service/ServiceEditorState.js'; import { assertErrorThrown, LogEvent, ActionState, prettyCONSTName, assertNonEmptyString, guaranteeNonNullable, UnsupportedOperationError, getNullableFirstElement, assertTrue, } from '@finos/legend-shared'; import { LEGEND_STUDIO_APP_EVENT } from '../../../LegendStudioAppEvent.js'; import { Version } from '@finos/legend-server-sdlc'; import { ServiceExecutionMode, } from '@finos/legend-graph'; import { ServiceRegistrationEnvInfo } from '../../../../application/LegendStudioApplicationConfig.js'; import { ActionAlertActionType, ActionAlertType, } from '@finos/legend-application'; export const LATEST_PROJECT_REVISION = 'Latest Project Revision'; const getServiceExecutionMode = (mode) => { switch (mode) { case ServiceExecutionMode.FULL_INTERACTIVE: return ServiceExecutionMode.FULL_INTERACTIVE; case ServiceExecutionMode.SEMI_INTERACTIVE: return ServiceExecutionMode.SEMI_INTERACTIVE; case ServiceExecutionMode.PROD: return ServiceExecutionMode.PROD; default: throw new UnsupportedOperationError(`Encountered unsupported service execution mode '${mode}'`); } }; const URL_SEPARATOR = '/'; export var SERVICE_REGISTRATION_PHASE; (function (SERVICE_REGISTRATION_PHASE) { SERVICE_REGISTRATION_PHASE["REGISTERING_SERVICE"] = "REGISTERING_SERVICE"; SERVICE_REGISTRATION_PHASE["ACTIVATING_SERVICE"] = "ACTIVATING_SERVICE"; })(SERVICE_REGISTRATION_PHASE = SERVICE_REGISTRATION_PHASE || (SERVICE_REGISTRATION_PHASE = {})); export class ServiceRegistrationState { editorStore; serviceEditorState; registrationState = ActionState.create(); serviceEnv; serviceExecutionMode; projectVersion; activatePostRegistration = true; constructor(editorStore, serviceEditorState) { makeAutoObservable(this, { editorStore: false, executionModes: computed, updateVersion: action, setProjectVersion: action, initialize: action, updateType: action, updateEnv: action, setActivatePostRegistration: action, }); this.editorStore = editorStore; this.serviceEditorState = serviceEditorState; this.initialize(); this.registrationState.setMessageFormatter(prettyCONSTName); } setServiceEnv(val) { this.serviceEnv = val; } setServiceExecutionMode(val) { this.serviceExecutionMode = val; } setProjectVersion(val) { this.projectVersion = val; } setActivatePostRegistration(val) { this.activatePostRegistration = val; } initialize() { this.serviceEnv = getNullableFirstElement(this.editorStore.applicationStore.config.options .TEMPORARY__serviceRegistrationConfig)?.env; this.serviceExecutionMode = this.executionModes[0]; this.updateVersion(); } updateVersion() { if (this.serviceExecutionMode === ServiceExecutionMode.SEMI_INTERACTIVE) { this.projectVersion = LATEST_PROJECT_REVISION; } else if (this.serviceExecutionMode === ServiceExecutionMode.PROD) { this.projectVersion = this.editorStore.sdlcState.projectVersions[0]; } else { this.projectVersion = undefined; } } updateType(val) { this.setServiceExecutionMode(val); this.updateVersion(); } updateEnv(val) { this.setServiceEnv(val); this.setServiceExecutionMode(this.executionModes[0]); } get options() { if (this.editorStore.sdlcServerClient.features.canCreateVersion) { return this.editorStore.applicationStore.config.options .TEMPORARY__serviceRegistrationConfig; } return this.editorStore.applicationStore.config.options.TEMPORARY__serviceRegistrationConfig.map((_envConfig) => { const envConfig = new ServiceRegistrationEnvInfo(); envConfig.env = _envConfig.env; envConfig.executionUrl = _envConfig.executionUrl; envConfig.managementUrl = _envConfig.managementUrl; // NOTE: For projects that we cannot create a version for, only fully-interactive mode is supported envConfig.modes = _envConfig.modes.filter((mode) => mode === ServiceExecutionMode.FULL_INTERACTIVE); return envConfig; }).filter((envConfig) => envConfig.modes.length); } get executionModes() { return (this.options.find((e) => e.env === this.serviceEnv)?.modes ?? []).map(getServiceExecutionMode); } get versionOptions() { if (this.editorStore.sdlcServerClient.features.canCreateVersion && this.serviceExecutionMode !== ServiceExecutionMode.FULL_INTERACTIVE) { const options = this.editorStore.sdlcState.projectVersions.map((version) => ({ label: version.id.id, value: version, })); if (this.serviceExecutionMode !== ServiceExecutionMode.PROD) { return [ { label: prettyCONSTName(LATEST_PROJECT_REVISION), value: LATEST_PROJECT_REVISION, }, ...options, ]; } return options; } return undefined; } *registerService() { try { this.registrationState.inProgress(); this.validateServiceForRegistration(); const config = guaranteeNonNullable(this.options.find((info) => info.env === this.serviceEnv)); const serverUrl = config.executionUrl; const versionInput = this.projectVersion instanceof Version ? this.projectVersion.id.id : undefined; const projectConfig = guaranteeNonNullable(this.editorStore.projectConfigurationEditorState.projectConfiguration); this.registrationState.setMessage(SERVICE_REGISTRATION_PHASE.REGISTERING_SERVICE); const serviceRegistrationResult = (yield this.editorStore.graphManagerState.graphManager.registerService(this.serviceEditorState.service, this.editorStore.graphManagerState.graph, projectConfig.groupId, projectConfig.artifactId, versionInput, serverUrl, guaranteeNonNullable(this.serviceExecutionMode))); if (this.activatePostRegistration) { this.registrationState.setMessage(SERVICE_REGISTRATION_PHASE.ACTIVATING_SERVICE); yield this.editorStore.graphManagerState.graphManager.activateService(serverUrl, serviceRegistrationResult.serviceInstanceId); } assertNonEmptyString(serviceRegistrationResult.pattern, 'Service registration pattern is missing'); const message = `Service with patten ${serviceRegistrationResult.pattern} registered ${this.activatePostRegistration ? 'and activated ' : ''}`; const encodedServicePattern = URL_SEPARATOR + encodeURIComponent(serviceRegistrationResult.pattern[0] === URL_SEPARATOR ? serviceRegistrationResult.pattern.substring(1) : serviceRegistrationResult.pattern); this.editorStore.setActionAlertInfo({ message, prompt: 'You can now launch and monitor the operation of your service', type: ActionAlertType.STANDARD, onEnter: () => this.editorStore.setBlockGlobalHotkeys(true), onClose: () => this.editorStore.setBlockGlobalHotkeys(false), actions: [ { label: 'Launch Service', type: ActionAlertActionType.PROCEED, handler: () => { this.editorStore.applicationStore.navigator.openNewWindow(`${config.managementUrl}${encodedServicePattern}`); }, default: true, }, { label: 'Close', type: ActionAlertActionType.PROCEED_WITH_CAUTION, }, ], }); } catch (error) { assertErrorThrown(error); this.editorStore.applicationStore.log.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.SERVICE_REGISTRATION_FAILURE), error); this.editorStore.applicationStore.notifyError(error); } finally { this.registrationState.reset(); this.registrationState.setMessage(undefined); } } validateServiceForRegistration() { this.serviceEditorState.service.owners.forEach((owner) => assertNonEmptyString(owner, `Service can't have an empty owner name`)); assertTrue(this.serviceEditorState.service.owners.length >= MINIMUM_SERVICE_OWNERS, `Service needs to have at least 2 owners in order to be registered`); guaranteeNonNullable(this.serviceEnv, 'Service registration environment can not be empty'); guaranteeNonNullable(this.serviceExecutionMode, 'Service type can not be empty'); if (this.serviceExecutionMode === ServiceExecutionMode.PROD || this.serviceExecutionMode === ServiceExecutionMode.SEMI_INTERACTIVE) { guaranteeNonNullable(this.projectVersion, 'Service version can not be empty in Semi-interactive and Prod service type'); } } } //# sourceMappingURL=ServiceRegistrationState.js.map