Skip to content

fixing removeFromArchive integration issues caused by WRC not maintaining their own archive state #225

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions electron/app/js/ipcRendererPreload.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const uuid = require('uuid');

const k8sUtils = require('./k8sUtils');
const fsUtils = require('./fsUtils');
const errorUtils = require('./errorUtils');
const WktApp = require('./wktApp');
const osUtils = require('./osUtils');
const i18n = require('./i18next.webui.config');
Expand Down Expand Up @@ -292,6 +293,7 @@ contextBridge.exposeInMainWorld(
'utils': {
generateUuid: () => uuid.v4(),
compareVersions: (version, otherVersion) => compareVersions(version, otherVersion),
getErrorMessage: (err) => errorUtils.getErrorMessage(err),
mainModule: mainModule,
wrcFrontendCompatibilityVersion: wrcFrontendCompatibilityVersion,
}
Expand Down
11 changes: 6 additions & 5 deletions electron/app/locales/en/webui.json
Original file line number Diff line number Diff line change
Expand Up @@ -1285,7 +1285,7 @@
"k8s-domain-undeployer-operator-installed-check-failed-error-message": "Unable to undeploy WebLogic domain because an error occurred while detecting if the WebLogic Kubernetes Operator {{operatorName}} is installed in Kubernetes namespace {{operatorNamespace}}: {{error}}.",
"k8s-domain-undeployer-update-operator-config-in-progress": "Updating WebLogic Kubernetes Operator {{operatorName}} in Kubernetes namespace {{operatorNamespace}} to stop managing WebLogic Domains in Kubernetes namespace {{domainNamespace}}",
"k8s-domain-undeployer-k8s-namespace-delete-failed-error-message": "Unable to undeploy the domain because an error occurred while trying to delete the Kubernetes namespace {{namespace}}: {{error}}.",
"k8s-domain-undeployer-k8s-object-delete-failed-error-message": "Unable to undeploy the domain because an error occurred while trying to delete the Kubernetes {{type}} object {{name}} from the Kubernetes namespace {{namespace}}: {{error}}.",
"k8s-domain-undeployer-k8s-object-delete-failed-error-message": "Unable to undeploy the domain because an error occurred while trying to delete the Kubernetes {{type}} {{name}} from the Kubernetes namespace {{namespace}}: {{error}}.",
"k8s-domain-undeployer-remove-domain-error-message": "Unable to update WebLogic Kubernetes Operator to remove Kubernetes namespace {{domainNamespace}} from its list of managed namespaces due to an error while upgrading the WebLogic Kubernetes Operator {{operatorName}} in namespace {{operatorNamespace}}: {{error}}.",
"k8s-domain-undeployer-undeploy-complete-title": "WebLogic Domain Undeployment from Kubernetes Complete",
"k8s-domain-undeployer-undeploy-domain-complete-message": "WebLogic domain {{domainName}} successfully undeployed from Kubernetes namespace {{domainNamespace}}.",
Expand Down Expand Up @@ -1854,9 +1854,8 @@
"quickstart-page5-list1-item-1": "Model - Defines the domain configuration.",
"quickstart-page5-list1-item-2": "Variables - Defines a set of tokens to be used in the model and their values.",
"quickstart-page5-list1-item-3": "Archive - Contains application-related and domain-related files and directories to be added to the domain.",
"quickstart-page5-paragraph-2-pre-url": "See the",
"quickstart-page5-wdt-url-label": "WebLogic Deploy Tooling documentation",
"quickstart-page5-paragraph-2-post-url": "for more information.",
"quickstart-page5-paragraph-2": "For more information, please see the documentation: ",
"quickstart-page5-wdt-url-label": "WebLogic Deploy Tooling",
"quickstart-page5-list2-heading": "The WKT UI application supports creating, discovering, importing, and editing WDT metadata models.",
"quickstart-page5-list2-item-1": "Use the File menu's Add Model menu to discover a model from a domain or import existing model files.",
"quickstart-page5-list2-item-2": "Use the Model section to create new or edit existing model-related files.",
Expand Down Expand Up @@ -1959,5 +1958,7 @@
"wrc-wdt-archive-add-bad-wrc-type-error": "Failed to add to archive because the WebLogic Remote Console entry type {{wrcType}} was not known.",
"wrc-wdt-archive-add-empty-file-path-error": "Failed to add to archive because WebLogic Remote Console entry type {{wrcType}} requires a non-empty file path.",
"wrc-wdt-archive-add-failed-error": "Failed to add WebLogic Remote Console entry type {{wrcType}} to archive: {{error}}",
"wrc-wdt-archive-remove-empty-path-error": "Failed to remove from archive because the archive path was empty."
"wrc-wdt-archive-remove-empty-path-error": "Failed to remove from archive because the archive path was empty.",
"wrc-wdt-archive-remove-failed-to-match-path-error": "Failed to remove {{archivePath}} from the archive because an error occurred while trying to match the path to its archive entry: {{error}}.",
"wrc-wdt-archive-remove-no-matching-node-error": "Failed to match WRC archive path {{archivePath}}'"
}
14 changes: 7 additions & 7 deletions webui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion webui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},
"dependencies": {
"@oracle/oraclejet": "^13.1.7",
"@oracle/wrc-jet-pack": "~2.4.2",
"@oracle/wrc-jet-pack": "^2.4.3-develop",
"ace-builds": "^1.15.0",
"i18next": "^22.4.9",
"jquery": "^3.6.3",
Expand Down
32 changes: 28 additions & 4 deletions webui/src/js/utils/wdt-archive-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
* Returns a singleton.
*/

define(['knockout', 'models/wkt-project'],
function (ko, project) {
define(['knockout', 'models/wkt-project', 'utils/wkt-logger'],
function (ko, project, wktLogger) {
function WdtArchiveHelper() {

this.project = project;
Expand Down Expand Up @@ -61,23 +61,31 @@ define(['knockout', 'models/wkt-project'],

this.addToArchive = async (archiveEntryTypeName, options) => {
const result = await window.api.ipc.invoke('add-archive-entry', archiveEntryTypeName, options);
wktLogger.debug('add-to-archive IPC call returned: %s', result);
// no archivePath means selection was cancelled, no need to notify or continue
if (!!result.archivePath) {
this._addArchiveUpdate(result.filePath, result.archiveUpdatePath);
this._addToArchiveModel(result.archivePath, options.fileType || 'emptyDir', result.childPaths);
}
return result.archivePath;
return result ? result.archiveUpdatePath : result;
};

this.removeFromArchive = (archivePath) => {
this.project.wdtModel.addArchiveUpdate('remove', archivePath);
if (archivePath) {
this._removeFromArchiveModel(archivePath, this.project.wdtModel.archiveRoots);
this._removeArchiveUpdate(archivePath);
}
};

// add an archive update that will be applied to the file on the next save.
this._addArchiveUpdate = (filePath, archivePath) => {
this.project.wdtModel.addArchiveUpdate('add', archivePath, filePath);
};

this._removeArchiveUpdate = (archivePath) => {
this.project.wdtModel.addArchiveUpdate('remove', archivePath);
};

// add the archive entry to the model, so it will be displayed in the tree.
this._addToArchiveModel = (archivePath, leafEntryFileType, leafChildPaths) => {
const childList = this.project.wdtModel.archiveRoots;
Expand Down Expand Up @@ -150,6 +158,22 @@ define(['knockout', 'models/wkt-project'],
}
}
};

this._removeFromArchiveModel = (archivePath, nodesObservable) => {
for (const node of nodesObservable()) {
if (node.id === archivePath) {
nodesObservable.remove(node);

// this shouldn't be required, but resolves tree view problems with emptied lists
nodesObservable.sort();
break;
}

if (node.children) {
this._removeFromArchiveModel(archivePath, node.children);
}
}
};
}

return new WdtArchiveHelper();
Expand Down
57 changes: 53 additions & 4 deletions webui/src/js/utils/wrc-wdt-archive.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
*/
'use strict';

define(['models/wkt-project', 'utils/i18n', 'utils/wdt-archive-helper'],
function(project, i18n, archiveHelper) {
define(['models/wkt-project', 'utils/i18n', 'utils/wdt-archive-helper', 'utils/wkt-logger'],
function(project, i18n, archiveHelper, wktLogger) {
class WrcWdtArchive {
constructor() {
this.project = project;
}

async addToArchive(wrcEntryTypeName, filePath, otherArgs={}) {
wktLogger.debug('entering WRC API addToArchive(%s, %s, %s)', wrcEntryTypeName, filePath, otherArgs);
const typeInfo = this._convertWrcType(wrcEntryTypeName);
if (typeof typeInfo === 'undefined') {
return Promise.reject(new Error(i18n.t('wrc-wdt-archive-add-empty-wrc-type-error')));
Expand All @@ -34,8 +35,11 @@ define(['models/wkt-project', 'utils/i18n', 'utils/wdt-archive-helper'],
const options =
archiveHelper.buildAddToArchiveOptions(archiveEntryTypeName, archiveEntry, filePath, filePathType, otherArgs);

wktLogger.debug('preparing to call archiveHelper.addToArchive(%s, %s)', archiveEntryTypeName, options);
return new Promise((resolve, reject) => {
archiveHelper.addToArchive(archiveEntryTypeName, options).then((archivePath) => {
wktLogger.debug('WRC API addToArchive(%s, %s, %s) returned %s', wrcEntryTypeName, filePath,
otherArgs, archivePath);
resolve(archivePath);
}).catch(err => {
const errMessage = err instanceof Error ? err.message : err;
Expand All @@ -46,11 +50,27 @@ define(['models/wkt-project', 'utils/i18n', 'utils/wdt-archive-helper'],
});
}

// WRC does not have the ability to remember the archivePath returned from addToArchive().
// This causes a problem for removing directories, where the underlying code depends on
// directory entries having a trailing slash. As such, we have to go determine if the
// archivePath argument is a directory and, if so, make sure it ends with a trailing slash
// before passing it on.
//
async removeFromArchive(archivePath) {
wktLogger.debug('entering WRC API removeFromToArchive(%s)', archivePath);
return new Promise((resolve, reject) => {
if (archivePath) {
archiveHelper.removeFromArchive(archivePath);
resolve();
try {
const updatedArchivePath = this._convertWrcArchivePath(archivePath);

wktLogger.debug('calling archiveHelper.removeFromArchive(%s)', updatedArchivePath);
archiveHelper.removeFromArchive(updatedArchivePath);
resolve();
} catch (err) {
const errorMessage = window.api.utils.getErrorMessage(err);
reject(new Error(i18n.t('wrc-wdt-archive-remove-failed-to-match-path-error',
{ archivePath, error: errorMessage})));
}
} else {
reject(new Error(i18n.t('wrc-wdt-archive-remove-empty-path-error')));
}
Expand Down Expand Up @@ -83,6 +103,35 @@ define(['models/wkt-project', 'utils/i18n', 'utils/wdt-archive-helper'],

return result;
}

_convertWrcArchivePath(wrcArchivePath, nodesObservable = this.project.wdtModel.archiveRoots) {
wktLogger.debug('Entering _convertWrcArchivePath(%s, %s)', wrcArchivePath, JSON.stringify(nodesObservable()));
const wrcPath = wrcArchivePath.endsWith('/') ? wrcArchivePath.slice(0, -1) : wrcArchivePath;
let result;
for (const node of nodesObservable()) {
if (wrcPath === node.id || wrcPath + '/' === node.id) {
wktLogger.debug('Found matching node id = %s', node.id);
return node.id;
}

if (node.children) {
wktLogger.debug('node %s has children', node.id);
result = this._convertWrcArchivePath(wrcArchivePath, node.children);
if (result) {
wktLogger.debug('return nested _convertWrcArchivePath() call from node %s: %s', node.id, result);
return result;
}
wktLogger.debug('No match found for %s in children of node %s', wrcArchivePath, node.id);
}
}

// If we are back at the topmost level and have no result, throw an error.
if (nodesObservable === this.project.wdtModel.archiveRoots && !result) {
throw new Error(i18n.t('wrc-wdt-archive-remove-no-matching-node-error', {archivePath: wrcArchivePath}));
}
wktLogger.debug('Exiting _convertWrcArchivePath() returning %s', result);
return result;
}
}

return new WrcWdtArchive();
Expand Down
24 changes: 0 additions & 24 deletions webui/src/js/viewModels/model-archive-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,32 +41,8 @@ function(accUtils, ko, i18n, project, dialogHelper, archiveHelper, ArrayTreeData

this.deleteSelected = () => {
const path = this.selectedItem();

// delete the path from the UI
this._deleteArchiveNode(path, project.wdtModel.archiveRoots);

// add a 'remove' operation to be applied on save
archiveHelper.removeFromArchive(path);
};

// recursively search the archive tree for a node matching the ID,
// then delete that element from its parent list.
this._deleteArchiveNode = (id, list) => {
for (let item of list()) {
if(item.id === id) {
list.remove(item);

// this shouldn't be required, but resolves tree view problems with emptied lists
list.sort();
break;
}

const children = item['children'];
if(children) {
this._deleteArchiveNode(id, children);
}
}
};
}

/*
Expand Down
2 changes: 1 addition & 1 deletion webui/src/js/viewModels/model-design-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ function(accUtils, i18n, ko, project, urlCatalog, wrcArchiveHelper, viewHelper,
// Set model properties provider option
providerOptions['modelProperties'] = JSON.parse(JSON.stringify(this.project.wdtModel.getModelPropertiesObject().observable()));
// Set model archive provider option
providerOptions['modelArchive'] = this.project.wdtModel.archiveRoots;
// providerOptions['modelArchive'] = this.project.wdtModel.archiveRoots;

return providerOptions;
};
Expand Down
3 changes: 1 addition & 2 deletions webui/src/js/views/quickstart/page5-view.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@ <h6><oj-bind-text value="[[labelMapper('title')]]"></oj-bind-text></h6>
</ul>

<p>
<oj-bind-text value="[[labelMapper('paragraph-2-pre-url')]]"></oj-bind-text>
<oj-bind-text value="[[labelMapper('paragraph-2')]]"></oj-bind-text>
<a href="https://oracle.github.io/weblogic-deploy-tooling/concepts/model/">
<oj-bind-text value="[[labelMapper('wdt-url-label')]]"></oj-bind-text>
</a>
<oj-bind-text value="[[labelMapper('paragraph-2-post-url')]]"></oj-bind-text>
</p>

<p><oj-bind-text value="[[labelMapper('list2-heading')]]"></oj-bind-text></p>
Expand Down