@finos/legend-studio
Version:
207 lines • 10.3 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 { 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