Skip to content

Commit 97a4442

Browse files
authored
Add option to discover remote domain without creating archive (#141)
* Add remote discovery switch to online dialog, disable domain home on change * Use view helper to open discover dialog * Require remote domain home for remote discovery * Remove read-only label update from domain home field * Display discover results dialog when -remote is used * Use tables to show archive entry files and paths
1 parent 7342992 commit 97a4442

File tree

8 files changed

+270
-51
lines changed

8 files changed

+270
-51
lines changed

electron/app/js/wdtDiscovery.js

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @license
3-
* Copyright (c) 2021, Oracle and/or its affiliates.
3+
* Copyright (c) 2021, 2022, Oracle and/or its affiliates.
44
* Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
55
*/
66
const path = require('path');
@@ -13,6 +13,8 @@ const { getAbsolutePath, makeDirectoryIfNotExists } = require('./fsUtils');
1313
const { getDiscoverDomainShellScript } = require('./wktTools');
1414
const { getLogger } = require('./wktLogging');
1515
const { sendToWindow } = require('./windowUtils');
16+
const { readFile } = require('fs/promises');
17+
const fsUtils = require('./fsUtils');
1618

1719
/* global process */
1820

@@ -77,16 +79,31 @@ async function _runDiscover(targetWindow, discoverConfig, online) {
7779
argList.push(discoverConfig['adminPass']);
7880
}
7981

80-
argList.push('-archive_file');
81-
argList.push(archiveFile);
82+
const isRemote = discoverConfig['isRemote'];
83+
if (!isRemote) {
84+
argList.push('-archive_file');
85+
argList.push(archiveFile);
86+
}
87+
8288
argList.push('-model_file');
8389
argList.push(modelFile);
8490
argList.push('-variable_file');
8591
argList.push(propertiesFile);
8692

87-
const env = {};
88-
if (!process.env.JAVA_HOME) {
89-
env['JAVA_HOME'] = discoverConfig['javaHome'];
93+
if (isRemote) {
94+
argList.push('-remote');
95+
}
96+
97+
const env = {
98+
JAVA_HOME: process.env.JAVA_HOME || discoverConfig['javaHome']
99+
};
100+
101+
let resultsDirectory = null;
102+
let resultsFile = null;
103+
if (isRemote) {
104+
resultsDirectory = await fsUtils.createTemporaryDirectory(projectDir, 'discoverModel');
105+
resultsFile = path.join(resultsDirectory, 'result.json');
106+
env['__WLSDEPLOY_STORE_RESULT__'] = resultsFile;
90107
}
91108

92109
let stdoutEventName = 'show-console-out-line';
@@ -114,6 +131,12 @@ async function _runDiscover(targetWindow, discoverConfig, online) {
114131

115132
results.modelFileContent = await project.getModelFileContent(targetWindow, [relativeModelFile], [relativePropertiesFile],
116133
[relativeArchiveFile]);
134+
135+
if(isRemote) {
136+
const resultsText = await readFile(resultsFile, {encoding: 'utf8'});
137+
results.resultData = JSON.parse(resultsText);
138+
await fsUtils.removeDirectoryRecursively(resultsDirectory);
139+
}
117140
} catch (err) {
118141
results.isSuccess = false;
119142
results.reason = i18n.t('wdt-discovery-failed-error-message', { script: getDiscoverDomainShellScript(), error: errorUtils.getErrorMessage(err)});

electron/app/locales/en/webui.json

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,16 @@
859859
"discover-dialog-admin-user-help": "The login user name for the Administration Server.",
860860
"discover-dialog-admin-password-label": "Administration Server Password",
861861
"discover-dialog-admin-password-help": "The login password for the Administration Server.",
862+
"discover-dialog-remote-discovery-label": "Remote Discovery",
863+
"discover-dialog-remote-discovery-help": "Discover without collecting archive artifacts",
864+
"discover-dialog-domain-home-remote-help": "The directory of the domain to be discovered on the remote system",
865+
"discover-dialog-domain-home-remote-label": "Remote Domain Home",
866+
867+
"discover-result-dialog-title": "Discover Domain Result",
868+
"discover-result-dialog-archive-message": "The following files need to be collected from the remote system and placed in the archive file at the specified paths",
869+
"discover-result-dialog-file-location-header": "File Location",
870+
"discover-result-dialog-archive-path-header": "Archive Path",
871+
"discover-result-dialog-archive-table-aria-label": "Archive Entries Table",
862872

863873
"wdt-discoverer-replace-title": "Replace Existing Model Content",
864874
"wdt-discoverer-replace-message": "This will replace the project's existing model content, continue?",
@@ -1448,5 +1458,22 @@
14481458
"quickstart-page9-list4-item-2": "Code view provides a shell script that shows how you can automate the installation as well as the YAML resource definitions.",
14491459
"quickstart-page9-list4-item-3": "The Install Ingress Controller and Update Ingress Routing buttons (and Go menu items) perform the necessary actions to install the ingress controller and update routes on an existing ingress controller.",
14501460

1451-
"quickstart-page10-title": "Verrazzano-Specific Sections"
1461+
"quickstart-page10-title": "Verrazzano-Specific Sections",
1462+
1463+
"archive-type-APPLICATION_PLAN": "Application Plans",
1464+
"archive-type-APPLICATIONS": "Applications",
1465+
"archive-type-CLASSPATH_LIB": "Classpath Libraries",
1466+
"archive-type-COHERENCE": "Coherence Files",
1467+
"archive-type-COHERENCE_CONFIG": "Coherence Configurations",
1468+
"archive-type-COHERENCE_PERSISTENCE_DIR": "Coherence Persistence Directories",
1469+
"archive-type-DOMAIN_BIN": "Domain Binaries",
1470+
"archive-type-DOMAIN_LIB": "Domain Libraries",
1471+
"archive-type-FILE_STORE": "File Stores",
1472+
"archive-type-JMS_FOREIGN_SERVER": "JMS Foreign Servers",
1473+
"archive-type-MIME_MAPPING": "MIME Mappings",
1474+
"archive-type-NODE_MANAGER_KEY_STORE": "Node Manager Key Stores",
1475+
"archive-type-SCRIPTS": "Scripts",
1476+
"archive-type-SERVER_KEYSTORE": "Server Key Stores",
1477+
"archive-type-SHARED_LIBRARIES": "Shared Libraries",
1478+
"archive-type-SHLIB_PLAN": "Shared Library Plans"
14521479
}

webui/src/css/app.css

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,12 @@ h6:first-child {
371371
height: auto;
372372
}
373373

374+
.wkt-discover-result-dialog {
375+
max-width: 1000px;
376+
height: 85vh;
377+
width: 85%;
378+
}
379+
374380
.wkt-add-to-archive-dialog {
375381
width: 600px;
376382
height: auto;
@@ -506,6 +512,11 @@ h6:first-child {
506512
height: 100%;
507513
}
508514

515+
.wkt-stacked-dialog-body {
516+
display: flex;
517+
flex-direction: column;
518+
}
519+
509520
/* the oj-switcher in the code view should use the remaining height */
510521
.wkt-code-view-switcher {
511522
min-height: 1px;

webui/src/js/utils/wdt-discoverer.js

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @license
3-
* Copyright (c) 2021, Oracle and/or its affiliates.
3+
* Copyright (c) 2021, 2022, Oracle and/or its affiliates.
44
* Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
55
*/
66
'use strict';
@@ -65,16 +65,21 @@ function (WdtActionsBase, ko, project, wktConsole, dialogHelper, projectIO, i18n
6565
return Promise.resolve(false);
6666
}
6767

68-
busyDialogMessage = i18n.t('flow-validate-domain-home-in-progress');
69-
dialogHelper.updateBusyDialog(busyDialogMessage, 2/totalSteps);
70-
const errContext = i18n.t('wdt-discoverer-invalid-domain-home-error-prefix');
71-
const domainHomeValidationResult =
72-
await window.api.ipc.invoke('validate-domain-home', domainHomeDirectory, errContext);
73-
if (!domainHomeValidationResult.isValid) {
74-
const errMessage = domainHomeValidationResult.reason;
75-
dialogHelper.closeBusyDialog();
76-
await window.api.ipc.invoke('show-error-message', errTitle, errMessage);
77-
return Promise.resolve(false);
68+
// for remote discovery, domain home is on the remote machine,
69+
// so don't validate the directory
70+
const isRemote = discoverConfig.isRemote;
71+
if (!isRemote) {
72+
busyDialogMessage = i18n.t('flow-validate-domain-home-in-progress');
73+
dialogHelper.updateBusyDialog(busyDialogMessage, 2/totalSteps);
74+
const errContext = i18n.t('wdt-discoverer-invalid-domain-home-error-prefix');
75+
const domainHomeValidationResult =
76+
await window.api.ipc.invoke('validate-domain-home', domainHomeDirectory, errContext);
77+
if (!domainHomeValidationResult.isValid) {
78+
const errMessage = domainHomeValidationResult.reason;
79+
dialogHelper.closeBusyDialog();
80+
await window.api.ipc.invoke('show-error-message', errTitle, errMessage);
81+
return Promise.resolve(false);
82+
}
7883
}
7984

8085
busyDialogMessage = i18n.t('flow-save-project-in-progress');
@@ -105,6 +110,11 @@ function (WdtActionsBase, ko, project, wktConsole, dialogHelper, projectIO, i18n
105110
if (discoverResults.isSuccess) {
106111
wktLogger.debug('discover complete: %s', discoverResults.modelFileContent);
107112
project.wdtModel.setModelFiles(discoverResults.modelFileContent);
113+
114+
if (isRemote) {
115+
const options = { resultData: discoverResults.resultData };
116+
dialogHelper.openDialog('discover-result-dialog', options);
117+
}
108118
return Promise.resolve(true);
109119
} else {
110120
let errMessage;

webui/src/js/viewModels/discover-dialog.js

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
/**
22
* @license
3-
* Copyright (c) 2021, Oracle and/or its affiliates.
3+
* Copyright (c) 2021, 2022, Oracle and/or its affiliates.
44
* Licensed under The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
55
*/
66
'use strict';
77

8-
define(['accUtils', 'knockout', 'utils/i18n', 'ojs/ojarraydataprovider', 'models/wkt-project',
8+
define(['accUtils', 'knockout', 'utils/i18n', 'utils/view-helper', 'ojs/ojarraydataprovider', 'models/wkt-project',
99
'utils/wdt-discoverer', 'ojs/ojknockout', 'ojs/ojinputtext', 'ojs/ojlabel', 'ojs/ojbutton',
10-
'ojs/ojdialog', 'ojs/ojformlayout', 'ojs/ojselectsingle', 'ojs/ojvalidationgroup'],
11-
function(accUtils, ko, i18n, ArrayDataProvider, project, wdtDiscoverer) {
10+
'ojs/ojdialog', 'ojs/ojformlayout', 'ojs/ojselectsingle', 'ojs/ojvalidationgroup', 'ojs/ojswitch'],
11+
function(accUtils, ko, i18n, viewHelper, ArrayDataProvider, project, wdtDiscoverer) {
1212
function DiscoverDialogModel(config) {
13+
const DIALOG_SELECTOR = '#discoverDialog';
1314

1415
this.connected = () => {
1516
if(config['hide']) {
@@ -18,11 +19,13 @@ function(accUtils, ko, i18n, ArrayDataProvider, project, wdtDiscoverer) {
1819

1920
accUtils.announce('Discover dialog loaded.', 'assertive');
2021

21-
// open the dialog after the current thread, which is loading this view model.
22+
this.dialogContainer = $(DIALOG_SELECTOR)[0];
23+
24+
// open the dialog when the container is ready.
2225
// using oj-dialog initial-visibility="show" causes vertical centering issues.
23-
setTimeout(function() {
24-
$('#discoverDialog')[0].open();
25-
}, 1);
26+
viewHelper.componentReady(this.dialogContainer).then(() => {
27+
this.dialogContainer.open();
28+
});
2629
};
2730

2831
this.labelMapper = (labelId, arg) => {
@@ -49,6 +52,15 @@ function(accUtils, ko, i18n, ArrayDataProvider, project, wdtDiscoverer) {
4952
this.adminUrl = ko.observable();
5053
this.adminUser = ko.observable();
5154
this.adminPassword = ko.observable();
55+
this.isRemote = ko.observable();
56+
57+
this.domainHomeHelp = ko.computed(() => {
58+
return this.labelMapper(this.isRemote() ? 'domain-home-remote-help' : 'domain-home-help');
59+
}, this);
60+
61+
this.domainHomeLabel = ko.computed(() => {
62+
return this.labelMapper(this.isRemote() ? 'domain-home-remote-label' : 'domain-home-label');
63+
}, this);
5264

5365
this.wdtDomainTypes = [
5466
{ key: 'WLS', label: this.labelMapper('wls-domain-type-label') },
@@ -80,9 +92,10 @@ function(accUtils, ko, i18n, ArrayDataProvider, project, wdtDiscoverer) {
8092
discoverConfig['adminUrl'] = this.adminUrl();
8193
discoverConfig['adminUser'] = this.adminUser();
8294
discoverConfig['adminPass'] = this.adminPassword();
95+
discoverConfig['isRemote'] = this.isRemote();
8396
}
8497

85-
$('#discoverDialog')[0].close();
98+
this.dialogContainer.close();
8699
wdtDiscoverer.executeDiscover(discoverConfig, this.online).then();
87100
} else {
88101
// show messages on all the components that have messages hidden.
@@ -92,7 +105,7 @@ function(accUtils, ko, i18n, ArrayDataProvider, project, wdtDiscoverer) {
92105
};
93106

94107
this.cancelDiscover = () => {
95-
$('#discoverDialog')[0].close();
108+
this.dialogContainer.close();
96109
};
97110

98111
this.chooseDomainHome = () => {
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* @license
3+
* Copyright (c) 2022, Oracle and/or its affiliates.
4+
* Licensed under The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
5+
*/
6+
'use strict';
7+
8+
define(['accUtils', 'knockout', 'utils/i18n', 'utils/view-helper', 'ojs/ojarraydataprovider',
9+
'ojs/ojknockout', 'ojs/ojbutton', 'ojs/ojdialog', 'ojs/ojtable'],
10+
function(accUtils, ko, i18n, viewHelper, ArrayDataProvider) {
11+
function DiscoverResultDialogModel(config) {
12+
const DIALOG_SELECTOR = '#discoverResultDialog';
13+
14+
this.connected = () => {
15+
accUtils.announce('Discover result dialog loaded.', 'assertive');
16+
17+
this.dialogContainer = $(DIALOG_SELECTOR)[0];
18+
19+
// open the dialog when the container is ready.
20+
// using oj-dialog initial-visibility="show" causes vertical centering issues.
21+
viewHelper.componentReady(this.dialogContainer).then(() => {
22+
this.dialogContainer.open();
23+
});
24+
};
25+
26+
this.labelMapper = (labelId, arg) => {
27+
if (arg) {
28+
return i18n.t(`discover-result-dialog-${labelId}`, arg);
29+
}
30+
return i18n.t(`discover-result-dialog-${labelId}`);
31+
};
32+
33+
this.anyLabelMapper = (labelId, arg) => {
34+
if (arg) {
35+
return i18n.t(labelId, arg);
36+
}
37+
return i18n.t(labelId);
38+
};
39+
40+
// organize the archive entries by type
41+
const resultData = config.resultData;
42+
const missingArchiveEntries = resultData.missingArchiveEntries;
43+
const archiveTypeMap = {};
44+
for(const entry of missingArchiveEntries) {
45+
const archiveType = entry.type;
46+
archiveTypeMap[archiveType] = archiveTypeMap[archiveType] || [];
47+
archiveTypeMap[archiveType].push({ file: entry.sourceFile, path: entry.path });
48+
}
49+
50+
// assemble the types into a list
51+
this.archiveTypes = [];
52+
for(const typeKey in archiveTypeMap) {
53+
const labelKey = 'archive-type-' + typeKey;
54+
const typeLabel = i18n.t(labelKey, typeKey);
55+
this.archiveTypes.push({ type: typeLabel, entries: new ArrayDataProvider(archiveTypeMap[typeKey]) });
56+
}
57+
58+
// sort archive types by resolved type name
59+
this.archiveTypes.sort((a, b) => {
60+
return a.type.localeCompare(b.type);
61+
});
62+
63+
this.typesColumnData = [
64+
{
65+
'headerText': this.labelMapper('file-location-header'),
66+
'sortProperty': 'file'
67+
},
68+
{
69+
'headerText': this.labelMapper('archive-path-header'),
70+
'sortable': 'disable'
71+
}
72+
];
73+
74+
this.closeDialog = () => {
75+
this.dialogContainer.close();
76+
};
77+
}
78+
79+
/*
80+
* Returns a constructor for the ViewModel.
81+
*/
82+
return DiscoverResultDialogModel;
83+
});

0 commit comments

Comments
 (0)