@finos/legend-application-studio 28.18.123 → 28.18.125
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/__lib__/LegendStudioNavigation.d.ts +7 -0
- package/lib/__lib__/LegendStudioNavigation.d.ts.map +1 -1
- package/lib/__lib__/LegendStudioNavigation.js +5 -0
- package/lib/__lib__/LegendStudioNavigation.js.map +1 -1
- package/lib/application/LegendIngestionConfiguration.d.ts +40 -0
- package/lib/application/LegendIngestionConfiguration.d.ts.map +1 -0
- package/lib/application/LegendIngestionConfiguration.js +57 -0
- package/lib/application/LegendIngestionConfiguration.js.map +1 -0
- package/lib/application/LegendStudioApplicationConfig.d.ts +2 -0
- package/lib/application/LegendStudioApplicationConfig.d.ts.map +1 -1
- package/lib/application/LegendStudioApplicationConfig.js +6 -0
- package/lib/application/LegendStudioApplicationConfig.js.map +1 -1
- package/lib/components/ElementIconUtils.d.ts.map +1 -1
- package/lib/components/ElementIconUtils.js +3 -1
- package/lib/components/ElementIconUtils.js.map +1 -1
- package/lib/components/LegendStudioWebApplication.d.ts.map +1 -1
- package/lib/components/LegendStudioWebApplication.js +16 -0
- package/lib/components/LegendStudioWebApplication.js.map +1 -1
- package/lib/components/editor/Editor.d.ts.map +1 -1
- package/lib/components/editor/Editor.js +3 -2
- package/lib/components/editor/Editor.js.map +1 -1
- package/lib/components/editor/editor-group/EditorGroup.d.ts.map +1 -1
- package/lib/components/editor/editor-group/EditorGroup.js +5 -0
- package/lib/components/editor/editor-group/EditorGroup.js.map +1 -1
- package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.d.ts +19 -0
- package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.d.ts.map +1 -0
- package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.js +71 -0
- package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.js.map +1 -0
- package/lib/components/lazy-text-editor/LazyTextEditor.js +1 -1
- package/lib/components/lazy-text-editor/LazyTextEditor.js.map +1 -1
- package/lib/index.css +1 -1
- package/lib/package.json +3 -1
- package/lib/stores/editor/EditorGraphState.d.ts.map +1 -1
- package/lib/stores/editor/EditorGraphState.js +4 -1
- package/lib/stores/editor/EditorGraphState.js.map +1 -1
- package/lib/stores/editor/EditorStore.d.ts +6 -2
- package/lib/stores/editor/EditorStore.d.ts.map +1 -1
- package/lib/stores/editor/EditorStore.js +21 -4
- package/lib/stores/editor/EditorStore.js.map +1 -1
- package/lib/stores/editor/EditorTabManagerState.d.ts +2 -1
- package/lib/stores/editor/EditorTabManagerState.d.ts.map +1 -1
- package/lib/stores/editor/EditorTabManagerState.js +6 -2
- package/lib/stores/editor/EditorTabManagerState.js.map +1 -1
- package/lib/stores/editor/GraphEditFormModeState.d.ts +2 -1
- package/lib/stores/editor/GraphEditFormModeState.d.ts.map +1 -1
- package/lib/stores/editor/GraphEditFormModeState.js +2 -2
- package/lib/stores/editor/GraphEditFormModeState.js.map +1 -1
- package/lib/stores/editor/GraphEditorMode.d.ts +2 -1
- package/lib/stores/editor/GraphEditorMode.d.ts.map +1 -1
- package/lib/stores/editor/GraphEditorMode.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/ElementEditorInitialConfiguration.d.ts +30 -0
- package/lib/stores/editor/editor-state/element-editor-state/ElementEditorInitialConfiguration.d.ts.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/ElementEditorInitialConfiguration.js +50 -0
- package/lib/stores/editor/editor-state/element-editor-state/ElementEditorInitialConfiguration.js.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/ElementEditorState.d.ts +2 -1
- package/lib/stores/editor/editor-state/element-editor-state/ElementEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/ElementEditorState.js +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/ElementEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.d.ts +37 -0
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.d.ts.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.js +107 -0
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.js.map +1 -0
- package/lib/stores/editor/utils/ModelClassifierUtils.d.ts +2 -1
- package/lib/stores/editor/utils/ModelClassifierUtils.d.ts.map +1 -1
- package/lib/stores/editor/utils/ModelClassifierUtils.js +1 -0
- package/lib/stores/editor/utils/ModelClassifierUtils.js.map +1 -1
- package/lib/stores/ingestion/IngestDeploymentServerClient.d.ts +29 -0
- package/lib/stores/ingestion/IngestDeploymentServerClient.d.ts.map +1 -0
- package/lib/stores/ingestion/IngestDeploymentServerClient.js +49 -0
- package/lib/stores/ingestion/IngestDeploymentServerClient.js.map +1 -0
- package/lib/stores/ingestion/IngestDiscoveryServerClient.d.ts +26 -0
- package/lib/stores/ingestion/IngestDiscoveryServerClient.d.ts.map +1 -0
- package/lib/stores/ingestion/IngestDiscoveryServerClient.js +35 -0
- package/lib/stores/ingestion/IngestDiscoveryServerClient.js.map +1 -0
- package/lib/stores/ingestion/IngestionDeploymentResponse.d.ts +30 -0
- package/lib/stores/ingestion/IngestionDeploymentResponse.d.ts.map +1 -0
- package/lib/stores/ingestion/IngestionDeploymentResponse.js +37 -0
- package/lib/stores/ingestion/IngestionDeploymentResponse.js.map +1 -0
- package/lib/stores/ingestion/IngestionManager.d.ts +35 -0
- package/lib/stores/ingestion/IngestionManager.d.ts.map +1 -0
- package/lib/stores/ingestion/IngestionManager.js +80 -0
- package/lib/stores/ingestion/IngestionManager.js.map +1 -0
- package/package.json +10 -8
- package/src/__lib__/LegendStudioNavigation.ts +14 -0
- package/src/application/LegendIngestionConfiguration.ts +94 -0
- package/src/application/LegendStudioApplicationConfig.ts +15 -0
- package/src/components/ElementIconUtils.tsx +3 -0
- package/src/components/LegendStudioWebApplication.tsx +29 -0
- package/src/components/editor/Editor.tsx +8 -3
- package/src/components/editor/editor-group/EditorGroup.tsx +4 -1
- package/src/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.tsx +156 -0
- package/src/components/lazy-text-editor/LazyTextEditor.tsx +1 -1
- package/src/stores/editor/EditorGraphState.ts +3 -0
- package/src/stores/editor/EditorStore.ts +39 -1
- package/src/stores/editor/EditorTabManagerState.ts +6 -0
- package/src/stores/editor/GraphEditFormModeState.ts +9 -2
- package/src/stores/editor/GraphEditorMode.ts +5 -1
- package/src/stores/editor/editor-state/element-editor-state/ElementEditorInitialConfiguration.ts +97 -0
- package/src/stores/editor/editor-state/element-editor-state/ElementEditorState.ts +6 -1
- package/src/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.ts +169 -0
- package/src/stores/editor/utils/ModelClassifierUtils.ts +1 -0
- package/src/stores/ingestion/IngestDeploymentServerClient.ts +83 -0
- package/src/stores/ingestion/IngestDiscoveryServerClient.ts +52 -0
- package/src/stores/ingestion/IngestionDeploymentResponse.ts +45 -0
- package/src/stores/ingestion/IngestionManager.ts +151 -0
- package/tsconfig.json +8 -0
package/src/stores/editor/editor-state/element-editor-state/ElementEditorInitialConfiguration.ts
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2020-present, Goldman Sachs
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
import {
|
18
|
+
SerializationFactory,
|
19
|
+
UnsupportedOperationError,
|
20
|
+
usingConstantValueSchema,
|
21
|
+
type PlainObject,
|
22
|
+
} from '@finos/legend-shared';
|
23
|
+
import { PACKAGEABLE_ELEMENT_TYPE } from '../../utils/ModelClassifierUtils.js';
|
24
|
+
import {
|
25
|
+
createModelSchema,
|
26
|
+
custom,
|
27
|
+
deserialize,
|
28
|
+
optional,
|
29
|
+
primitive,
|
30
|
+
serialize,
|
31
|
+
} from 'serializr';
|
32
|
+
|
33
|
+
export abstract class ElementEditorInitialConfiguration {
|
34
|
+
abstract type: PACKAGEABLE_ELEMENT_TYPE;
|
35
|
+
}
|
36
|
+
|
37
|
+
export class IngestElementEditorInitialConfiguration extends ElementEditorInitialConfiguration {
|
38
|
+
deployOnOpen?: boolean;
|
39
|
+
type = PACKAGEABLE_ELEMENT_TYPE.INGEST_DEFINITION;
|
40
|
+
|
41
|
+
static readonly serialization = new SerializationFactory(
|
42
|
+
createModelSchema(IngestElementEditorInitialConfiguration, {
|
43
|
+
_type: usingConstantValueSchema(
|
44
|
+
PACKAGEABLE_ELEMENT_TYPE.INGEST_DEFINITION,
|
45
|
+
),
|
46
|
+
deployOnOpen: optional(primitive()),
|
47
|
+
}),
|
48
|
+
);
|
49
|
+
}
|
50
|
+
|
51
|
+
const serializeElementEditorInitialConfiguration = (
|
52
|
+
protocol: ElementEditorInitialConfiguration,
|
53
|
+
): PlainObject<ElementEditorInitialConfiguration> => {
|
54
|
+
if (protocol instanceof IngestElementEditorInitialConfiguration) {
|
55
|
+
return serialize(
|
56
|
+
IngestElementEditorInitialConfiguration.serialization.schema,
|
57
|
+
protocol,
|
58
|
+
);
|
59
|
+
}
|
60
|
+
throw new UnsupportedOperationError(
|
61
|
+
`Can't serialize element config`,
|
62
|
+
protocol,
|
63
|
+
);
|
64
|
+
};
|
65
|
+
|
66
|
+
const deseralizeElementEditorInitialConfiguration = (
|
67
|
+
json: PlainObject<ElementEditorInitialConfiguration>,
|
68
|
+
): ElementEditorInitialConfiguration => {
|
69
|
+
switch (json._type) {
|
70
|
+
case PACKAGEABLE_ELEMENT_TYPE.INGEST_DEFINITION:
|
71
|
+
return deserialize(
|
72
|
+
IngestElementEditorInitialConfiguration.serialization.schema,
|
73
|
+
json,
|
74
|
+
);
|
75
|
+
default: {
|
76
|
+
throw new UnsupportedOperationError(
|
77
|
+
`Can't deserialize element config`,
|
78
|
+
json,
|
79
|
+
);
|
80
|
+
}
|
81
|
+
}
|
82
|
+
};
|
83
|
+
|
84
|
+
export class EditorInitialConfiguration {
|
85
|
+
elementEditorConfiguration?: ElementEditorInitialConfiguration;
|
86
|
+
|
87
|
+
static readonly serialization = new SerializationFactory(
|
88
|
+
createModelSchema(EditorInitialConfiguration, {
|
89
|
+
elementEditorConfiguration: optional(
|
90
|
+
custom(
|
91
|
+
serializeElementEditorInitialConfiguration,
|
92
|
+
deseralizeElementEditorInitialConfiguration,
|
93
|
+
),
|
94
|
+
),
|
95
|
+
}),
|
96
|
+
);
|
97
|
+
}
|
@@ -36,6 +36,7 @@ import {
|
|
36
36
|
import { DEFAULT_TAB_SIZE } from '@finos/legend-application';
|
37
37
|
import type { ElementFileGenerationState } from './ElementFileGenerationState.js';
|
38
38
|
import type { ElementXTSchemaGenerationState } from './ElementExternalFormatGenerationState.js';
|
39
|
+
import type { EditorInitialConfiguration } from './ElementEditorInitialConfiguration.js';
|
39
40
|
|
40
41
|
const generateMultiLineCommentForError = (
|
41
42
|
message: string,
|
@@ -104,7 +105,11 @@ export abstract class ElementEditorState extends EditorState {
|
|
104
105
|
textContent = '';
|
105
106
|
isReadOnly = false;
|
106
107
|
|
107
|
-
constructor(
|
108
|
+
constructor(
|
109
|
+
editorStore: EditorStore,
|
110
|
+
element: PackageableElement,
|
111
|
+
config?: EditorInitialConfiguration | undefined,
|
112
|
+
) {
|
108
113
|
super(editorStore);
|
109
114
|
|
110
115
|
makeObservable(this, {
|
package/src/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.ts
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2020-present, Goldman Sachs
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
import { IngestDefinition, type PackageableElement } from '@finos/legend-graph';
|
18
|
+
import { ElementEditorState } from '../ElementEditorState.js';
|
19
|
+
import type { EditorStore } from '../../../EditorStore.js';
|
20
|
+
import {
|
21
|
+
ActionState,
|
22
|
+
assertErrorThrown,
|
23
|
+
assertTrue,
|
24
|
+
guaranteeNonNullable,
|
25
|
+
guaranteeType,
|
26
|
+
type GeneratorFn,
|
27
|
+
} from '@finos/legend-shared';
|
28
|
+
import type { IngestionManager } from '../../../../ingestion/IngestionManager.js';
|
29
|
+
import { flow, flowResult, makeObservable, observable } from 'mobx';
|
30
|
+
import type { IngestDefinitionDeploymentResponse } from '../../../../ingestion/IngestionDeploymentResponse.js';
|
31
|
+
import {
|
32
|
+
EditorInitialConfiguration,
|
33
|
+
IngestElementEditorInitialConfiguration,
|
34
|
+
} from '../ElementEditorInitialConfiguration.js';
|
35
|
+
import type { AuthContextProps } from 'react-oidc-context';
|
36
|
+
import { EXTERNAL_APPLICATION_NAVIGATION__generateUrlWithEditorConfig } from '../../../../../__lib__/LegendStudioNavigation.js';
|
37
|
+
|
38
|
+
const createEditorInitialConfiguration = (): EditorInitialConfiguration => {
|
39
|
+
const config = new EditorInitialConfiguration();
|
40
|
+
const ingest = new IngestElementEditorInitialConfiguration();
|
41
|
+
ingest.deployOnOpen = true;
|
42
|
+
config.elementEditorConfiguration = ingest;
|
43
|
+
return config;
|
44
|
+
};
|
45
|
+
|
46
|
+
const editorInitialConfigToBase64 = (val: EditorInitialConfiguration): string =>
|
47
|
+
btoa(JSON.stringify(EditorInitialConfiguration.serialization.toJson(val)));
|
48
|
+
|
49
|
+
export const generateUrlToDeployOnOpen = (
|
50
|
+
val: IngestDefinitionEditorState,
|
51
|
+
): string => {
|
52
|
+
return val.editorStore.applicationStore.navigationService.navigator.generateAddress(
|
53
|
+
EXTERNAL_APPLICATION_NAVIGATION__generateUrlWithEditorConfig(
|
54
|
+
val.editorStore.editorMode.generateElementLink(val.ingest.path),
|
55
|
+
editorInitialConfigToBase64(createEditorInitialConfiguration()),
|
56
|
+
),
|
57
|
+
);
|
58
|
+
};
|
59
|
+
export class IngestDefinitionEditorState extends ElementEditorState {
|
60
|
+
deploymentState = ActionState.create();
|
61
|
+
deployOnOpen = false;
|
62
|
+
|
63
|
+
constructor(
|
64
|
+
editorStore: EditorStore,
|
65
|
+
element: PackageableElement,
|
66
|
+
config?: EditorInitialConfiguration,
|
67
|
+
) {
|
68
|
+
super(editorStore, element);
|
69
|
+
|
70
|
+
makeObservable(this, {
|
71
|
+
deploymentState: observable,
|
72
|
+
deployOnOpen: observable,
|
73
|
+
setDeployOnOpen: observable,
|
74
|
+
init_with_deploy: flow,
|
75
|
+
deploy: flow,
|
76
|
+
});
|
77
|
+
const elementConfig = config?.elementEditorConfiguration;
|
78
|
+
if (elementConfig instanceof IngestElementEditorInitialConfiguration) {
|
79
|
+
this.deployOnOpen = elementConfig.deployOnOpen ?? false;
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
get ingestionManager(): IngestionManager | undefined {
|
84
|
+
return this.editorStore.ingestionManager;
|
85
|
+
}
|
86
|
+
|
87
|
+
setDeployOnOpen(value: boolean): void {
|
88
|
+
this.deployOnOpen = value;
|
89
|
+
}
|
90
|
+
|
91
|
+
*init_with_deploy(auth: AuthContextProps): GeneratorFn<void> {
|
92
|
+
this.setDeployOnOpen(false);
|
93
|
+
if (!auth.isAuthenticated) {
|
94
|
+
auth
|
95
|
+
.signinRedirect({
|
96
|
+
state: generateUrlToDeployOnOpen(this),
|
97
|
+
})
|
98
|
+
.catch(this.editorStore.applicationStore.alertUnhandledError);
|
99
|
+
return;
|
100
|
+
}
|
101
|
+
const token = auth.user?.access_token;
|
102
|
+
yield flowResult(this.generateElementGrammar()).catch(
|
103
|
+
this.editorStore.applicationStore.alertUnhandledError,
|
104
|
+
);
|
105
|
+
flowResult(this.deploy(token)).catch(
|
106
|
+
this.editorStore.applicationStore.alertUnhandledError,
|
107
|
+
);
|
108
|
+
}
|
109
|
+
|
110
|
+
*deploy(token: string | undefined): GeneratorFn<void> {
|
111
|
+
try {
|
112
|
+
assertTrue(
|
113
|
+
this.validForDeployment,
|
114
|
+
'Ingest definition is not valid for deployment',
|
115
|
+
);
|
116
|
+
this.deploymentState.inProgress();
|
117
|
+
const response = (yield guaranteeNonNullable(
|
118
|
+
this.ingestionManager,
|
119
|
+
).deploy(
|
120
|
+
guaranteeNonNullable(this.textContent),
|
121
|
+
guaranteeNonNullable(this.ingest.appDirDeployment),
|
122
|
+
this.deploymentState,
|
123
|
+
token,
|
124
|
+
)) as unknown as IngestDefinitionDeploymentResponse;
|
125
|
+
this.editorStore.applicationStore.notificationService.notifySuccess(
|
126
|
+
`Ingest definition successfully deployed on ${response.ingestDefinitionUrn}`,
|
127
|
+
);
|
128
|
+
} catch (error) {
|
129
|
+
assertErrorThrown(error);
|
130
|
+
this.editorStore.applicationStore.notificationService.notifyError(
|
131
|
+
`Ingest definition failed to deploy: ${error.message}`,
|
132
|
+
);
|
133
|
+
} finally {
|
134
|
+
this.deploymentState.complete();
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
reprocess(
|
139
|
+
newElement: PackageableElement,
|
140
|
+
editorStore: EditorStore,
|
141
|
+
): ElementEditorState {
|
142
|
+
return new IngestDefinitionEditorState(editorStore, newElement);
|
143
|
+
}
|
144
|
+
|
145
|
+
get validForDeployment(): boolean {
|
146
|
+
return Boolean(
|
147
|
+
this.ingest.appDirDeployment && this.textContent && this.ingestionManager,
|
148
|
+
);
|
149
|
+
}
|
150
|
+
|
151
|
+
get validationMessage(): string {
|
152
|
+
if (!this.ingest.appDirDeployment) {
|
153
|
+
return 'No app dir deployment found';
|
154
|
+
} else if (!this.textContent) {
|
155
|
+
return 'No ingest definition found';
|
156
|
+
} else if (!this.ingestionManager) {
|
157
|
+
return 'No ingestion manager found';
|
158
|
+
}
|
159
|
+
return 'Deploy';
|
160
|
+
}
|
161
|
+
|
162
|
+
get ingest(): IngestDefinition {
|
163
|
+
return guaranteeType(
|
164
|
+
this.element,
|
165
|
+
IngestDefinition,
|
166
|
+
'Element inside ingest editor state must be a IngestDefinition',
|
167
|
+
);
|
168
|
+
}
|
169
|
+
}
|
@@ -0,0 +1,83 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2020-present, Goldman Sachs
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
import {
|
18
|
+
AbstractServerClient,
|
19
|
+
ContentType,
|
20
|
+
HttpHeader,
|
21
|
+
type PlainObject,
|
22
|
+
} from '@finos/legend-shared';
|
23
|
+
import { makeObservable, observable } from 'mobx';
|
24
|
+
import type {
|
25
|
+
IngestDefinitionDeploymentResponse,
|
26
|
+
IngestDefinitionValidationResponse,
|
27
|
+
} from './IngestionDeploymentResponse.js';
|
28
|
+
import type { IngestDeploymentServerConfig } from '../../application/LegendIngestionConfiguration.js';
|
29
|
+
|
30
|
+
export class IngestDeploymentServerClient extends AbstractServerClient {
|
31
|
+
environmentClassification: string;
|
32
|
+
constructor(config: IngestDeploymentServerConfig) {
|
33
|
+
super({
|
34
|
+
baseUrl: config.ingestServerUrl,
|
35
|
+
});
|
36
|
+
this.environmentClassification = config.environmentClassification;
|
37
|
+
makeObservable(this, {
|
38
|
+
environmentClassification: observable,
|
39
|
+
baseUrl: observable,
|
40
|
+
});
|
41
|
+
}
|
42
|
+
|
43
|
+
private _token = (token?: string) => ({
|
44
|
+
Authorization: `Bearer ${token}`,
|
45
|
+
});
|
46
|
+
|
47
|
+
private _tokenWithTextPlain = (token?: string) => ({
|
48
|
+
[HttpHeader.CONTENT_TYPE]: ContentType.TEXT_PLAIN,
|
49
|
+
Authorization: `Bearer ${token}`,
|
50
|
+
});
|
51
|
+
|
52
|
+
private _ingest = (): string =>
|
53
|
+
`${this.baseUrl}/ingest/sdlc/deploy/definitions`;
|
54
|
+
|
55
|
+
changeServer(serverConfig: IngestDeploymentServerConfig): void {
|
56
|
+
this.baseUrl = serverConfig.ingestServerUrl;
|
57
|
+
this.environmentClassification = serverConfig.environmentClassification;
|
58
|
+
}
|
59
|
+
|
60
|
+
validate(
|
61
|
+
validateGrammar: string,
|
62
|
+
token: string | undefined,
|
63
|
+
): Promise<PlainObject<IngestDefinitionValidationResponse>> {
|
64
|
+
return this.post(
|
65
|
+
`${this._ingest()}/validate`,
|
66
|
+
validateGrammar,
|
67
|
+
undefined,
|
68
|
+
this._tokenWithTextPlain(token),
|
69
|
+
);
|
70
|
+
}
|
71
|
+
|
72
|
+
deploy(
|
73
|
+
deployGrammar: string,
|
74
|
+
token: string | undefined,
|
75
|
+
): Promise<IngestDefinitionDeploymentResponse> {
|
76
|
+
return this.post(
|
77
|
+
`${this._ingest()}`,
|
78
|
+
deployGrammar,
|
79
|
+
undefined,
|
80
|
+
this._tokenWithTextPlain(token),
|
81
|
+
);
|
82
|
+
}
|
83
|
+
}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2020-present, Goldman Sachs
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
import { AbstractServerClient, type PlainObject } from '@finos/legend-shared';
|
18
|
+
import type { IngestDeploymentServerConfig } from '../../application/LegendIngestionConfiguration.js';
|
19
|
+
|
20
|
+
export class IngestDiscoveryServerClient extends AbstractServerClient {
|
21
|
+
constructor(url: string) {
|
22
|
+
super({
|
23
|
+
baseUrl: url,
|
24
|
+
});
|
25
|
+
}
|
26
|
+
private _ingest = (): string =>
|
27
|
+
`${this.baseUrl}/ingest/discovery/environments/producers`;
|
28
|
+
|
29
|
+
private _env = (): string => `${this.baseUrl}/ingest/discovery/environments`;
|
30
|
+
|
31
|
+
private _token = (token?: string) => ({
|
32
|
+
Authorization: `Bearer ${token}`,
|
33
|
+
});
|
34
|
+
|
35
|
+
discover(
|
36
|
+
token?: string | undefined,
|
37
|
+
): Promise<PlainObject<IngestDeploymentServerConfig[]>> {
|
38
|
+
return this.get(`${this._env()}`, {}, this._token(token));
|
39
|
+
}
|
40
|
+
|
41
|
+
findProducerServer(
|
42
|
+
id: number,
|
43
|
+
level: string,
|
44
|
+
token?: string | undefined,
|
45
|
+
): Promise<PlainObject<IngestDeploymentServerConfig>> {
|
46
|
+
return this.get(
|
47
|
+
`${this._ingest()}/${id}/${level}/search`,
|
48
|
+
{},
|
49
|
+
this._token(token),
|
50
|
+
);
|
51
|
+
}
|
52
|
+
}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2020-present, Goldman Sachs
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
import { SerializationFactory } from '@finos/legend-shared';
|
18
|
+
import { createModelSchema, primitive } from 'serializr';
|
19
|
+
|
20
|
+
export enum IngestDefinitionValidationResponseStatus {
|
21
|
+
NOT_CHECKED = 'NOT_CHECKED',
|
22
|
+
SUCCESS = 'SUCCESS',
|
23
|
+
FAILURE = 'FAILURE',
|
24
|
+
}
|
25
|
+
|
26
|
+
// TODO: include full response for user
|
27
|
+
export class IngestDefinitionValidationResponse {
|
28
|
+
status!: IngestDefinitionValidationResponseStatus;
|
29
|
+
|
30
|
+
static readonly serialization = new SerializationFactory(
|
31
|
+
createModelSchema(IngestDefinitionValidationResponse, {
|
32
|
+
status: primitive(),
|
33
|
+
}),
|
34
|
+
);
|
35
|
+
}
|
36
|
+
|
37
|
+
export class IngestDefinitionDeploymentResponse {
|
38
|
+
ingestDefinitionUrn!: string;
|
39
|
+
|
40
|
+
static readonly serialization = new SerializationFactory(
|
41
|
+
createModelSchema(IngestDefinitionDeploymentResponse, {
|
42
|
+
ingestDefinitionUrn: primitive(),
|
43
|
+
}),
|
44
|
+
);
|
45
|
+
}
|
@@ -0,0 +1,151 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2020-present, Goldman Sachs
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
import type { AppDirNode } from '@finos/legend-graph';
|
18
|
+
import { IngestDeploymentServerClient } from './IngestDeploymentServerClient.js';
|
19
|
+
import { IngestDiscoveryServerClient } from './IngestDiscoveryServerClient.js';
|
20
|
+
import type { GenericLegendApplicationStore } from '@finos/legend-application';
|
21
|
+
import { type ActionState, type PlainObject } from '@finos/legend-shared';
|
22
|
+
import {
|
23
|
+
IngestDefinitionValidationResponse,
|
24
|
+
IngestDefinitionDeploymentResponse,
|
25
|
+
IngestDefinitionValidationResponseStatus,
|
26
|
+
} from './IngestionDeploymentResponse.js';
|
27
|
+
import {
|
28
|
+
IngestDeploymentServerConfig,
|
29
|
+
type LegendIngestionConfiguration,
|
30
|
+
} from '../../application/LegendIngestionConfiguration.js';
|
31
|
+
|
32
|
+
export class IngestionManager {
|
33
|
+
private ingestDiscoveryServerClient: IngestDiscoveryServerClient;
|
34
|
+
private ingestDeploymentServerClient: IngestDeploymentServerClient;
|
35
|
+
private _currentAppID: number | undefined;
|
36
|
+
private _currentLevel: string | undefined;
|
37
|
+
private readonly applicationStore: GenericLegendApplicationStore;
|
38
|
+
|
39
|
+
constructor(
|
40
|
+
config: LegendIngestionConfiguration,
|
41
|
+
applicationStore: GenericLegendApplicationStore,
|
42
|
+
) {
|
43
|
+
this.ingestDiscoveryServerClient = new IngestDiscoveryServerClient(
|
44
|
+
config.discoveryUrl,
|
45
|
+
);
|
46
|
+
this.ingestDiscoveryServerClient.setTracerService(
|
47
|
+
applicationStore.tracerService,
|
48
|
+
);
|
49
|
+
this.ingestDeploymentServerClient = new IngestDeploymentServerClient(
|
50
|
+
config.deployment.defaultServer,
|
51
|
+
);
|
52
|
+
this.ingestDeploymentServerClient.setTracerService(
|
53
|
+
applicationStore.tracerService,
|
54
|
+
);
|
55
|
+
this.applicationStore = applicationStore;
|
56
|
+
}
|
57
|
+
|
58
|
+
isCurrentAppDirNode(appDirNode: AppDirNode): boolean {
|
59
|
+
return (
|
60
|
+
this._currentAppID === appDirNode.appDirId &&
|
61
|
+
this._currentLevel === appDirNode.level
|
62
|
+
);
|
63
|
+
}
|
64
|
+
|
65
|
+
setCurrentAppDirNode(appDirNode: AppDirNode): void {
|
66
|
+
this._currentAppID = appDirNode.appDirId;
|
67
|
+
this._currentLevel = appDirNode.level;
|
68
|
+
}
|
69
|
+
|
70
|
+
async deploy(
|
71
|
+
ingestDefinition: string,
|
72
|
+
appDirNode: AppDirNode,
|
73
|
+
actionState: ActionState | undefined,
|
74
|
+
token: string | undefined,
|
75
|
+
): Promise<IngestDefinitionDeploymentResponse> {
|
76
|
+
actionState?.setMessage(
|
77
|
+
`Discovering associated ingest environment for DID ${appDirNode.appDirId}...`,
|
78
|
+
);
|
79
|
+
await this.identifyIngestDeploymentServer(appDirNode, token);
|
80
|
+
actionState?.setMessage(
|
81
|
+
`Validating ingest with server ${this.ingestDeploymentServerClient.baseUrl ?? ''} for realm ${this.ingestDeploymentServerClient.environmentClassification}...`,
|
82
|
+
);
|
83
|
+
const validateResonse = await this._validate(
|
84
|
+
ingestDefinition,
|
85
|
+
undefined,
|
86
|
+
token,
|
87
|
+
);
|
88
|
+
if (
|
89
|
+
validateResonse.status !==
|
90
|
+
IngestDefinitionValidationResponseStatus.SUCCESS
|
91
|
+
) {
|
92
|
+
throw new Error('Failed to validate Ingest Definition');
|
93
|
+
}
|
94
|
+
actionState?.setMessage(
|
95
|
+
`Validation Success. Deploying ingest with server ${this.ingestDeploymentServerClient.baseUrl ?? ''} for realm ${this.ingestDeploymentServerClient.environmentClassification}...`,
|
96
|
+
);
|
97
|
+
return this._deploy(ingestDefinition, undefined, token);
|
98
|
+
}
|
99
|
+
|
100
|
+
private async _validate(
|
101
|
+
ingestDefinition: string,
|
102
|
+
appDirNode: AppDirNode | undefined,
|
103
|
+
token: string | undefined,
|
104
|
+
): Promise<IngestDefinitionValidationResponse> {
|
105
|
+
if (appDirNode) {
|
106
|
+
await this.identifyIngestDeploymentServer(appDirNode, token);
|
107
|
+
}
|
108
|
+
// validate
|
109
|
+
const response = await this.ingestDeploymentServerClient.validate(
|
110
|
+
ingestDefinition,
|
111
|
+
token,
|
112
|
+
);
|
113
|
+
return IngestDefinitionValidationResponse.serialization.fromJson(response);
|
114
|
+
}
|
115
|
+
|
116
|
+
private async _deploy(
|
117
|
+
ingestDefinition: string,
|
118
|
+
appDirNode: AppDirNode | undefined,
|
119
|
+
token: string | undefined,
|
120
|
+
): Promise<IngestDefinitionDeploymentResponse> {
|
121
|
+
if (appDirNode) {
|
122
|
+
await this.identifyIngestDeploymentServer(appDirNode, token);
|
123
|
+
}
|
124
|
+
// validate
|
125
|
+
const response = (await this.ingestDeploymentServerClient.deploy(
|
126
|
+
ingestDefinition,
|
127
|
+
token,
|
128
|
+
)) as unknown as PlainObject<IngestDefinitionDeploymentResponse>;
|
129
|
+
return IngestDefinitionDeploymentResponse.serialization.fromJson(response);
|
130
|
+
}
|
131
|
+
|
132
|
+
private async identifyIngestDeploymentServer(
|
133
|
+
appDirNode: AppDirNode,
|
134
|
+
token: string | undefined,
|
135
|
+
): Promise<void> {
|
136
|
+
// we do not change if current appDirNode is the same as the one we are trying to set
|
137
|
+
if (this.isCurrentAppDirNode(appDirNode)) {
|
138
|
+
return;
|
139
|
+
}
|
140
|
+
const serverConfig = IngestDeploymentServerConfig.serialization.fromJson(
|
141
|
+
await this.ingestDiscoveryServerClient.findProducerServer(
|
142
|
+
appDirNode.appDirId,
|
143
|
+
appDirNode.level,
|
144
|
+
token,
|
145
|
+
),
|
146
|
+
);
|
147
|
+
|
148
|
+
this.ingestDeploymentServerClient.changeServer(serverConfig);
|
149
|
+
this.setCurrentAppDirNode(appDirNode);
|
150
|
+
}
|
151
|
+
}
|
package/tsconfig.json
CHANGED
@@ -67,6 +67,7 @@
|
|
67
67
|
"./src/__lib__/LegendStudioTesting.ts",
|
68
68
|
"./src/__lib__/LegendStudioUserDataHelper.ts",
|
69
69
|
"./src/__lib__/STO_Relational_LegendStudioCommand.ts",
|
70
|
+
"./src/application/LegendIngestionConfiguration.ts",
|
70
71
|
"./src/application/LegendStudioApplicationConfig.ts",
|
71
72
|
"./src/application/LegendStudioPluginManager.ts",
|
72
73
|
"./src/components/__test-utils__/EmbeddedQueryBuilderTestUtils.ts",
|
@@ -108,6 +109,7 @@
|
|
108
109
|
"./src/stores/editor/editor-state/diff-viewer-state/ProjectConfigurationDiffEditorState.ts",
|
109
110
|
"./src/stores/editor/editor-state/element-editor-state/ClassEditorState.ts",
|
110
111
|
"./src/stores/editor/editor-state/element-editor-state/ClassState.ts",
|
112
|
+
"./src/stores/editor/editor-state/element-editor-state/ElementEditorInitialConfiguration.ts",
|
111
113
|
"./src/stores/editor/editor-state/element-editor-state/ElementEditorState.ts",
|
112
114
|
"./src/stores/editor/editor-state/element-editor-state/ElementExternalFormatGenerationState.ts",
|
113
115
|
"./src/stores/editor/editor-state/element-editor-state/ElementFileGenerationState.ts",
|
@@ -134,6 +136,7 @@
|
|
134
136
|
"./src/stores/editor/editor-state/element-editor-state/function-activator/PostDeploymentActionEditorState.ts",
|
135
137
|
"./src/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.ts",
|
136
138
|
"./src/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.ts",
|
139
|
+
"./src/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.ts",
|
137
140
|
"./src/stores/editor/editor-state/element-editor-state/mapping/FlatDataInstanceSetImplementationState.ts",
|
138
141
|
"./src/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.ts",
|
139
142
|
"./src/stores/editor/editor-state/element-editor-state/mapping/MappingElementDecorator.ts",
|
@@ -202,6 +205,10 @@
|
|
202
205
|
"./src/stores/graph-modifier/STO_FlatData_GraphModifierHelper.ts",
|
203
206
|
"./src/stores/graph-modifier/STO_Relational_GraphModifierHelper.ts",
|
204
207
|
"./src/stores/graph-modifier/Testable_GraphModifierHelper.ts",
|
208
|
+
"./src/stores/ingestion/IngestDeploymentServerClient.ts",
|
209
|
+
"./src/stores/ingestion/IngestDiscoveryServerClient.ts",
|
210
|
+
"./src/stores/ingestion/IngestionDeploymentResponse.ts",
|
211
|
+
"./src/stores/ingestion/IngestionManager.ts",
|
205
212
|
"./src/stores/lazy-text-editor/LazyTextEditorStore.ts",
|
206
213
|
"./src/stores/project-reviewer/ProjectReviewerStore.ts",
|
207
214
|
"./src/stores/project-view/ProjectViewerEditorMode.ts",
|
@@ -267,6 +274,7 @@
|
|
267
274
|
"./src/components/editor/editor-group/function-activator/INTERNAL__UnknownFunctionActivatorEdtior.tsx",
|
268
275
|
"./src/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.tsx",
|
269
276
|
"./src/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.tsx",
|
277
|
+
"./src/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.tsx",
|
270
278
|
"./src/components/editor/editor-group/mapping-editor/ClassMappingEditor.tsx",
|
271
279
|
"./src/components/editor/editor-group/mapping-editor/EnumerationMappingEditor.tsx",
|
272
280
|
"./src/components/editor/editor-group/mapping-editor/FlatDataPropertyMappingEditor.tsx",
|