ENTAXY-634 release version 1.9.0

This commit is contained in:
2023-08-11 03:05:45 +03:00
parent 3cc15f7459
commit 574fd61847
1720 changed files with 93209 additions and 44106 deletions

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
@ -31,22 +37,36 @@ var Entaxy;
<button type="button" class="close" aria-label="Close" ng-click="$ctrl.cancel()">
<span class="pficon pficon-close" aria-hidden="true"></span>
</button>
<h4 class="modal-title">Add Connector to {{$ctrl.profileName}}</h4>
<h4 class="modal-title">{{$ctrl.modalTitle}}</h4>
</div>
<div ng-if="$ctrl.step1">
<div ng-if="$ctrl.step1 && $ctrl.profiles">
<div class="modal-body-header">
<h2>Choose profile to attach connector to</h2>
</div>
<div class="modal-body" style="height:433px; max-height:433px">
<entaxy-modal-list items="$ctrl.profiles" selected="$ctrl.selectedProfile"
change-selection="$ctrl.changeProfileSelection" enable-dbl-click="true"></entaxy-modal-list>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-click="$ctrl.next()"
ng-disabled="!$ctrl.selectedProfile">Next</button>
</div>
</div>
<div ng-if="$ctrl.step2">
<div class="modal-body-header">
<h2>Choose connector template</h2>
</div>
<div class="modal-body" style="height:433px; max-height:433px">
<entaxy-modal-list items="$ctrl.viewedTemplates" selected="$ctrl.selectedItem"
change-selection="$ctrl.changeSelection"></entaxy-modal-list>
<entaxy-modal-list items="$ctrl.templates" selected="$ctrl.selectedTemplate"
change-selection="$ctrl.changeTemplateSelection" enable-dbl-click="true"></entaxy-modal-list>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-click="$ctrl.back()" ng-if="$ctrl.profiles">Back</button>
<button type="button" class="btn btn-default" ng-click="$ctrl.next()"
ng-disabled="!$ctrl.selectedItem">Next</button>
ng-disabled="!$ctrl.selectedTemplate">Next</button>
</div>
</div>
<form name="connectorForm" class="form-horizontal" ng-if="$ctrl.step2" ng-submit="$ctrl.saveConnector($ctrl.formFields)">
<form name="connectorForm" class="form-horizontal" ng-if="$ctrl.step3" ng-submit="$ctrl.saveConnector($ctrl.formFields)">
<div class="modal-body" style="height:503px; max-height:503px;">
<div class="modal-body-header">
<h2>Fill in connector template parameters</h2>
@ -56,7 +76,7 @@ var Entaxy;
<label class="col-sm-3 control-label" ng-class="{'required-pf': formField.isRequired}" for="{{formField.name}}">{{formField.label}}</label>
<div class="col-sm-8">
<input type="{{formField.type}}" id="{{formField.name}}" ng-class="{'form-control': formField.type !== 'checkbox'}"
ng-model="formField.value" ng-readonly="formField.isReadOnly">
ng-model="formField.value" ng-readonly="formField.isReadOnly" ng-if="!formField.typeInfo">
<span class="help-block" ng-show="$ctrl.errors[formField.name]">{{$ctrl.errors[formField.name]}}</span>
</div>
</div>
@ -72,52 +92,70 @@ var Entaxy;
})
.name;
function EntaxyAddConnectorModalController(workspace) {
function EntaxyAddConnectorModalController(workspace, jolokia) {
'ngInject';
var ctrl = this;
ctrl.$onInit = function() {
ctrl.step1 = true;
ctrl.step2 = false;
let templates = Entaxy.getConnectorTemplates();
ctrl.templates = templates.map(template => { return { name: template, displayName: template }});
ctrl.viewedTemplates = ctrl.templates;
ctrl.profileName = ctrl.resolve.profileName;
ctrl.profiles = ctrl.resolve.profiles;
if (ctrl.profiles) {
ctrl.step1 = true;
ctrl.step2 = false;
ctrl.step3 = false;
} else {
ctrl.step1 = false;
ctrl.step2 = true;
ctrl.step3 = false;
}
ctrl.modalTitle = ctrl.resolve.profileName ?
'Add Legacy Connector to ' + ctrl.resolve.profileName : 'Add Legacy Connector';
}
ctrl.listConfig = {
selectionMatchProp: 'name',
selectItems: true,
showSelectBox: false,
dlbClick: true,
onDblClick: function(item, event){
ctrl.listConfig.selectedItems.push(item);
ctrl.next();
ctrl.changeProfileSelection = function(item, isDblClicked) {
ctrl.selectedProfile = item;
if (isDblClicked) {
ctrl.next();
}
}
ctrl.changeSelection = function(item, isDblClicked) {
ctrl.selectedItem = item;
ctrl.changeTemplateSelection = function(item, isDblClicked) {
ctrl.selectedTemplate = item;
if (isDblClicked) {
ctrl.next();
}
}
ctrl.next = function() {
ctrl.step1 = false;
ctrl.step2 = true;
if (ctrl.step1 === true) {
ctrl.step1 = false;
ctrl.step2 = true;
} else if (ctrl.step2 === true) {
ctrl.step2 = false;
ctrl.step3 = true;
}
if (ctrl.step3 === true) {
defineFormFields();
}
}
function defineFormFields() {
if (!ctrl.formFields || ctrl.selectedTemplate.name !== ctrl.formFields[0].value) {
ctrl.formFields = Entaxy.getConnectorTemplateParams(ctrl.selectedTemplate.name);
if (!ctrl.formFields || ctrl.selectedItem.name !== ctrl.formFields[0].value) {
ctrl.formFields = Entaxy.getConnectorTemplateParams(ctrl.selectedItem.name);
ctrl.formFields.unshift({
label: 'templateName',
displayName: 'Template Name',
type: 'java.lang.String',
helpText: null,
value: ctrl.selectedItem.name,
value: ctrl.selectedTemplate.name,
isReadOnly: true
});
ctrl.formFields.forEach(formField => {
@ -131,8 +169,13 @@ var Entaxy;
}
ctrl.back = function() {
ctrl.step1 = true;
ctrl.step2 = false;
if (ctrl.step2 === true) {
ctrl.step1 = true;
ctrl.step2 = false;
} else if (ctrl.step3 === true) {
ctrl.step2 = true;
ctrl.step3 = false;
}
}
ctrl.cancel = function() {
@ -144,6 +187,7 @@ var Entaxy;
if (Object.keys(ctrl.errors).length === 0) {
let connectorArgs = {
profile: ctrl.selectedProfile,
connectorTemplateName: ctrl.formFields.shift().value,
connectorFields: ctrl.formFields.map(formField => { return { label: formField.name, value: formField.value }; })
};
@ -164,6 +208,6 @@ var Entaxy;
return errors;
}
}
EntaxyAddConnectorModalController.$inject = ['workspace'];
EntaxyAddConnectorModalController.$inject = ['workspace', 'jolokia'];
})(Entaxy || (Entaxy = {}));

View File

@ -0,0 +1,99 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module.component('entaxyAddFolderModal', {
bindings: {
modalInstance: '<',
resolve: '<'
},
template:
`
<div class="entaxy-simple-modal-container">
<div class="modal-header">
<button type="button" class="close" aria-label="Close" ng-click="$ctrl.cancel()">
<span class="pficon pficon-close" aria-hidden="true"></span>
</button>
<h4 class="modal-title">Set folder name</h4>
</div>
<div class="modal-body-small">
<div class="form-group" ng-class="{'has-error': $ctrl.error}">
<div class="col-sm-12">
<input type="text" class="form-control" ng-model="$ctrl.name">
<span class="help-block" ng-show="$ctrl.error">{{$ctrl.error}}</span>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" ng-click="$ctrl.save()">Save</button>
</div>
</div>
`,
controller: entaxyAddFolderModalController
})
.name;
function entaxyAddFolderModalController($uibModal) {
'ngInject';
let ctrl = this;
ctrl.$onInit = function() {
ctrl.names = ctrl.resolve.names;
}
ctrl.cancel = function(reason) {
ctrl.modalInstance.dismiss(reason);
}
ctrl.save = function() {
ctrl.error = validate();
if (!ctrl.error) {
ctrl.modalInstance.close(ctrl.name);
}
}
function validate() {
let error;
if (!ctrl.name || ctrl.name.length == 0 || ctrl.name.trim().length == 0) {
return 'Folder name must not be empty';
}
['/', '\\', ':', '*', '?', '<', '>', '|'].forEach((symbol) => {
if (ctrl.name.indexOf(symbol) >= 0) {
error = 'Folder name must not include symbols /\\:*?<>|';
}
});
ctrl.names.forEach((name) => {
if (name === ctrl.name) {
error = 'Folder with this name already exists';
}
});
return error;
}
}
entaxyAddFolderModalController.$inject = ['$uibModal'];
})(Entaxy || (Entaxy = {}));

View File

@ -0,0 +1,321 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module
.component('entaxyAllConnectorsTable', {
template:
`
<h2>
Connectors
</h2>
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
<pf-table-view config="$ctrl.tableConfig"
columns="$ctrl.tableColumns"
action-buttons="$ctrl.tableActionButtons"
menu-actions="$ctrl.menuActions"
page-config="$ctrl.pageConfig"
items="$ctrl.viewedItems">
</pf-table-view>
`,
controller: EntaxyAllConnectorsTableController
})
.name;
function EntaxyAllConnectorsTableController($q, workspace, $scope, operationsService, jolokia, jolokiaService, entaxyService, entaxyLegacyConnectorService) {
'ngInject';
let ctrl = this;
ctrl.workspace = workspace;
ctrl.itemName = "Connector";
ctrl.statusName = "BundleState";
let filterValues = Entaxy.getAllBundleStates();
ctrl.tableConfig = {
selectionMatchProp: 'displayName',
showCheckboxes: false
};
ctrl.toolbarConfig = {
filterConfig: {
fields: [
{
id: 'direction',
title: 'Direction',
placeholder: 'Filter by Direction...',
filterType: 'select',
filterValues: ['in', 'out']
},
{
id: 'displayName',
title: 'Name',
placeholder: 'Filter by Name...',
filterType: 'text'
},
{
id: 'profile',
title: 'Profile',
placeholder: 'Filter by Profile...',
filterType: 'select',
filterValues: getProfiles().map(profile => profile.name)
},
{
id: 'status',
title: 'Status',
placeholder: 'Filter by Status...',
filterType: 'select',
filterValues: filterValues
}
],
appliedFilters: [],
onFilterChange: filterChange
},
isTableView: true
};
ctrl.tableColumns = [
{ header: 'Direction', itemField: 'direction' },
{ header: 'Name', itemField: 'displayName' },
{ header: 'Profile', itemField: 'profile' },
{ header: 'Status', itemField: 'status' }
];
ctrl.pageConfig = Entaxy.getStandardPageConfig();
function filterChange(filters) {
ctrl.viewedItems = Entaxy.applyFilters(ctrl.items, filters, matchesFilter);
ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.viewedItems.length;
};
function matchesFilter(item, filter) {
let match = true;
if (filter.id === 'direction') {
match = item.direction === filter.value;
} else if (filter.id === 'displayName') {
match = item.displayName.match(filter.value) !== null;
} else if (filter.id === 'profile') {
match = item.profile === filter.value;
} else if (filter.id === 'status') {
match = item.status === filter.value;
}
return match;
};
ctrl.items = [];
ctrl.viewedItems = [];
ctrl.$onInit = function() {
populateTable();
let primaryActions = [
{
name: 'Add Connector',
actionFn: () => ctrl.showModal(Entaxy.MODAL_MODES.ADD),
isDisabled: getProfiles().length === 0
},
{
name: 'Add Legacy Connector',
actionFn: () => ctrl.showAddLegacyConnectorModal(),
isDisabled: getProfiles().length === 0
}
];
ctrl.toolbarConfig.actionsConfig = {
primaryActions: primaryActions
};
ctrl.tableActionButtons = [
{ name: 'Start', title: 'Start ' + ctrl.itemName, actionFn: startItem },
{ name: 'Stop', title: 'Stop ' + ctrl.itemName, actionFn: stopItem },
{ name: 'Uninstall', title: 'Uninstall ' + ctrl.itemName, actionFn: uninstallItem }
];
ctrl.menuActions = [
{ name: 'View Properties', title: 'View ' + ctrl.itemName + ' Properties', actionFn: showPropertiesModal },
{ name: 'Edit Properties', title: 'Edit ' + ctrl.itemName + ' Properties', actionFn: showPropertiesModal }
];
}
function showPropertiesModal(action, item) {
if (action.name === 'View Properties') {
ctrl.showModal(Entaxy.MODAL_MODES.VIEW, item);
} else if (action.name === 'Edit Properties') {
ctrl.showModal(Entaxy.MODAL_MODES.EDIT, item);
}
}
function populateTable() {
let items = [];
let promises = [];
let profilesFolder = entaxyService.getDomainFolder()
.findDescendant(child => child.objectName && child.objectName.endsWith('category=profiles'));
let mbeans = entaxyService.getAllChildMBeansByRuntimeType(profilesFolder, 'entaxy.runtime.connector');
mbeans.forEach(mbean => {
let profileMBeanName = findConnectorParentProfileMBeanName(mbean);
promises.push(jolokiaService.getAttributes(mbean.objectName, [ctrl.statusName, 'Name', 'DisplayName', 'Direction'])
.then((response) => {
items.push({
name: response['Name'],
displayName: response['DisplayName'] === '' || response['DisplayName'].startsWith('ERROR') ? response['Name'] : response['DisplayName'],
direction: response['Direction'] === '' || response['Direction'].startsWith('ERROR') ? '-' : response['Direction'],
status: response[ctrl.statusName],
mbeanName: mbean.objectName,
profileMBeanName: profileMBeanName,
profile: jolokia.getAttribute(profileMBeanName, 'Name')
});
}));
});
$q.all(promises)
.then(() => {
ctrl.items = items;
ctrl.viewedItems = items;
let filters = ctrl.toolbarConfig.filterConfig.appliedFilters;
if (filters.length > 0) {
filterChange(filters);
} else {
ctrl.toolbarConfig.filterConfig.resultsCount = items.length;
}
});
}
function findConnectorParentProfileMBeanName(connectorMBean) {
let parent = connectorMBean.parent;
if (parent.objectName) {
let attributes = jolokia.getAttribute(parent.objectName);
if (attributes.RuntimeType === 'entaxy.runtime.profile') {
return parent.objectName;
}
} else {
return findConnectorParentProfileMBeanName(parent);
}
}
function getProfiles() {
let profilesFolder = entaxyService.getDomainFolder()
.findDescendant(child => child.objectName && child.objectName.endsWith('category=profiles'));
let profileMbeans = entaxyService.getAllChildMBeansByRuntimeType(profilesFolder, 'entaxy.runtime.profile');
let profiles = profileMbeans.length > 0 ?
profileMbeans.map(mbean => {
let name = jolokia.getAttribute(mbean.objectName, 'Name');
return {
name: name,
displayName: name,
mbeanName: mbean.objectName
};
}) : [];
return profiles;
}
ctrl.showModal = function(mode, item) {
if (mode === Entaxy.MODAL_MODES.ADD) {
let resolve = {
mode: () => mode,
itemType: () => ctrl.itemName,
profiles: () => getProfiles()
};
entaxyService.openAddItemModalAndProcessResults(resolve);
} else {
let mbeanName = item.profileMBeanName;
entaxyService.openEditItemModalAndProcessResults(mbeanName, ctrl.itemName, item.name, mode);
}
}
ctrl.showAddLegacyConnectorModal = function() {
let resolve = {
profiles: () => getProfiles()
};
entaxyLegacyConnectorService.openAddLegacyConnectorModal(resolve).then(connectorArgs => {
addLegacyConnector(connectorArgs);
});
}
function addLegacyConnector(connectorArgs) {
let args = entaxyLegacyConnectorService.getArguments(connectorArgs);
let mbeanName = connectorArgs.profile.mbeanName;
operationsService.executeOperation(mbeanName, { name: 'addConnector' }, args)
.then(result => {
Core.notification('success', result, 3000);
}).catch(error => {
Core.notification('danger', error, 5000);
});
}
$scope.$on(Jmx.TreeEvent.Updated, () => {
populateTable();
});
function startItem(action, item) {
if (item.status !== 'Active') {
processOperation(item.profileMBeanName, 'start', item.name);
} else {
Core.notification('info', ctrl.itemName + ' has been already started');
}
}
function stopItem(action, item) {
if (item.status !== 'Resolved') {
processOperation(item.profileMBeanName, 'stop', item.name);
} else {
Core.notification('info', ctrl.itemName + ' has been already stopped');
}
}
function uninstallItem(action, item) {
let title = 'Confirm Uninstalling';
let message = 'Do you want to uninstall ' + ctrl.itemName.toLowerCase() + ' ' + item.displayName + '?';
entaxyService.openConfirmationWindow(title, message).then(() => {
processOperation(item.profileMBeanName,'remove', item.name);
});
}
function processOperation(mbeanName, operationName, selectedItemName) {
let operation = { name: operationName + ctrl.itemName };
entaxyService.processTableOperation(mbeanName, operation, selectedItemName);
}
ctrl.dismissAlert = () => ctrl.alert = null;
}
EntaxyAllConnectorsTableController.$inject = ['$q', 'workspace', '$scope', 'operationsService', 'jolokia', 'jolokiaService', 'entaxyService', 'entaxyLegacyConnectorService'];
})(Entaxy || (Entaxy = {}));

View File

@ -0,0 +1,77 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module.component('entaxyConfirmationModal', {
bindings: {
modalInstance: '<',
resolve: '<'
},
template:
`
<div class="entaxy-simple-modal-container message-modal-container">
<div class="modal-header">
<button type="button" class="close" aria-label="Close" ng-click="$ctrl.cancel()">
<span class="pficon pficon-close" aria-hidden="true"></span>
</button>
<h4 class="modal-title">{{$ctrl.title}}</h4>
</div>
<div class="modal-body-small">
<span class="simple-modal-message">
{{$ctrl.message}}
</span>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-click="$ctrl.cancel()">Cancel</button>
<button type="submit" class="btn btn-primary" ng-click="$ctrl.confirm()">Confirm</button>
</div>
</div>
`,
controller: entaxyConfirmationModalController
})
.name;
function entaxyConfirmationModalController($uibModal) {
'ngInject';
let ctrl = this;
ctrl.$onInit = function() {
ctrl.title = ctrl.resolve.title;
ctrl.message = ctrl.resolve.message;
}
ctrl.cancel = function(reason) {
ctrl.modalInstance.dismiss(reason);
}
ctrl.confirm = function() {
ctrl.modalInstance.close(true);
}
}
entaxyConfirmationModalController.$inject = ['$uibModal'];
})(Entaxy || (Entaxy = {}));

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
@ -29,7 +35,8 @@ var Entaxy;
{{$ctrl.pageTitle}}
</h2>
<entaxy-table item-name="Connection" folder-name="Коннекции" status-name="Status" object-name="name"></entaxy-table>
<entaxy-table runtime-type="entaxy.runtime.connection"
status-name="Status" object-name="name"></entaxy-table>
`
})
.name;

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
@ -30,7 +36,7 @@ var Entaxy;
{{$ctrl.pageTitle}}
</h2>
<entaxy-table item-name="Connector" folder-name="Коннекторы"
<entaxy-table runtime-type="entaxy.runtime.connector"
status-name="BundleState" object-name="systemName"
extra-primary-actions-config="$ctrl.config"
is-parent-dependent="true"></entaxy-table>
@ -40,12 +46,11 @@ var Entaxy;
})
.name;
function EntaxyConnectorsController(workspace, $scope, $uibModal, operationsService, jolokiaService) {
function EntaxyConnectorsController(workspace, $scope, $uibModal, operationsService, jolokia, entaxyLegacyConnectorService) {
'ngInject';
var ctrl = this;
ctrl.workspace = workspace;
var entaxyJmxDomain = localStorage['entaxyJmxDomain'] || "ru.entaxy.esb";
let primaryActions = [ { name: 'Add Legacy Connector', actionFn: () => ctrl.showAddConnectorModal() } ];
ctrl.config = {
@ -53,48 +58,25 @@ var Entaxy;
isTableUpdateNeeded: true
}
ctrl.connectors = [];
ctrl.viewedConnectors = [];
ctrl.showAddConnectorModal = function() {
let selectedMBean = workspace.getSelectedMBean();
let selectedMBeanName = workspace.getSelectedMBeanName();
$uibModal.open({
component: 'entaxyAddConnectorModal',
resolve: {
connector: null,
profileName: () => selectedMBean.title
},
size: 'lg',
backdrop: 'static'
})
.result.then(connectorArgs => {
let resolve = {
profileName: () => jolokia.getAttribute(selectedMBeanName, 'Name')
};
entaxyLegacyConnectorService.openAddLegacyConnectorModal(resolve).then(connectorArgs => {
addConnector(connectorArgs);
});
}
function addConnector(connectorArgs) {
let args = [];
args.push(connectorArgs.connectorTemplateName);
let argParams = '{';
_.forEach(connectorArgs.connectorFields, (field) => {
argParams += '\"' + field.label + '\":\"' + field.value + '\",';
});
if (argParams.length > 1) {
argParams = argParams.substring(0, argParams.length - 1);
}
argParams += '}';
args.push(argParams);
let args = entaxyLegacyConnectorService.getArguments(connectorArgs);
let mbeanName = ctrl.workspace.getSelectedMBeanName();
operationsService.executeOperation(mbeanName, { name: 'addConnector' }, args)
.then(result => {
if (ctrl.config.isTableUpdateNeeded && ctrl.config.updateTableFn) {
$scope.$on(Jmx.TreeEvent.Updated, ctrl.config.updateTableFn);
}
Core.notification('success', result, 3000);
}).catch(error => {
Core.notification('danger', error, 5000);
@ -104,6 +86,6 @@ var Entaxy;
ctrl.dismissAlert = () => ctrl.alert = null;
}
EntaxyConnectorsController.$inject = ['workspace', '$scope', '$uibModal', 'operationsService', 'jolokiaService'];
EntaxyConnectorsController.$inject = ['workspace', '$scope', '$uibModal', 'operationsService', 'jolokia', 'entaxyLegacyConnectorService'];
})(Entaxy || (Entaxy = {}));

View File

@ -0,0 +1,136 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module
.component('entaxyConnectorsWithFlow', {
bindings: {
direction: '@',
connectors: '<',
profileName: '<',
editCustomizationPointFn: '<'
},
template:
`
<div class="connectors-group-container">
<span class="connectors-group-title">{{$ctrl.connectorsGroupTitle}}</span>
<div class="connectors-with-flow-container">
<div class="connectors-container">
<div class="connector-block" ng-repeat="connector in $ctrl.connectors"
ng-click="$ctrl.editConnectorProperties(connector, $event)">
<span>{{connector.name}}</span>
<div id="{{connector.name}}_{{customizationPoint}}" class="customization-point-block"
ng-repeat="customizationPoint in $ctrl.connectorCustomizationPoints"
ng-click="$ctrl.editConnectorCustomizationPoint(connector, customizationPoint, $event)">
{{customizationPoint}}
</div>
</div>
</div>
<div id="{{$ctrl.direction}}-flow-block" class="flow-block">
<span>{{$ctrl.flowName}}</span>
<div id="{{$ctrl.direction}}-flow_{{customizationPoint}}" class="customization-point-block"
ng-repeat="customizationPoint in $ctrl.flowCustomizationPoints"
ng-click="$ctrl.editFlowCustomizationPoint(customizationPoint, $event)">
{{customizationPoint}}
</div>
</div>
</div>
</div>
`,
controller: entaxyConnectorsWithFlowController
})
.name;
function entaxyConnectorsWithFlowController(workspace, operationsService, entaxyService) {
'ngInject';
let ctrl = this;
ctrl.$onInit = function() {
if (ctrl.direction) {
let isDirectionIn = ctrl.direction === 'in';
ctrl.connectorsGroupTitle = '--- ' + ctrl.direction.toUpperCase() + ' ---';
ctrl.flowName = ctrl.direction.toUpperCase() + '-FLOW';
ctrl.connectorCustomizationPoints = isDirectionIn ? ['pre-route', 'response'] : ['pre-output', 'postprocess'];
ctrl.flowCustomizationPoints = isDirectionIn ? ['pre-route', 'response'] : ['pre-route', 'postprocess'];
} else {
Entaxy.log.error('Connectors group direction is not defined');
}
}
ctrl.editConnectorProperties = function (connector, event) {
event.stopPropagation();
let mbeanName = workspace.getSelectedMBeanName();
let itemType = 'Connector';
let mode = Entaxy.MODAL_MODES.EDIT;
entaxyService.openEditItemModalAndProcessResults(mbeanName, itemType, connector.name, mode);
}
ctrl.editConnectorCustomizationPoint = function (connector, customizationPoint, event) {
event.stopPropagation();
let mbeanName = workspace.getSelectedMBeanName();
let propertyName = getPropertyNameForConnectorCustomizationPoint(customizationPoint);
ctrl.editCustomizationPointFn(mbeanName, 'getConnectorConfig', [ connector.name ], propertyName);
}
ctrl.editFlowCustomizationPoint = function (customizationPoint, event) {
event.stopPropagation();
let selectedMbean = workspace.getSelectedMBean();
let mbeanName = selectedMbean.parent.objectName;
let propertyName = getPropertyNameForFlowCustomizationPoint(customizationPoint);
ctrl.editCustomizationPointFn(mbeanName, 'getProfileConfig', [ ctrl.profileName ], propertyName);
}
function getPropertyNameForConnectorCustomizationPoint(customizationPointName) {
switch (customizationPointName) {
case 'pre-route':
case 'pre-output':
return customizationPointName;
case 'response':
case 'postprocess':
return 'responseRoute';
};
}
function getPropertyNameForFlowCustomizationPoint(customizationPointName) {
switch (customizationPointName) {
case 'pre-route':
return ctrl.direction + '-flow-' + customizationPointName;
case 'response':
case 'postprocess':
return ctrl.direction + '-flow-response';
};
}
}
entaxyConnectorsWithFlowController.$inject = ['workspace', 'operationsService', 'entaxyService'];
})(Entaxy || (Entaxy = {}));

View File

@ -0,0 +1,67 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module
.component('entaxyCrumbs', {
bindings: {
rootCrumb: '<',
crumbs: '='
},
template:
`
<div class="crumbs no-selection">
<div class="crumb" ng-if="$ctrl.rootCrumb">
<div class="crumb-info" ng-click="$ctrl.changeLocationToRoot()">
{{$ctrl.rootCrumb}}
</div>
<span class="fa fa-angle-right" ng-if="$ctrl.crumbs.length > 0"></span>
</div>
<div class="crumb" ng-repeat="crumb in $ctrl.crumbs track by $index">
<div class="crumb-info" ng-click="$ctrl.changeLocation(crumb)">
{{crumb}}
</div>
<span class="fa fa-angle-right"></span>
</div>
</div>
`,
controller: entaxyCrumbsController
})
.name;
function entaxyCrumbsController() {
let ctrl = this;
ctrl.changeLocationToRoot = function () {
ctrl.crumbs = [];
}
ctrl.changeLocation = function (crumb) {
let index = ctrl.crumbs.indexOf(crumb);
ctrl.crumbs.length = index + 1;
}
}
})(Entaxy || (Entaxy = {}));

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;

View File

@ -0,0 +1,109 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module
.directive('entaxyFileDrop', ['$parse', function ($parse) {
return {
restrict: 'A',
replace: false,
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
let enterTarget = null;
element.on('dragenter', function (e) {
e.preventDefault();
e.stopPropagation();
enterTarget = e.target;
element.addClass('highlighted');
createNotification();
});
element.on('dragover', function (e) {
e.preventDefault();
e.stopPropagation();
});
element.on('dragleave', function (e) {
if (e.target === enterTarget) {
e.preventDefault();
e.stopPropagation();
element.removeClass('highlighted');
removeNotification();
}
});
let notificationContainer = null;
function createNotification() {
if (notificationContainer === null) {
notificationContainer = document.createElement('div');
notificationContainer.className = 'upload-notification';
let span = document.createElement('span');
span.className = 'fa fa-upload';
notificationContainer.appendChild(span);
notificationContainer.appendChild(document.createTextNode('Drop file to upload'));
let elementWidth = element.width();
let offset = 150 + elementWidth/2 + 20;
notificationContainer.style.left = 'calc(100vw - ' + offset + 'px)';
element.append(notificationContainer);
}
}
function removeNotification() {
if (notificationContainer !== null) {
notificationContainer.parentNode.removeChild(notificationContainer);
notificationContainer = null;
}
}
element.on('drop', function (e) {
e.preventDefault();
e.stopPropagation();
element.removeClass('highlighted');
removeNotification();
if (e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files.length > 0) {
ngModel.$setViewValue(e.originalEvent.dataTransfer.files[0]);
let processFn = $parse(attrs.processFn);
if (processFn) {
processFn(scope);
}
}
return false;
});
}
};
}])
.name;
})(Entaxy || (Entaxy = {}));

View File

@ -0,0 +1,72 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module
.component('entaxyFilePanel', {
bindings: {
items: '=',
selectedItem: '<',
view: '<',
changeSelectionFn: '<',
openFn: '<'
},
template:
`
<!-- //todo style add min-width -->
<div class="file-panel no-selection" ng-class="{'tile-theme': $ctrl.view === 'tiles', 'list-theme': $ctrl.view === 'list'}">
<div ng-class="{'tile': $ctrl.view === 'tiles', 'list': $ctrl.view === 'list', 'active': $ctrl.selectedItem === item}"
ng-repeat="item in $ctrl.items" ng-click="$ctrl.changeSelection(item)" ng-dblclick="$ctrl.open(item)">
<div class="icon">
<span ng-class="{'fa fa-folder': item.isFolder, 'fa fa-file': !item.isFolder}"></span>
</div>
<div class="name" data-toggle="tooltip" title="{{item.name}}">
{{ $ctrl.view === 'tiles' ? (item.name | limitTo: 22) : item.name }}{{ ($ctrl.view === 'tiles' && item.name.length > 22) ? '...' : '' }}
</div>
</div>
<div class="tile empty" ng-if="$ctrl.view === 'tiles'" ng-repeat="item in $ctrl.emptyItems"></div>
</div>
`,
controller: entaxyFilePanelController
})
.name;
function entaxyFilePanelController() {
let ctrl = this;
ctrl.$onInit = function () {
ctrl.emptyItems = [{},{},{},{},{},{},{},{}];
}
ctrl.changeSelection = function (item) {
ctrl.changeSelectionFn(item);
}
ctrl.open = function (item) {
ctrl.openFn(item);
}
}
})(Entaxy || (Entaxy = {}));

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
@ -39,12 +45,11 @@ var Entaxy;
<h2>{{$ctrl.firstStepTitle}}</h2>
</div>
<div class="modal-body">
<entaxy-modal-list-with-description items="$ctrl.factories" selected-item="$ctrl.selectedItem"
change-selection="$ctrl.changeSelection"></entaxy-modal-list-with-description>
<entaxy-modal-list items="$ctrl.profiles" selected="$ctrl.selectedProfile"
change-selection="$ctrl.changeProfileSelection" enable-dbl-click="true"></entaxy-modal-list>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-click="$ctrl.next()"
ng-disabled="!$ctrl.selectedItem">Next</button>
<button type="button" class="btn btn-default" ng-click="$ctrl.next()" ng-disabled="!$ctrl.selectedProfile">Next</button>
</div>
</div>
@ -52,13 +57,28 @@ var Entaxy;
<div class="modal-body-header">
<h2>{{$ctrl.secondStepTitle}}</h2>
</div>
<div class="modal-body">
<entaxy-modal-list-with-description items="$ctrl.factories" selected-item="$ctrl.selectedFactory"
change-selection="$ctrl.changeFactorySelection"></entaxy-modal-list-with-description>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-if="$ctrl.profiles" ng-click="$ctrl.back()">Back</button>
<button type="button" class="btn btn-default" ng-click="$ctrl.next()" ng-disabled="!$ctrl.selectedFactory">Next</button>
</div>
</div>
<div ng-if="$ctrl.step3">
<div class="modal-body-header">
<h2>{{$ctrl.thirdStepTitle}}</h2>
</div>
<div class="modal-body">
<entaxy-modal-group-fields groups="$ctrl.groups" fields="$ctrl.formFields"
use-form-dirty="true" is-form-dirty="$ctrl.isFormDirty"
errors="$ctrl.errors" mode="$ctrl.mode"></entaxy-modal-group-fields>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-if="$ctrl.hasSteps" ng-click="$ctrl.back()">Back</button>
<button type="submit" class="btn btn-primary" ng-click="$ctrl.save($ctrl.formFields)">{{$ctrl.submitBtnTitle}}</button>
<button type="button" class="btn btn-default" ng-if="$ctrl.factories.length > 1 || $ctrl.profiles" ng-click="$ctrl.back()">Back</button>
<button type="submit" class="btn btn-primary" ng-click="$ctrl.save()">{{$ctrl.submitBtnTitle}}</button>
</div>
<div>
</div>
@ -67,7 +87,7 @@ var Entaxy;
})
.name;
function entaxyModalController(operationsService, entaxyService) {
function entaxyModalController($scope, operationsService, entaxyService) {
'ngInject';
var ctrl = this;
@ -90,36 +110,62 @@ var Entaxy;
let itemName = ctrl.resolve.itemName;
ctrl.firstStepTitle = ctrl.resolve.firstStepTitle ? ctrl.resolve.firstStepTitle : 'Choose factory';
ctrl.firstStepTitle = 'Choose profile to attach connector to';
ctrl.secondStepTitle = itemName ? ctrl.mode + ' properties for ' + itemName
: ctrl.resolve.secondStepTitle ? ctrl.resolve.secondStepTitle : 'Fill in fields';
ctrl.secondStepTitle = ctrl.resolve.secondStepTitle ? ctrl.resolve.secondStepTitle : 'Choose factory';
ctrl.thirdStepTitle = itemName ? ctrl.mode + ' properties for ' + itemName
: ctrl.resolve.thirdStepTitle ? ctrl.resolve.thirdStepTitle : 'Fill in fields';
if (ctrl.mode !== Entaxy.MODAL_MODES.ADD) {
let properties = Object.entries(ctrl.resolve.info.properties);
ctrl.properties = properties.map(property => { return { name: property[0], value: property[1] }; });
}
ctrl.profiles = ctrl.resolve.profiles;
ctrl.factories = ctrl.resolve.factories ? ctrl.resolve.factories : null;
if (ctrl.factories && ctrl.factories.length !== 0) {
if (!ctrl.factories || ctrl.factories.length === 0) {
ctrl.cancel('Factories are not found');
}
ctrl.factories.sort(Entaxy.compareBy('displayName'));
if (ctrl.profiles) {
ctrl.step1 = true;
ctrl.step2 = false;
ctrl.step3 = false
} else {
if (ctrl.factories.length > 1) {
ctrl.factories.sort(Entaxy.compareBy('displayName'));
ctrl.step1 = true;
ctrl.step2 = false;
ctrl.hasSteps = true;
ctrl.step1 = false;
ctrl.step2 = true;
ctrl.step3 = false;
} else if (ctrl.factories.length === 1) {
ctrl.hasSteps = false;
ctrl.next();
}
} else {
ctrl.cancel('Factories are not found');
}
}
ctrl.next = function() {
if (!ctrl.formFields || ctrl.selectedItem.name !== ctrl.formFields[0].value) {
if (ctrl.step1 === true) {
if (ctrl.factories.length > 1) {
ctrl.step1 = false;
ctrl.step2 = true;
} else if (ctrl.factories.length === 1) {
defineFormFields();
}
} else {
defineFormFields();
}
}
function defineFormFields() {
let container = ctrl.formFields ? ctrl.formFields.find(field => field.name === '__entaxyContainerId') : undefined;
if (!ctrl.formFields || ctrl.selectedFactory.name !== ctrl.formFields[0].value
|| (ctrl.profiles && container.value !== ctrl.selectedProfile.name)) {
ctrl.formFields = [];
@ -128,13 +174,13 @@ var Entaxy;
name: 'factoryId',
type: 'java.lang.String',
helpText: null,
value: ctrl.hasSteps ? ctrl.selectedItem.name : ctrl.factories[0].name,
value: ctrl.factories.length > 1 ? ctrl.selectedFactory.name : ctrl.factories[0].name,
readOnly: true,
required: ctrl.mode === Entaxy.MODAL_MODES.VIEW ? false : true,
group: 'general'
});
let mbeanName = ctrl.hasSteps ? ctrl.selectedItem.mbeanName : ctrl.factories[0].mbeanName;
let mbeanName = ctrl.factories.length > 1 ? ctrl.selectedFactory.mbeanName : ctrl.factories[0].mbeanName;
operationsService.executeOperation(mbeanName, { name: 'getFields' }, [ 'init' ])
.then((response) => {
@ -148,60 +194,111 @@ var Entaxy;
if (ctrl.mode !== Entaxy.MODAL_MODES.ADD) {
objectId = ctrl.resolve.info['objectId'];
}
let formField = entaxyService.makeFormField(field, objectId, ctrl.properties, ctrl.mode);
ctrl.formFields.push(formField);
groups.add(formField.group);
let profileName = ctrl.selectedProfile ? ctrl.selectedProfile.name : undefined;
let formField = entaxyService.makeFormField(field, objectId, ctrl.properties, ctrl.mode, profileName);
if (formField) {
ctrl.formFields.push(formField);
groups.add(formField.group);
}
});
ctrl.formFields.forEach(formField => formField.type = Entaxy.convertToHtmlInputType(formField.type));
processDependencies();
ctrl.groups = Array.from(groups).map((group) => { return { name: group, displayName: group }; });
ctrl.step1 = false;
ctrl.step2 = true;
ctrl.step2 = false;
ctrl.step3 = true;
});
} else {
ctrl.step1 = false;
ctrl.step2 = true;
ctrl.step2 = false;
ctrl.step3 = true;
}
}
function processDependencies() {
let dependentFormFields = entaxyService.getDependentFormFields(ctrl.formFields);
ctrl.definingFormFields = entaxyService.getDefiningFormFields(dependentFormFields, ctrl.formFields);
for (let i = 0; i < ctrl.definingFormFields.length; i++) {
if (ctrl.definingFormFields[i].value) {
let dependentFormFieldsWithListType = dependentFormFields
.filter(field => (field.typeInfo && field.typeInfo.type === 'list'));
entaxyService.processDependencies(dependentFormFieldsWithListType,
ctrl.definingFormFields,
ctrl.definingFormFields[i].name,
ctrl.definingFormFields[i].value,
undefined);
}
$scope.$watch('$ctrl.definingFormFields[' + i + '].value', function(newValue, oldValue) {
if (newValue !== oldValue) {
entaxyService.processDependencies(dependentFormFields,
ctrl.definingFormFields,
ctrl.definingFormFields[i].name,
newValue,
oldValue);
}
});
}
}
ctrl.back = function() {
ctrl.step1 = true;
ctrl.step2 = false;
if (ctrl.step2 === true) {
ctrl.step1 = true;
ctrl.step2 = false;
} else if (ctrl.step3 === true) {
ctrl.errors = undefined;
ctrl.step2 = true;
ctrl.step3 = false;
}
}
ctrl.cancel = function(reason) {
ctrl.modalInstance.dismiss(reason);
}
ctrl.changeSelection = function(item, isDblClicked) {
ctrl.selectedItem = item;
ctrl.changeProfileSelection = function(item, isDblClicked) {
ctrl.selectedProfile = item;
if (isDblClicked) {
ctrl.next();
}
}
ctrl.save = function(fields) {
ctrl.changeFactorySelection = function(item, isDblClicked) {
ctrl.selectedFactory = item;
if (isDblClicked) {
ctrl.next();
}
}
ctrl.save = function() {
if (ctrl.mode === Entaxy.MODAL_MODES.VIEW) {
ctrl.cancel();
}
let selectedFactory = ctrl.selectedItem ? ctrl.selectedItem : ctrl.factories[0];
let isConfirmationNeeded = ctrl.mode === Entaxy.MODAL_MODES.EDIT && !ctrl.isFormDirty;
entaxyService.requestConfirmationForSavingIfNeededAndProceed(isConfirmationNeeded, save);
}
entaxyService.validateFields(fields, selectedFactory, ctrl.itemType)
function save () {
let selectedFactory = ctrl.selectedFactory ? ctrl.selectedFactory : ctrl.factories[0];
let profileMBeanName = ctrl.selectedProfile ? ctrl.selectedProfile.mbeanName : undefined;
entaxyService.validateFields(ctrl.formFields, selectedFactory, ctrl.itemType, profileMBeanName)
.then(errors => {
ctrl.errors = errors;
if (Object.keys(ctrl.errors).length === 0) {
let args = entaxyService.getArguments(fields, ctrl.factories);
let args = entaxyService.getArguments(ctrl.formFields, ctrl.factories);
ctrl.modalInstance.close(args);
}
});
}
}
entaxyModalController.$inject = ['operationsService', 'entaxyService'];
entaxyModalController.$inject = ['$scope', 'operationsService', 'entaxyService'];
})(Entaxy || (Entaxy = {}));

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
@ -25,7 +31,9 @@ var Entaxy;
groups: '<',
fields: '<',
errors: '<',
mode: '<'
mode: '<',
useFormDirty: '<',
isFormDirty: '='
},
template:
`
@ -35,7 +43,7 @@ var Entaxy;
selected="$ctrl.selectedGroup" change-selection="$ctrl.change" filter="$ctrl.matchesFilter"></entaxy-modal-list>
</div>
<div class="modal-group-fields-form-container">
<form name="connectorForm" class="form-horizontal">
<form name="entaxyObjectForm" class="form-horizontal">
<div class="form-group" ng-class="{'has-error': $ctrl.errors[formField.name]}"
ng-repeat="formField in $ctrl.viewedFormFields" ng-if="!formField.isBackRef && !formField.isHidden">
<div class="col-sm-4 label-col">
@ -48,13 +56,19 @@ var Entaxy;
<div class="col-sm-7">
<input type="{{formField.type}}" id="{{formField.name}}" placeholder="{{formField.placeholder}}" ng-class="{'form-control': formField.type !== 'checkbox'}"
ng-model="formField.value" ng-readonly="formField.readOnly" ng-disabled="formField.type === 'checkbox' && formField.readOnly"
ng-if="!formField.type.startsWith('entaxy.runtime.') && formField.type !== 'xml:route' && !formField.typeInfo">
ng-if="!formField.type.startsWith('entaxy.runtime.') && formField.type !== 'xml:route' && (!formField.typeInfo || (formField.typeInfo && formField.typeInfo.type === 'String'))">
<entaxy-url-input id="{{formField.name}}" model="formField.value" config="formField.typeInfo"
ng-if="formField.type === 'url' && formField.typeInfo" form-controller="entaxyObjectForm"></entaxy-url-input>
<entaxy-select type="formField.type" id="{{formField.name}}" filter="formField.filter" model="formField.value"
update-parent-fn="$ctrl.updateFieldsAfterSelectionChange" options="formField.options" ng-readonly="formField.readOnly"
ng-if="formField.type.startsWith('entaxy.runtime.')"></entaxy-select>
update-parent="formField.typeInfo ? formField.typeInfo.updateParentFields : false"
creation-enabled="formField.typeInfo ? formField.typeInfo.enablePrivateObjectCreation : false"
ng-if="formField.type.startsWith('entaxy.runtime.')" form-controller="entaxyObjectForm"></entaxy-select>
<entaxy-select-from-enum id="{{formField.name}}" values="formField.typeInfo.values" model="formField.value"
ng-readonly="formField.readOnly" ng-if="formField.typeInfo && formField.typeInfo.type === 'enum'"></entaxy-select-from-enum>
<entaxy-xml id="{{formField.name}}" ng-model="formField.value" ng-if="formField.type === 'xml:route'" mode="$ctrl.localMode"></entaxy-xml>
readonly="formField.readOnly" is-empty-included="formField.typeInfo.isEmptyIncluded"
ng-if="formField.typeInfo && (formField.typeInfo.type === 'enum' || formField.typeInfo.type === 'list')"></entaxy-select-from-enum>
<entaxy-xml id="{{formField.name}}" ng-model="formField.value" ng-if="formField.type === 'xml:route'"
mode="$ctrl.localMode" disabled="formField.readOnly && !formField.value" form-controller="entaxyObjectForm"></entaxy-xml>
<span class="help-block" ng-show="$ctrl.errors[formField.name]">{{$ctrl.errors[formField.name]}}</span>
</div>
</div>
@ -66,7 +80,7 @@ var Entaxy;
})
.name;
function entaxyModalGroupFieldsController(operationsService) {
function entaxyModalGroupFieldsController(operationsService, $scope) {
'ngInject';
var ctrl = this;
@ -75,6 +89,22 @@ var Entaxy;
ctrl.localMode = ctrl.mode === Entaxy.MODAL_MODES.ADD ? Entaxy.MODAL_MODES.EDIT : ctrl.mode;
ctrl.selectedGroup = ctrl.groups[0];
if (ctrl.useFormDirty) {
$scope.$watch('entaxyObjectForm.$dirty', function (newValue) {
ctrl.isFormDirty = newValue;
});
$scope.$watch('$ctrl.isFormDirty', function (newValue) {
if ($scope.entaxyObjectForm.$dirty != newValue) {
if (newValue) {
$scope.entaxyObjectForm.$setDirty();
} else {
$scope.entaxyObjectForm.$setPristine();
}
}
});
}
}
ctrl.$onChanges = function(changes) {
@ -93,7 +123,7 @@ var Entaxy;
}
ctrl.matchesFilter = function(group, filter) {
var match = false;
let match = false;
_.forEach(ctrl.fields.filter((formField) => formField.group === group.name), (field) => {
if (field.tag && field.tag.length !== 0) {
@ -151,6 +181,6 @@ var Entaxy;
}
}
}
entaxyModalGroupFieldsController.$inject = ['operationsService'];
entaxyModalGroupFieldsController.$inject = ['operationsService', '$scope'];
})(Entaxy || (Entaxy = {}));

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
@ -68,11 +74,22 @@ var Entaxy;
} else if (shouldShowProfilesTab()) {
tabs.unshift(new Nav.HawtioTab(TAB_CONFIG.profiles.title, TAB_CONFIG.profiles.route));
// todo smth like goto/$location.search ?
} else if (shouldShowConnectorsInProfileTab()) {
tabs.unshift(new Nav.HawtioTab(TAB_CONFIG.connectorsInProfile.title, TAB_CONFIG.connectorsInProfile.route));
tabs.unshift(new Nav.HawtioTab(TAB_CONFIG.profileProperties.title, TAB_CONFIG.profileProperties.route));
tabs.unshift(new Nav.HawtioTab(TAB_CONFIG.profileDiagram.title, TAB_CONFIG.profileDiagram.route));
} else if (shouldShowConnectorPropertiesTab()) {
tabs.unshift(new Nav.HawtioTab(TAB_CONFIG.connectorProperties.title, TAB_CONFIG.connectorProperties.route));
} else if (shouldShowConnectorsTab()) {
tabs.unshift(new Nav.HawtioTab(TAB_CONFIG.connectors.title, TAB_CONFIG.connectors.route));
tabs.unshift(new Nav.HawtioTab(TAB_CONFIG.properties.title, TAB_CONFIG.properties.route));
tabs.unshift(new Nav.HawtioTab(TAB_CONFIG.connectors.title, TAB_CONFIG.connectors.route));
} else if (shouldShowSourceTab()) {
tabs.unshift(new Nav.HawtioTab(TAB_CONFIG.source.title, TAB_CONFIG.source.route));
} else if (shouldShowResourcesTab()) {
tabs.unshift(new Nav.HawtioTab(TAB_CONFIG.resources.title, TAB_CONFIG.resources.route));
} else if (shouldShowServicesTab()) {
tabs.unshift(new Nav.HawtioTab(TAB_CONFIG.services.title, TAB_CONFIG.services.route));
} else if (shouldShowServicePropertiesTab()) {
tabs.unshift(new Nav.HawtioTab(TAB_CONFIG.serviceProperties.title, TAB_CONFIG.serviceProperties.route));
} else {
let mbeanName = workspace.getSelectedMBeanName();
let parsedMbean = Core.parseMBean(mbeanName);
@ -104,7 +121,7 @@ var Entaxy;
workspace.getSelectedMBeanName().endsWith('category=profiles');
}
function shouldShowConnectorsTab() {
function shouldShowConnectorsInProfileTab() {
let mbeanName = workspace.getSelectedMBeanName();
let parsedMbean = Core.parseMBean(mbeanName);
return workspace.hasDomainAndProperties(entaxyJmxDomain, {'category': 'profiles'}) &&
@ -112,6 +129,19 @@ var Entaxy;
!parsedMbean.attributes.section;
}
function shouldShowConnectorPropertiesTab() {
let mbeanName = workspace.getSelectedMBeanName();
let parsedMbean = Core.parseMBean(mbeanName);
return workspace.hasDomainAndProperties(entaxyJmxDomain, {'category': 'profiles'}) &&
workspace.hasDomainAndProperties(entaxyJmxDomain, {'section': 'connectors'}) &&
parsedMbean.attributes.connector;
}
function shouldShowConnectorsTab() {
return workspace.hasDomainAndProperties(entaxyJmxDomain, {'category': 'connectors'}) &&
workspace.getSelectedMBeanName().endsWith('category=connectors');
}
function shouldShowSourceTab() {
let mbeanName = workspace.getSelectedMBeanName();
let parsedMbean = Core.parseMBean(mbeanName);
@ -119,6 +149,28 @@ var Entaxy;
parsedMbean.attributes.profile &&
parsedMbean.attributes.route;
}
function shouldShowResourcesTab() {
let mbeanName = workspace.getSelectedMBeanName();
let parsedMbean = Core.parseMBean(mbeanName);
return workspace.hasDomainAndProperties(entaxyJmxDomain, {'category': 'resource'}) &&
parsedMbean.attributes.provider;
}
function shouldShowServicesTab() {
let mbeanName = workspace.getSelectedMBeanName();
let parsedMbean = Core.parseMBean(mbeanName);
return workspace.hasDomainAndProperties(entaxyJmxDomain, {'category': 'services'}) &&
!parsedMbean.attributes.service;
}
function shouldShowServicePropertiesTab() {
let mbeanName = workspace.getSelectedMBeanName();
let parsedMbean = Core.parseMBean(mbeanName);
return workspace.hasDomainAndProperties(entaxyJmxDomain, {'category': 'services'}) &&
parsedMbean.attributes.service;
}
// global event for entaxy extras
$rootScope.$emit('entaxyNavigationInited', $scope);
}
@ -132,9 +184,15 @@ var Entaxy;
when('/entaxy/test', { template: '<entaxy-test></entaxy-test>' }).
when('/entaxy/connections', { template: '<entaxy-connections page-title="Connections"></entaxy-connections>' }).
when('/entaxy/profiles', { template: '<entaxy-profiles page-title="Profiles"></entaxy-profiles>' }).
when('/entaxy/properties', { template: '<entaxy-properties></entaxy-properties>' }).
when('/entaxy/connectors', { template: '<entaxy-connectors page-title="Connectors"></entaxy-connectors>' }).
when('/entaxy/route/source', { template: '<entaxy-source></entaxy-source>' });
when('/entaxy/profile/diagram', { template: '<entaxy-profile-diagram></entaxy-profile-diagram>' }).
when('/entaxy/profile/properties', { template: '<entaxy-properties item-name="Profile"></entaxy-properties>' }).
when('/entaxy/profile/connectors', { template: '<entaxy-connectors page-title="Connectors"></entaxy-connectors>' }).
when('/entaxy/connector/properties', { template: '<entaxy-properties item-name="Connector" use-grand-parent-mbean="true"></entaxy-properties>' }).
when('/entaxy/connectors', { template: '<entaxy-all-connectors-table></entaxy-all-connectors-table>' }).
when('/entaxy/route/source', { template: '<entaxy-source></entaxy-source>' }).
when('/entaxy/resources', { template: '<entaxy-resources></entaxy-resources>' }).
when('/entaxy/services', { template: '<entaxy-services page-title="Services"></entaxy-services>' }).
when('/entaxy/service/properties', { template: '<entaxy-properties item-name="Service"></entaxy-properties>' });
}
configureRoutes.$inject = ['$routeProvider'];
@ -165,9 +223,21 @@ var TAB_CONFIG = {
title: 'Profiles',
route: '/entaxy/profiles'
},
properties: {
profileDiagram: {
title: 'Profile Diagram',
route: '/entaxy/profile/diagram'
},
profileProperties: {
title: 'Properties',
route: 'entaxy/properties'
route: '/entaxy/profile/properties'
},
connectorsInProfile: {
title: 'Connectors',
route: '/entaxy/profile/connectors'
},
connectorProperties: {
title: 'Properties',
route: '/entaxy/connector/properties'
},
connectors: {
title: 'Connectors',
@ -176,5 +246,17 @@ var TAB_CONFIG = {
source: {
title: 'Source',
route: '/entaxy/route/source'
},
resources: {
title: 'Resources',
route: '/entaxy/resources'
},
services: {
title: 'Services',
route: '/entaxy/services'
},
serviceProperties: {
title: 'Properties',
route: '/entaxy/service/properties'
}
};

View File

@ -0,0 +1,395 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module
.component('entaxyProfileDiagram', {
template:
`
<div id="leader-lines-container" class="profile-diagram-container">
<div class="blocks-container">
<div id="source-block" class="source-block" ng-if="$ctrl.inConnectors && $ctrl.inConnectors.length > 0">
<span>source</span>
</div>
<div id="target-block" class="target-block" ng-if="$ctrl.outConnectors && $ctrl.outConnectors.length > 0">
<span>target</span>
</div>
</div>
<div class="profile-block" ng-click="$ctrl.goToProfileProperties()">
<span class="profile-title">{{$ctrl.profileTitle}}</span>
<entaxy-connectors-with-flow direction="in" connectors="$ctrl.inConnectors" profile-name="$ctrl.profileName"
edit-customization-point-fn="$ctrl.editCustomizationPoint" ng-if="$ctrl.inConnectors && $ctrl.inConnectors.length > 0">
</entaxy-connectors-with-flow>
<entaxy-connectors-with-flow direction="out" connectors="$ctrl.outConnectors" profile-name="$ctrl.profileName"
edit-customization-point-fn="$ctrl.editCustomizationPoint" ng-if="$ctrl.outConnectors && $ctrl.outConnectors.length > 0">
</entaxy-connectors-with-flow>
</div>
<div class="blocks-container">
<div id="integrations-in-block" class="integrations-block" ng-if="$ctrl.inConnectors && $ctrl.inConnectors.length > 0">
<span>integrations</span>
</div>
<div id="default-route-block" class="default-route-block" ng-click="$ctrl.editDefaultRouteProperties()"
ng-if="$ctrl.inConnectors && $ctrl.inConnectors.length > 0">
<span>default-route</span>
</div>
<div id="integrations-out-block" class="integrations-block" ng-if="$ctrl.outConnectors && $ctrl.outConnectors.length > 0">
<span>integrations</span>
</div>
</div>
</div>
`,
controller: entaxyProfileDiagramController
})
.name;
function entaxyProfileDiagramController($scope, workspace, jolokia, $location, operationsService, entaxyService, $uibModal) {
'ngInject';
var ctrl = this;
let selectedMBean = workspace.getSelectedMBean();
ctrl.$onInit = function () {
ctrl.profileName = jolokia.getAttribute(selectedMBean.objectName, 'Name')
ctrl.profileTitle = 'Profile: ' + ctrl.profileName;
populateConnectors();
}
function populateConnectors() {
let inConnectors = [];
let outConnectors = [];
if (selectedMBean && selectedMBean.isFolder) {
let connectorMbeans = entaxyService.getAllChildMBeansByRuntimeType(selectedMBean, 'entaxy.runtime.connector');
connectorMbeans.forEach((mbean) => {
let direction = jolokia.getAttribute(mbean.objectName, 'Direction');
let connector = {
name: jolokia.getAttribute(mbean.objectName, 'Name'),
mbeanName: mbean.objectName
};
if (direction === 'in') {
inConnectors.push(connector);
} else if (direction === 'out') {
outConnectors.push(connector);
}
});
ctrl.inConnectors = inConnectors.sort(Entaxy.compareBy('name'));
ctrl.outConnectors = outConnectors.sort(Entaxy.compareBy('name'));
}
}
// sets top margin for source, target, default-route and integration blocks
setTimeout(function () {
let sourceBlockMarginPlusHeight = 0;
let defaultRouteBlockMarginPlusHeight = 0;
if (ctrl.inConnectors && ctrl.inConnectors.length > 0) {
let padding = 10;
let integrationsInBlock = document.getElementById("integrations-in-block");
let inFlowBlock = document.getElementById("in-flow-block");
let sourceBlock = document.getElementById("source-block");
let defaultRouteBlock = document.getElementById("default-route-block");
let integrationsInBlockHeight = integrationsInBlock.offsetHeight;
let sourceBlockMarginTop = getMarginFromTopElement(inFlowBlock, sourceBlock);
let integrationsInBlockMarginTop = getMarginFromTopElement(inFlowBlock, defaultRouteBlock) -
inFlowBlock.offsetHeight + padding;
let defaultRouteBlockMarginTop = inFlowBlock.offsetHeight - integrationsInBlockHeight - padding;
sourceBlock.style.marginTop = sourceBlockMarginTop + 'px';
integrationsInBlock.style.marginTop = integrationsInBlockMarginTop + 'px';
defaultRouteBlock.style.marginTop = defaultRouteBlockMarginTop + 'px';
sourceBlockMarginPlusHeight = sourceBlockMarginTop + sourceBlock.offsetHeight;
defaultRouteBlockMarginPlusHeight = integrationsInBlockMarginTop + integrationsInBlockHeight +
defaultRouteBlockMarginTop + defaultRouteBlock.offsetHeight;
}
if (ctrl.outConnectors && ctrl.outConnectors.length > 0) {
let outFlowBlock = document.getElementById("out-flow-block");
let targetBlock = document.getElementById("target-block");
let integrationsBlock = document.getElementById("integrations-out-block");
let targetBlockMarginTop = getMarginFromTopElement(outFlowBlock, targetBlock) - sourceBlockMarginPlusHeight;
let integrationsBlockMarginTop = getMarginFromTopElement(outFlowBlock, integrationsBlock) - defaultRouteBlockMarginPlusHeight;
targetBlock.style.marginTop = targetBlockMarginTop + 'px';
integrationsBlock.style.marginTop = integrationsBlockMarginTop + 'px';
}
}, 10);
function getMarginFromTopElement(sourceBlock, targetBlock) {
let sourceBlockOffsetTop = sourceBlock.offsetTop;
let sourceBlockOffsetHeight = sourceBlock.offsetHeight;
let targetBlockOffsetHeight = targetBlock.offsetHeight;
let difference = Math.abs(targetBlockOffsetHeight - sourceBlockOffsetHeight);
let marginTop = sourceBlockOffsetTop + difference / 2;
return marginTop;
}
let lines = [];
// draws lines for in-directed connector block
$scope.$watchCollection('$ctrl.inConnectors', function (newValue, oldValue) {
if (newValue && newValue.length > 0) {
setTimeout(function () {
if (ctrl.inConnectors) {
let pathType = ctrl.inConnectors.length === 1 ? 'straight' : 'grid';
ctrl.inConnectors.forEach((connector) => {
lines.push(new LeaderLine(
LeaderLine.pointAnchor(document.getElementById('source-block'), {x: '100%', y: 12.5}),
document.getElementById(connector.name + '_pre-route'),
{color: 'green', size: 2, path: pathType, startSocketGravity: [15, 0]}
));
lines.push(new LeaderLine(
document.getElementById(connector.name + '_pre-route'),
document.getElementById('in-flow_pre-route'),
{color: 'green', size: 2, path: 'grid', startSocketGravity: [10, 0]}
));
lines.push(new LeaderLine(
document.getElementById(connector.name + '_response'),
LeaderLine.pointAnchor(document.getElementById('source-block'), {x: '100%', y: 44.5}),
{color: 'blue', size: 2, path: pathType, endSocketGravity: [35, 0]}
));
lines.push(new LeaderLine(
document.getElementById('in-flow_response'),
document.getElementById(connector.name + '_response'),
{color: 'blue', size: 2, path: 'grid', startSocketGravity: [-10, 0]}
));
});
lines.push(new LeaderLine(
document.getElementById('in-flow_pre-route'),
LeaderLine.pointAnchor(document.getElementById('default-route-block'), {x: 0, y: 12.5}),
{color: 'green', size: 2, path: 'straight'}
));
lines.push(new LeaderLine(
LeaderLine.pointAnchor(document.getElementById('default-route-block'), {x: 0, y: 44.5}),
document.getElementById('in-flow_response'),
{color: 'blue', size: 2, path: 'straight'}
));
lines.push(new LeaderLine(
LeaderLine.pointAnchor(document.getElementById('default-route-block'), {x: 32.5, y: 0}),
LeaderLine.pointAnchor(document.getElementById('integrations-in-block'), {x: 32.5, y: '100%'}),
{color: 'green', size: 2, path: 'straight'}
));
lines.push(new LeaderLine(
LeaderLine.pointAnchor(document.getElementById('integrations-in-block'), {x: 64.5, y: '100%'}),
LeaderLine.pointAnchor(document.getElementById('default-route-block'), {x: 64.5, y: 0}),
{color: 'blue', size: 2, path: 'straight'}
));
}
}, 50);
}
});
// draws lines for out-directed connector block
$scope.$watchCollection('$ctrl.outConnectors', function (newValue, oldValue) {
if (newValue && newValue.length > 0) {
setTimeout(function () {
if (ctrl.outConnectors) {
let pathType = ctrl.outConnectors.length === 1 ? 'straight' : 'grid';
ctrl.outConnectors.forEach((connector) => {
lines.push(new LeaderLine(
document.getElementById(connector.name + '_pre-output'),
LeaderLine.pointAnchor(document.getElementById('target-block'), {x: '100%', y: 12.5}),
{color: 'green', size: 2, path: pathType, endSocketGravity: [35, 0]}
));
lines.push(new LeaderLine(
document.getElementById('out-flow_pre-route'),
document.getElementById(connector.name + '_pre-output'),
{color: 'green', size: 2, path: 'grid', startSocketGravity: [-10, 0]}
));
lines.push(new LeaderLine(
LeaderLine.pointAnchor(document.getElementById('target-block'), {x: '100%', y: 44.5}),
document.getElementById(connector.name + '_postprocess'),
{color: 'blue', size: 2, path: pathType, startSocketGravity: [15, 0]}
));
lines.push(new LeaderLine(
document.getElementById(connector.name + '_postprocess'),
document.getElementById('out-flow_postprocess'),
{color: 'blue', size: 2, path: 'grid', startSocketGravity: [10, 0]}
));
})
lines.push(new LeaderLine(
LeaderLine.pointAnchor(document.getElementById('integrations-out-block'), {x: 0, y: 12.5}),
document.getElementById('out-flow_pre-route'),
{color: 'green', size: 2, path: 'straight'}
));
lines.push(new LeaderLine(
document.getElementById('out-flow_postprocess'),
LeaderLine.pointAnchor(document.getElementById('integrations-out-block'), {x: 0, y: 44.5}),
{color: 'blue', size: 2, path: 'straight'}
));
}
}, 50);
}
});
// reposition of lines while container size is changed without changing window size
document.querySelector('#leader-lines-container').handleResize = entry => {
lines.forEach(line => line.position());
}
let resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
if (entry.target.handleResize) {
entry.target.handleResize(entry);
}
}
});
resizeObserver.observe(document.querySelector('#leader-lines-container'));
// reposition of lines on scroll event
setTimeout(function () {
let contentElement = document.getElementsByClassName("contents")[0];
contentElement.onscroll = (event) => {
lines.forEach(line => line.position());
};
}, 10);
// reposition of lines while jmx-header is loaded after being empty
$scope.$on('jmxTreeClicked', (event, selected) => {
setTimeout(function () {
if (selected.objectName === selectedMBean.objectName) {
lines.forEach(line => line.position());
}
}, 10);
});
$scope.$on('$destroy', function () {
lines.forEach(line => line.remove());
resizeObserver.disconnect();
});
ctrl.goToProfileProperties = function () {
let currentLocationPath = $location.path();
$location.path(currentLocationPath.replace('diagram', 'properties'));
}
ctrl.editDefaultRouteProperties = function () {
let defaultRouteMbean = selectedMBean.findDescendant(child => {
if (child.objectName) {
return child.objectName.endsWith('route=default');
}
});
ctrl.editCustomizationPoint(defaultRouteMbean.objectName, 'doGetRouteConfig', [], 'routeContent');
}
ctrl.editCustomizationPoint = function (mbeanName, operationName, parameters, propertyName) {
operationsService
.executeOperation(mbeanName, {name: operationName}, parameters)
.then(result => {
let args = getArgumentsFromConfig(JSON.parse(result));
let property = args.fields.find(property => property.name === propertyName);
openXmlEditor(property, args);
}).catch(error => {
Core.notification('danger', error, 5000);
Entaxy.log.error(error);
});
}
function getArgumentsFromConfig(configInfo) {
let properties = Object.entries(configInfo.properties);
properties = properties.map(property => {
return {name: property[0], value: property[1]};
});
properties = properties.filter(property => property.name !== '__objectId');
properties = properties.filter(property => property.name !== '##config');
properties.unshift({name: 'objectId', value: configInfo.objectId});
let factoryFolder = entaxyService.getDomainFolder()
.findDescendant(child => child.title === configInfo.factoryId);
let factory = {name: factoryFolder.title, mbeanName: factoryFolder.objectName};
return {fields: properties, factoryId: factory};
}
function openXmlEditor(property, args) {
$uibModal.open({
component: 'entaxyXmlModal',
resolve: {
xml: () => atob(property.value),
mode: () => Entaxy.MODAL_MODES.EDIT
},
size: 'xl',
backdrop: 'static',
windowTopClass: 'modal-top-margin-override'
})
.result.then(xml => {
if (xml && xml.trim().length > 0) { // fixme
property.value = btoa(xml);
entaxyService.saveItem(args);
} else {
Core.notification('danger', 'Value cannot be empty', 5000);
}
});
}
}
entaxyProfileDiagramController.$inject = ['$scope', 'workspace', 'jolokia', '$location', 'operationsService', 'entaxyService', '$uibModal'];
})(Entaxy || (Entaxy = {}));

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
@ -30,7 +36,7 @@ var Entaxy;
{{$ctrl.pageTitle}}
</h2>
<entaxy-table item-name="Profile" folder-name="Профили"
<entaxy-table runtime-type="entaxy.runtime.profile"
status-name="BundleState" object-name="systemName"></entaxy-table>
`

View File

@ -4,63 +4,83 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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.
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module
.component('entaxyProperties', {
bindings: {
itemName: '@',
useGrandParentMbean: '<'
},
template:
`
<h2>
{{$ctrl.title}}
</h2>
<div class="properties-container">
<entaxy-modal-group-fields groups="$ctrl.groups" fields="$ctrl.formFields"
errors="$ctrl.errors" mode="$ctrl.mode" ng-if="$ctrl.groups && $ctrl.formFields"></entaxy-modal-group-fields>
</div>
<button type="submit" class="btn btn-primary" ng-click="$ctrl.save($ctrl.formFields)">{{$ctrl.submitBtnTitle}}</button>
<div class="properties-header-container">
<h2>
{{$ctrl.title}}
</h2>
<button type="submit" class="btn btn-primary" ng-click="$ctrl.save()">
{{$ctrl.submitBtnTitle}}
</button>
</div>
<div class="properties-container">
<entaxy-modal-group-fields groups="$ctrl.groups" fields="$ctrl.formFields"
use-form-dirty="true" is-form-dirty="$ctrl.isFormDirty" errors="$ctrl.errors"
mode="$ctrl.mode" ng-if="$ctrl.groups && $ctrl.formFields"></entaxy-modal-group-fields>
</div>
`,
controller: entaxyPropertiesController
})
.name;
function entaxyPropertiesController(workspace, operationsService, entaxyService) {
function entaxyPropertiesController($scope, workspace, operationsService, entaxyService, jolokia, $location) {
'ngInject';
var ctrl = this;
let ctrl = this;
ctrl.$onInit = function() {
ctrl.itemName = 'Profile';
ctrl.mode = Entaxy.MODAL_MODES.EDIT;
let selectedMbean = workspace.getSelectedMBean();
ctrl.title = 'Properties of ' + selectedMbean.title;
ctrl.submitBtnTitle = Entaxy.getButtonTitleByMode(ctrl.mode);
let itemName = jolokia.getAttribute(selectedMbean.objectName, 'Name');
let profilesMbean = workspace.tree.findDescendant(child => child.objectName ? child.objectName.endsWith('category=profiles') : false);
let mbeanName = profilesMbean.objectName;
let mbeanName = selectedMbean.parent.objectName;
if (ctrl.useGrandParentMbean === true) {
mbeanName = selectedMbean.parent.parent.objectName;
}
operationsService
.executeOperation(mbeanName, { name: 'get' + ctrl.itemName + 'Config' }, [ selectedMbean.title ])
.executeOperation(mbeanName, { name: 'get' + ctrl.itemName + 'Config' }, [ itemName ])
.then(result => {
ctrl.itemInfo = JSON.parse(result);
let properties = Object.entries(ctrl.itemInfo.properties);
ctrl.properties = properties.map(property => { return { name: property[0], value: property[1] }; });
let factory = workspace.tree.findDescendant(child => child.title === ctrl.itemInfo.factoryId);
let factory = entaxyService.getDomainFolder()
.findDescendant(child => child.title === ctrl.itemInfo.factoryId);
ctrl.factories = [{ name: factory.title, mbeanName: factory.objectName }];
makeFormFieldsAndGroups();
@ -96,20 +116,73 @@ var Entaxy;
_.forEach(JSON.parse(response), (field) => {
let formField = entaxyService.makeFormField(field, ctrl.itemInfo['objectId'], ctrl.properties, ctrl.mode);
ctrl.formFields.push(formField);
groups.add(formField.group);
if (formField) {
ctrl.formFields.push(formField);
groups.add(formField.group);
}
});
ctrl.formFields.forEach(formField => formField.type = Entaxy.convertToHtmlInputType(formField.type));
processDependencies();
ctrl.groups = Array.from(groups).map((group) => { return { name: group, displayName: group }; });
});
}
ctrl.save = function(fieldsOrigin) {
function processDependencies() {
let dependentFormFields = entaxyService.getDependentFormFields(ctrl.formFields);
ctrl.definingFormFields = entaxyService.getDefiningFormFields(dependentFormFields, ctrl.formFields);
let fields = JSON.parse(JSON.stringify(fieldsOrigin));
for (let i = 0; i < ctrl.definingFormFields.length; i++) {
if (ctrl.definingFormFields[i].value) {
let dependentFormFieldsWithListType = dependentFormFields
.filter(field => (field.typeInfo && field.typeInfo.type === 'list'));
entaxyService.processDependencies(dependentFormFieldsWithListType,
ctrl.definingFormFields,
ctrl.definingFormFields[i].name,
ctrl.definingFormFields[i].value,
undefined);
}
$scope.$watch('$ctrl.definingFormFields[' + i + '].value', function(newValue, oldValue) {
if (newValue !== oldValue) {
entaxyService.processDependencies(dependentFormFields,
ctrl.definingFormFields,
ctrl.definingFormFields[i].name,
newValue,
oldValue);
}
});
}
}
setTimeout( function () {
ctrl.activeTabIndex = entaxyService.getActiveTabIndex();
})
$scope.$on("$locationChangeStart", function(event) {
if (ctrl.isFormDirty && !confirm('You have unsaved changes. Do you want to leave the page anyway?')) {
event.preventDefault();
ctrl.isTreeOrTabSelectionUpdateNeeded = true;
}
});
$scope.$watch('$ctrl.isTreeOrTabSelectionUpdateNeeded', function (newValue) {
if (newValue) {
setTimeout(function () {
entaxyService.updateTabSelection(ctrl.activeTabIndex);
});
Jmx.updateTreeSelectionFromURL($location, $(entaxyTreeElementId));
ctrl.isTreeOrTabSelectionUpdateNeeded = false;
}
});
ctrl.save = function() {
entaxyService.requestConfirmationForSavingIfNeededAndProceed(!ctrl.isFormDirty, save);
}
function save() {
let fields = JSON.parse(JSON.stringify(ctrl.formFields));
entaxyService.validateFields(fields, ctrl.factories[0], ctrl.itemName)
.then(errors => {
@ -117,32 +190,12 @@ var Entaxy;
if (Object.keys(ctrl.errors).length === 0) {
let args = entaxyService.getArguments(fields, ctrl.factories);
update(args);
entaxyService.saveItem(args);
ctrl.isFormDirty = false;
}
});
}
function update(args) {
let objectId = args.fields.find((field) => field.name === 'objectId').value;
let fields = objectId ? args.fields.filter((field) => field.name !== 'objectId') : args.fields;
let mbeanName = args.factoryId.mbeanName;
let properties = fields.reduce((obj, cur) => ({ ...obj, [cur.name] : cur.value }), {});
let instructions = {"@LIFECYCLE":["general"]};
operationsService.executeOperation(mbeanName, { name: 'createObjectByInstructions' }, [ objectId, 'public', instructions, properties ] )
.then(result => {
let tableHtml = Entaxy.createTableFromResponse(result);
Entaxy.notification('success', tableHtml, 10000);
}).catch(error => {
Core.notification('danger', error, 5000);
Entaxy.log.error(error);
});
}
}
entaxyPropertiesController.$inject = ['workspace', 'operationsService', 'entaxyService'];
entaxyPropertiesController.$inject = ['$scope', 'workspace', 'operationsService', 'entaxyService', 'jolokia', '$location'];
})(Entaxy || (Entaxy = {}));

View File

@ -0,0 +1,170 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module.component('entaxyResourceViewerModal', {
bindings: {
modalInstance: '<',
resolve: '<'
},
template:
`
<div class="entaxy-modal-container">
<div class="modal-header">
<button type="button" class="close" aria-label="Close" ng-click="$ctrl.cancel()">
<span class="pficon pficon-close" aria-hidden="true"></span>
</button>
<h4 class="modal-title">{{$ctrl.modalTitle}}</h4>
</div>
<div class="modal-body-without-header" style="margin-top: 0;">
<div class="modal-resources-viewer-container">
<entaxy-crumbs root-crumb="$ctrl.protocol" crumbs="$ctrl.crumbs"></entaxy-crumbs>
<entaxy-file-panel items="$ctrl.items" selected-item="$ctrl.selectedItem" view="$ctrl.view"
change-selection-fn="$ctrl.changeSelection" open-fn="$ctrl.open"></entaxy-file-panel>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" ng-click="$ctrl.save()">Select</button>
</div>
</div>
`,
controller: entaxyResourceViewerModalController
})
.name;
function entaxyResourceViewerModalController($uibModal, $scope, workspace, operationsService, entaxyService) {
'ngInject';
let ctrl = this;
let entaxyJmxDomain = localStorage['entaxyJmxDomain'] || "ru.entaxy.esb";
ctrl.$onInit = function() {
ctrl.modalTitle = 'Select Resources';
ctrl.view = 'tiles';
ctrl.protocol = ctrl.resolve.config.resourceProvider;
let provider = entaxyService.getDomainFolder().findDescendant(child => {
let childObjectName = child.objectName;
if (childObjectName && childObjectName.startsWith(entaxyJmxDomain) && childObjectName.endsWith('provider=' + ctrl.protocol)) {
return child;
}
});
ctrl.providerMBeanName = provider.objectName;
ctrl.filter = ctrl.resolve.config.filter;
ctrl.enableFolderSelection = ctrl.resolve.config.target === 'folder' ? true : false;
let location = ctrl.resolve.location;
if (location && location.includes(':')) {
let path = location.split(':')[1];
let splitPath = path.split('/');
if (!ctrl.enableFolderSelection) {
splitPath.pop();
}
// todo else check if the last item in path is folder or not
ctrl.crumbs = splitPath;
} else {
ctrl.crumbs = [];
}
}
$scope.$watchCollection('$ctrl.crumbs', function(newValue, oldValue) {
ctrl.selectedItem = null;
updateItems();
})
ctrl.changeSelection = function (item) {
ctrl.selectedItem = item;
}
ctrl.open = function (item) {
if (item.isFolder === true) {
ctrl.crumbs.push(item.name);
} else {
ctrl.changeSelection(item);
ctrl.save();
}
}
function updateItems() {
let path = getPath();
operationsService
.executeOperation(ctrl.providerMBeanName, { name: 'getResourcesInfo' }, [ path ])
.then((result) => {
let items = JSON.parse(result);
if (Array.isArray(ctrl.filter) && ctrl.filter.length > 0) {
items = items.filter(item => {
let match = false;
if (item.isFolder) {
return true;
}
ctrl.filter.forEach(filter => {
if (filter.startsWith('*') && item.name.endsWith(filter.substring(1, filter.length))) {
match = true;
}
});
return match;
});
} else if (ctrl.filter && ctrl.filter.startsWith('*')) {
items = items.filter(item => item.isFolder || item.name.endsWith(ctrl.filter.substring(1, ctrl.filter.length)));
}
ctrl.items = items.sort(Entaxy.compareBy('name')).sort((a, b) => b.isFolder - a.isFolder);
})
.catch((error) => {
Entaxy.log.error(error);
Core.notification('danger', 'An error occurred while getting resources.', 5000);
})
}
function getPath() {
let path = '';
if (ctrl.crumbs && ctrl.crumbs.length > 0) {
path = ctrl.crumbs.join('/');
}
return path;
}
ctrl.cancel = function(reason) {
ctrl.modalInstance.dismiss(reason);
}
ctrl.save = function() {
if ((!ctrl.enableFolderSelection && !ctrl.selectedItem.isFolder) || ctrl.enableFolderSelection) {
let separator = getPath().length > 0 ? '/' : '';
let location = ctrl.protocol + ':' + getPath() + separator + ctrl.selectedItem.name;
ctrl.modalInstance.close(location);
}
}
}
entaxyResourceViewerModalController.$inject = ['$uibModal', '$scope', 'workspace', 'operationsService', 'entaxyService'];
})(Entaxy || (Entaxy = {}));

View File

@ -0,0 +1,235 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module
.component('entaxyResources', {
template:
`
<div class="resources-header-container">
<h2>
Resources
</h2>
<p class="text-muted">{{$ctrl.location}}</p>
<button type="button" class="btn-clipboard" data-toggle="tooltip" title="Copy location to clipboard" ng-click="$ctrl.copyLocationToClipboard()">
<span class="fa fa-copy"></span>
</button>
<button type="button" data-toggle="tooltip" title="Create folder" ng-click="$ctrl.createFolder()">
<span class="pficon pficon-add-circle-o"></span>
</button>
<button type="button" data-toggle="tooltip" title="Change to list" ng-click="$ctrl.changeView('list')" ng-if="$ctrl.view === 'tiles'">
<span class="fa fa-list"></span>
</button>
<button type="button" data-toggle="tooltip" title="Change to tiles" ng-click="$ctrl.changeView('tiles')" ng-if="$ctrl.view === 'list'">
<span class="fa fa-th"></span>
</button>
</div>
<entaxy-crumbs root-crumb="$ctrl.protocol" crumbs="$ctrl.crumbs"></entaxy-crumbs>
<div class="resources-file-drop-zone" entaxy-file-drop ng-model="$ctrl.file" process-fn="$ctrl.upload($ctrl.file)">
<div class="file-panel-container">
<entaxy-file-panel items="$ctrl.items" selected-item="$ctrl.selectedItem" view="$ctrl.view"
change-selection-fn="$ctrl.changeSelection" open-fn="$ctrl.open"></entaxy-file-panel>
</div>
<div class="meta-info" resizable r-directions="['left']" ng-if="$ctrl.selectedItem && $ctrl.selectedItem.metadata">
<uib-tabset active="$ctrl.activeTab" class="meta-tabs">
<uib-tab ng-repeat="(section, info) in $ctrl.selectedItem.metadata track by $index" heading="{{section}}">
<div class="json-formatter">
<json-formatter json="info" open="1"></json-formatter>
</div>
</uib-tab>
</uib-tabset>
</div>
</div>
`,
controller: entaxyResourcesController
})
.name;
function entaxyResourcesController(workspace, $scope, jolokiaService, operationsService, restService, $timeout, $uibModal) {
'ngInject';
let ctrl = this;
let selectedMbeanName = workspace.getSelectedMBeanName();
let clientFolders = [];
ctrl.$onInit = function () {
ctrl.view = 'list';
jolokiaService.getAttribute(selectedMbeanName, 'Protocol')
.then((protocol) => {
ctrl.protocol = protocol;
ctrl.crumbs = [];
});
}
$scope.$watchCollection('$ctrl.crumbs', function(newValue, oldValue) {
ctrl.selectedItem = null;
ctrl.location = getLocation();
updateItems();
})
ctrl.changeView = function (view) {
ctrl.view = view;
}
ctrl.changeSelection = function (item) {
ctrl.selectedItem = item;
ctrl.location = getLocation();
$timeout(function () {
ctrl.activeTab = 0;
});
}
ctrl.open = function (item) {
if (item.isFolder === true) {
ctrl.crumbs.push(item.name);
}
}
function updateItems() {
let path = getPath();
operationsService
.executeOperation(selectedMbeanName, { name: 'getResourcesInfo' }, [ path ])
.then((result) => {
let items = JSON.parse(result);
items.forEach(item => {
if (item.metadata) {
Object.keys(item.metadata).forEach(section => {
item.metadata[section] = JSON.parse(item.metadata[section]);
});
}
});
items = items.concat(getClientFoldersToAdd(items));
ctrl.items = items.sort(Entaxy.compareBy('name')).sort((a, b) => b.isFolder - a.isFolder);
})
.catch((error) => {
Entaxy.log.error(error);
Core.notification('danger', 'An error occurred while getting resources.', 5000);
})
}
function getPath() {
let path = '';
if (ctrl.crumbs && ctrl.crumbs.length > 0) {
path = ctrl.crumbs.join('/');
}
return path;
}
ctrl.copyLocationToClipboard = function() {
let clipboard = new ClipboardJS('.btn-clipboard', {
text: (trigger) => ctrl.location
});
setTimeout(() => clipboard.destroy(), 1000);
}
function getLocation() {
let separator = getPath().length > 0 ? '/' : '';
let selectedItemName = ctrl.selectedItem && !ctrl.selectedItem.isFolder ? ctrl.selectedItem.name : '';
return ctrl.protocol + ':' + getPath() + separator + selectedItemName;
}
ctrl.createFolder = function () {
$uibModal.open({
component: 'entaxyAddFolderModal',
resolve: {
names: () => ctrl.items.filter((item) => item.isFolder).map((item) => item.name)
},
size: 'sm-custom',
backdrop: 'static',
windowTopClass: 'modal-top-margin-center-override'
})
.result.then(name => {
let newFolder = {
name: name,
isFolder: true,
crumbs: ctrl.crumbs.map((crumb) => crumb)
};
ctrl.items.push(newFolder);
ctrl.items = ctrl.items.sort(Entaxy.compareBy('name')).sort((a, b) => b.isFolder - a.isFolder);
clientFolders.push(newFolder);
});
}
function getClientFoldersToAdd(items) {
let foldersToAdd = [];
if (clientFolders.length > 0) {
clientFolders = clientFolders.filter((folder) => {
let isSaved = true;
if (folder.crumbs.length == ctrl.crumbs.length && (folder.crumbs.length == 0 ||
(folder.crumbs.length > 0 && folder.crumbs[folder.crumbs.length - 1] ===
ctrl.crumbs[ctrl.crumbs.length - 1]))) {
items.forEach((item) => {
if (item.isFolder && item.name === folder.name) {
isSaved = false;
}
});
if (isSaved) {
foldersToAdd.push(folder);
}
}
return isSaved;
});
}
return foldersToAdd;
}
ctrl.upload = function (file) {
if (!file) {
return;
}
let fd = new FormData();
fd.append('file', file);
fd.append('protocol', ctrl.protocol);
let separator = getPath().length > 0 ? '/' : '';
fd.append('path', getPath() + separator + file.name);
restService.post('/cxf/file-upload/upload/resource', fd)
.then((response) => {
Core.notification('success', 'File ' + response.data + ' was successfully uploaded.', 3000);
updateItems();
})
.catch((error) => {
Entaxy.log.error(error);
Core.notification('danger', 'An error occurred while uploading the file.', 5000);
});
}
}
entaxyResourcesController.$inject = ['workspace', '$scope', 'jolokiaService', 'operationsService', 'restService', '$timeout', '$uibModal'];
})(Entaxy || (Entaxy = {}));

View File

@ -4,30 +4,38 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
// fixme this component works only for connections now
Entaxy._module
.component('entaxySelect', {
bindings: {
type: '<',
filter: '<',
model: '=',
updateParent: '<',
updateParentFn: '<',
options: '='
options: '=',
creationEnabled: '<',
formController: '<'
},
template:
`
@ -38,7 +46,10 @@ var Entaxy;
</button>
<ul class="dropdown-menu">
<li ng-repeat="option in $ctrl.options" id="option.name" ng-click="$ctrl.changeSelection(option)">{{ option.name }}</li>
<li id="addItem" class="dropdown-option-new" ng-click="$ctrl.addConnection()"><span class="pficon pficon-add-circle-o"></span>New private connection...</li>
<li id="addItem" class="dropdown-option-new" ng-click="$ctrl.showModal()" ng-if="$ctrl.creationEnabled">
<span class="pficon pficon-add-circle-o"></span>
{{$ctrl.createObjectOptionTitle}}
</li>
</ul>
</div>
`,
@ -46,70 +57,70 @@ var Entaxy;
})
.name;
function entaxySelectController(workspace, jolokiaService, $q, $uibModal) {
function entaxySelectController(workspace, jolokiaService, jolokia, $q, $uibModal, entaxyService) {
'ngInject';
var ctrl = this;
let ctrl = this;
ctrl.$onInit = function() {
if (ctrl.type === 'entaxy.runtime.connection') {
ctrl.itemType = Entaxy.getItemTypeFromRuntimeType(ctrl.type);
if (!ctrl.options) {
if (ctrl.creationEnabled) {
ctrl.createObjectOptionTitle = 'New private ' + ctrl.itemType + '...';
}
let promises = [];
let filteredConnections = [];
if (!ctrl.options) {
let connectionsFolder = workspace.tree.findDescendant(child => (child.objectName && child.objectName.endsWith('category=connections')));
let domain = entaxyService.getDomainFolder();
let typedMBeans = entaxyService.getAllChildMBeansByRuntimeType(domain, ctrl.type);
if (connectionsFolder) {
if (ctrl.filter) {
connectionsFolder.children.forEach((child) => {
promises.push(
jolokiaService.getAttribute(child.objectName, 'Label')
.then((label) => {
if (label.indexOf(ctrl.filter) > -1) {
filteredConnections.push({ name: child.title, mbeanName: connectionsFolder.objectName });
}
})
);
});
} else {
filteredConnections = connectionsFolder.children ? connectionsFolder.children.map(child => { name: child.title }) : [];
}
}
$q.all(promises).then(() => {
if (filteredConnections && filteredConnections.length > 0) {
ctrl.options = filteredConnections.sort(Entaxy.compareBy('name'));
ctrl.changeSelection(filteredConnections[0]);
} else {
Core.notification('danger', 'There are no suitable connections', 5000);
// todo close the modal
if (ctrl.filter) {
let filteredMbeans = [];
typedMBeans.forEach(mbean => {
let label = jolokia.getAttribute(mbean.objectName, 'Label');
if (label.match(ctrl.filter)) {
filteredMbeans.push(mbean);
}
});
} else {
ctrl.selectedOption = ctrl.options.find((option) => option.name === ctrl.model || option.value === ctrl.model);
typedMBeans = filteredMbeans;
}
let items = typedMBeans.map(mbean => { return { name: jolokia.getAttribute(mbean.objectName, 'Name') }; });
if (items && items.length > 0) {
ctrl.options = items.sort(Entaxy.compareBy('name'));
ctrl.changeSelection(items[0]);
} else {
ctrl.options = [];
let notificationType = ctrl.creationEnabled ? 'warning' : 'danger';
Core.notification(notificationType, 'There are no suitable ' + ctrl.itemType, 5000);
// todo close the modal if creation isn't enabled
}
} else {
ctrl.selectedOption = ctrl.options.find((option) => option.name === ctrl.model || option.value === ctrl.model);
}
}
ctrl.changeSelection = function (option) {
let previousOption = ctrl.selectedOption;
ctrl.selectedOption = option;
ctrl.model = option.value ? option.value : option.name;
if (ctrl.selectedOption !== option) {
let previousOption = ctrl.selectedOption;
ctrl.selectedOption = option;
ctrl.model = option.value ? option.value : option.name;
if (ctrl.type === 'entaxy.runtime.connection') {
if (previousOption) {
Core.notification('warning', 'Changing connection field value may lead to changes in other fields of the current connector. ' +
'Please, make sure to revise all fields before accepting.', 10000);
if (previousOption && ctrl.formController && !ctrl.formController.$dirty) {
ctrl.formController.$setDirty();
}
ctrl.updateParentFn(previousOption, option, 'Connection');
}
}
ctrl.addConnection = function () {
ctrl.showModal();
if (ctrl.updateParent) {
if (previousOption) {
Core.notification('warning',
'Changing ' + ctrl.itemType + ' field value may lead to changes in other fields of the current object. ' +
'Please, make sure to revise all fields before accepting.', 10000);
}
ctrl.updateParentFn(previousOption, option, Entaxy.capitalize(ctrl.itemType));
}
}
}
ctrl.showModal = function() {
@ -117,7 +128,7 @@ var Entaxy;
let factories = [];
let promises = [];
let factoryFolder = workspace.tree.findDescendant(child => child.title === ctrl.type);
let factoryFolder = entaxyService.getDomainFolder().findDescendant(child => child.title === ctrl.type);
if (factoryFolder && factoryFolder.children) {
factoryFolder.children.forEach((child) => {
@ -144,7 +155,7 @@ var Entaxy;
component: 'entaxyModal',
resolve: {
mode: () => Entaxy.MODAL_MODES.ADD,
itemType: () => 'Connection',
itemType: () => Entaxy.capitalize(ctrl.itemType),
factories: $q.all(promises).then(() => factories)
},
size: 'xl',
@ -180,7 +191,7 @@ var Entaxy;
};
let newObjectOption = {
name: objectId ? objectId : 'private-connection',
name: objectId ? objectId : ('private-' + ctrl.itemType),
value: newObjectProperties
};
@ -188,6 +199,6 @@ var Entaxy;
ctrl.changeSelection(newObjectOption);
}
}
entaxySelectController.$inject = ['workspace', 'jolokiaService', '$q', '$uibModal'];
entaxySelectController.$inject = ['workspace', 'jolokiaService', 'jolokia', '$q', '$uibModal', 'entaxyService'];
})(Entaxy || (Entaxy = {}));

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
@ -24,35 +30,57 @@ var Entaxy;
bindings: {
values: '<',
isEmptyIncluded: '<',
model: '='
model: '=',
readonly: '<'
},
template:
`
<select class="form-control" ng-options="option.name for option in $ctrl.options" ng-model="$ctrl.selectedOption"
ng-change="$ctrl.changeSelection()">
ng-change="$ctrl.changeSelection()" ng-disabled="$ctrl.readonly">
`,
controller: entaxySelectFromEnumController
})
.name;
function entaxySelectFromEnumController() {
function entaxySelectFromEnumController($scope) {
'ngInject';
let ctrl = this;
let emptyValue = { name: '--Empty value--' };
ctrl.$onInit = function() {
ctrl.options = ctrl.values.map(value => { return { name: value } });
populateOptions();
}
ctrl.options.unshift(emptyValue);
function populateOptions() {
ctrl.options = (ctrl.values && ctrl.values.length > 0) ? ctrl.values.map(value => { return { name: value } }) : [];
if (ctrl.isEmptyIncluded !== false) {
ctrl.options.unshift(emptyValue);
}
}
$scope.$watchCollection('$ctrl.values', function(newValue, oldValue) {
if (newValue !== oldValue) {
populateOptions();
let currentSelectedOption = ctrl.options.find((option) => option.name === ctrl.selectedOption.name);
ctrl.selectedOption = currentSelectedOption ? currentSelectedOption : ctrl.options[0];
ctrl.changeSelection();
}
});
$scope.$watch('$ctrl.model', function(newValue, oldValue) {
ctrl.selectedOption = ctrl.model ? ctrl.options.find((option) => option.name === ctrl.model) : ctrl.options[0];
ctrl.changeSelection();
}
});
ctrl.changeSelection = function () {
ctrl.model = (ctrl.selectedOption === emptyValue) ? undefined : ctrl.selectedOption.name;
}
}
entaxySelectFromEnumController.$inject = ['$scope'];
})(Entaxy || (Entaxy = {}));

View File

@ -0,0 +1,45 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module
.component('entaxyServices', {
bindings: {
pageTitle: '@'
},
template:
`
<h2>
{{$ctrl.pageTitle}}
</h2>
<entaxy-table runtime-type="entaxy.runtime.service"
status-name="BundleState" object-name="systemName"></entaxy-table>
`
})
.name;
})(Entaxy || (Entaxy = {}));

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
@ -24,16 +30,18 @@ var Entaxy;
template:
`
<div class="route-source-header-container">
<h2>
Source
</h2>
<span class="route-source-error-message" ng-if="$ctrl.errorMessage">*{{$ctrl.errorMessage}}</span>
<div>
<h2>
Source
</h2>
<span class="route-source-error-message" ng-if="$ctrl.xml.trim().length === 0">*{{$ctrl.errorMessage}}</span>
</div>
<button type="submit" class="btn btn-primary" ng-click="$ctrl.save()" ng-if="$ctrl.isContentPresent">Save changes</button>
</div>
<div ng-if="$ctrl.isContentPresent">
<div class="xml-route-source-container">
<div hawtio-editor="xml" mode="'xml'" output-editor="xmlEditor"></div>
<entaxy-xml-editor class="xml-editor" source-doc="$ctrl.xml"></entaxy-xml-editor>
</div>
<button type="submit" class="btn btn-primary" ng-click="$ctrl.save()">Save changes</button>
</div>
<div ng-if="$ctrl.isContentPresent === false">There is no viewable content.</div>
`,
@ -41,10 +49,11 @@ var Entaxy;
})
.name;
function entaxySourceController(workspace, operationsService, $scope) {
function entaxySourceController(workspace, $location, operationsService, $scope, entaxyService) {
'ngInject';
let ctrl = this;
ctrl.errorMessage = 'Value cannot be empty';
ctrl.$onInit = function() {
@ -64,7 +73,7 @@ var Entaxy;
ctrl.scope = info.scope;
ctrl.systemName = info.properties.systemName;
$scope.xml = atob(xml);
ctrl.xml = atob(xml);
} else {
ctrl.isContentPresent = false;
}
@ -75,13 +84,45 @@ var Entaxy;
});
}
ctrl.save = function() {
if ($scope.xml.trim().length !== 0) {
ctrl.errorMessage = '';
$scope.$watch('$ctrl.xml', function (newValue, oldValue) {
if (newValue && oldValue) {
if (!ctrl.isDirty) {
ctrl.isDirty = true;
}
}
});
let factoryFolder = workspace.tree.findDescendant(child => child.title === ctrl.factoryId);
setTimeout( function () {
ctrl.activeTabIndex = entaxyService.getActiveTabIndex();
})
$scope.$on("$locationChangeStart", function(event) {
if (ctrl.isDirty && !confirm('You have unsaved changes. Do you want to leave the page anyway?')) {
event.preventDefault();
ctrl.isTreeOrTabSelectionUpdateNeeded = true;
}
});
$scope.$watch('$ctrl.isTreeOrTabSelectionUpdateNeeded', function (newValue) {
if (newValue) {
setTimeout(function () {
entaxyService.updateTabSelection(ctrl.activeTabIndex);
});
Jmx.updateTreeSelectionFromURL($location, $(entaxyTreeElementId));
ctrl.isTreeOrTabSelectionUpdateNeeded = false;
}
});
ctrl.save = function() {
entaxyService.requestConfirmationForSavingIfNeededAndProceed(!ctrl.isDirty, save);
};
function save() {
if (ctrl.xml.trim().length !== 0) {
let factoryFolder = entaxyService.getDomainFolder()
.findDescendant(child => child.title === ctrl.factoryId);
let mbeanName = factoryFolder.objectName
let properties = { systemName: ctrl.systemName, routeContent: btoa($scope.xml) };
let properties = { systemName: ctrl.systemName, routeContent: btoa(ctrl.xml) };
let instructions = {"@LIFECYCLE":["general"]};
operationsService.executeOperation(mbeanName, { name: 'createObjectByInstructions' }, [ ctrl.objectId, ctrl.scope, instructions, properties ] )
@ -92,16 +133,11 @@ var Entaxy;
Core.notification('danger', error, 5000);
Entaxy.log.error(error);
});
} else {
ctrl.errorMessage = 'Value cannot be empty';
}
};
setTimeout(function() {
$scope.xmlEditor.options.extraKeys = Entaxy.getExtraKeys();
$scope.xmlEditor.options.hintOptions = Entaxy.getHintOptionsForRouteXml();
}, 100);
ctrl.isDirty = false;
}
}
}
entaxySourceController.$inject = ['workspace', 'operationsService', '$scope'];
entaxySourceController.$inject = ['workspace', '$location', 'operationsService', '$scope', 'entaxyService'];
})(Entaxy || (Entaxy = {}));

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
@ -22,8 +28,7 @@ var Entaxy;
Entaxy._module
.component('entaxyTable', {
bindings: {
itemName: '@',
folderName: '@',
runtimeType: '@',
statusName: '@',
objectName: '@',
isParentDependent: '<',
@ -44,17 +49,16 @@ var Entaxy;
})
.name;
function EntaxyTableController(workspace, $location, $scope, $q, jolokia, jolokiaService, $uibModal, operationsService) {
function EntaxyTableController(workspace, $location, $scope, $q, jolokia, jolokiaService, operationsService, entaxyService) {
'ngInject';
var ctrl = this;
ctrl.workspace = workspace;
var entaxyJmxDomain = localStorage['entaxyJmxDomain'] || "ru.entaxy.esb";
let filterValues = Entaxy.getAllBundleStates();
ctrl.tableConfig = {
selectionMatchProp: 'name',
selectionMatchProp: 'displayName',
showCheckboxes: false
};
@ -62,7 +66,7 @@ var Entaxy;
filterConfig: {
fields: [
{
id: 'name',
id: 'displayName',
title: 'Name',
placeholder: 'Filter by Name...',
filterType: 'text'
@ -82,49 +86,21 @@ var Entaxy;
};
ctrl.tableColumns = [
{ header: 'Name', itemField: 'name' },
{ header: 'Name', itemField: 'displayName' },
{ header: 'Status', itemField: 'status' }
];
ctrl.pageConfig = {
pageNumber: 1,
pageSize: 10,
pageSizeIncrements: [5, 10, 20, 50, 100]
};
ctrl.pageConfig = Entaxy.getStandardPageConfig();
function filterChange(filters) {
applyFilters(filters);
ctrl.viewedItems = Entaxy.applyFilters(ctrl.items, filters, matchesFilter);
ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.viewedItems.length;
};
function applyFilters(filters) {
ctrl.viewedItems = [];
if (filters && filters.length > 0) {
ctrl.items.forEach(function (item) {
if (matchesFilters(item, filters)) {
ctrl.viewedItems.push(item);
}
});
} else {
ctrl.viewedItems = ctrl.items;
}
};
function matchesFilters(item, filters) {
var matches = true;
filters.forEach(function(filter) {
if (!matchesFilter(item, filter)) {
matches = false;
return false;
}
});
return matches;
};
function matchesFilter(item, filter) {
var match = true;
if (filter.id === 'name') {
match = item.name.match(filter.value) !== null;
let match = true;
if (filter.id === 'displayName') {
match = item.displayName.match(filter.value) !== null;
} else if (filter.id === 'status') {
match = item.status === filter.value;
}
@ -137,7 +113,9 @@ var Entaxy;
ctrl.$onInit = function() {
populateTable();
let primaryActions = [ { name: 'Add ' + ctrl.itemName, actionFn: () => ctrl.showModal(Entaxy.MODAL_MODES.ADD) } ];
ctrl.itemType = Entaxy.capitalize(Entaxy.getItemTypeFromRuntimeType(ctrl.runtimeType));
let primaryActions = [ { name: 'Add ' + ctrl.itemType, actionFn: () => ctrl.showModal(Entaxy.MODAL_MODES.ADD) } ];
if (ctrl.extraPrimaryActionsConfig) {
let extraPrimaryActions = ctrl.extraPrimaryActionsConfig.primaryActions;
@ -153,14 +131,14 @@ var Entaxy;
};
ctrl.tableActionButtons = [
{ name: 'Start', title: 'Start ' + ctrl.itemName, actionFn: startItem },
{ name: 'Stop', title: 'Stop ' + ctrl.itemName, actionFn: stopItem },
{ name: 'Uninstall', title: 'Uninstall ' + ctrl.itemName, actionFn: uninstallItem }
{ name: 'Start', title: 'Start ' + ctrl.itemType, actionFn: startItem },
{ name: 'Stop', title: 'Stop ' + ctrl.itemType, actionFn: stopItem },
{ name: 'Uninstall', title: 'Uninstall ' + ctrl.itemType, actionFn: uninstallItem }
];
ctrl.menuActions = [
{ name: 'View Properties', title: 'View ' + ctrl.itemName + ' Properties', actionFn: showPropertiesModal },
{ name: 'Edit Properties', title: 'Edit ' + ctrl.itemName + ' Properties', actionFn: showPropertiesModal }
{ name: 'View Properties', title: 'View ' + ctrl.itemType + ' Properties', actionFn: showPropertiesModal },
{ name: 'Edit Properties', title: 'Edit ' + ctrl.itemType + ' Properties', actionFn: showPropertiesModal }
];
}
@ -174,138 +152,68 @@ var Entaxy;
function populateTable() {
let items = [];
let promises = [];
let selectedMBean = workspace.getSelectedMBean();
if (selectedMBean && selectedMBean.isFolder) {
let currentFolder = selectedMBean;
if (selectedMBean.text !== ctrl.folderName) {
currentFolder = selectedMBean.get(ctrl.folderName);
}
let children = entaxyService.getAllChildMBeansByRuntimeType(selectedMBean, ctrl.runtimeType);
if (currentFolder) {
let children = currentFolder.children;
if (children) {
children.forEach((child) => {
jolokiaService.getAttributes(child.objectName, [ctrl.statusName])
.then((response) => {
items.push({name: child.title, status: response[ctrl.statusName], mbeanName: child.objectName});
if (children) {
children.forEach((child) => {
promises.push(jolokiaService.getAttributes(child.objectName, [ctrl.statusName, 'Name', 'DisplayName'])
.then((response) => {
items.push({
name: response['Name'],
displayName: response['DisplayName'] === '' || response['DisplayName'].startsWith('ERROR') ? response['Name'] : response['DisplayName'],
status: response[ctrl.statusName],
mbeanName: child.objectName
});
});
}));
});
$q.all(promises)
.then(() => {
ctrl.items = items;
ctrl.viewedItems = items;
ctrl.toolbarConfig.filterConfig.resultsCount = children.length;
}
let filters = ctrl.toolbarConfig.filterConfig.appliedFilters;
if (filters.length > 0) {
filterChange(filters);
} else {
ctrl.toolbarConfig.filterConfig.resultsCount = items.length;
}
});
}
}
}
ctrl.showModal = function(mode, item) {
let factories = [];
let promises = [];
if (mode === Entaxy.MODAL_MODES.ADD) {
let factoryFolder = workspace.tree.findDescendant(child => child.title === 'entaxy.runtime.' + ctrl.itemName.toLowerCase());
let parentName;
if (ctrl.isParentDependent === true) {
let selectedMbeanName = workspace.getSelectedMBeanName();
parentName = jolokia.getAttribute(selectedMbeanName, 'Name');
}
if (factoryFolder && factoryFolder.children) {
factoryFolder.children.forEach((child) => {
promises.push(jolokiaService.getAttributes(child.objectName, ['Abstract', 'DisplayName', 'Label', 'Description', 'Deprecated'])
.then((result) => {
if (!result['Abstract']) {
factories.push({
name: child.title,
displayName: result['DisplayName'] ? result['DisplayName'] : child.title,
label: result['Label'],
mbeanName: child.objectName,
description: result['Description'] ? result['Description'] : 'There is no description for this factory.',
additionalInfo: result['Deprecated'] ? ['[DEPRECATED]'] : undefined
});
}
}));
});
let resolve = {
mode: () => mode,
itemType: () => ctrl.itemType,
parentName: () => parentName
};
$q.all(promises).then(() => {
if (mode === Entaxy.MODAL_MODES.ADD) {
let parentName;
if (ctrl.isParentDependent === true) {
let selectedMbean = workspace.getSelectedMBean();
parentName = selectedMbean.title;
}
openEntaxyModal({
mode: () => mode,
itemType: () => ctrl.itemName,
parentName: () => parentName,
factories: () => factories
}, mode);
} else {
let mbeanName = workspace.getSelectedMBeanName();
operationsService
.executeOperation(mbeanName, { name: 'get' + ctrl.itemName + 'Config' }, [ item.name ])
.then(result => {
let itemInfo = JSON.parse(result);
let factory = factories.find(factory => factory.name === itemInfo.factoryId);
openEntaxyModal({
itemName: () => item.name,
itemType: () => ctrl.itemName,
mode: () => mode,
info: () => itemInfo,
factories: () => [ factory ]
}, mode);
}).catch(error => {
Core.notification('danger', 'Unable to view configuration of selected item.', 5000);
Entaxy.log.error(error);
});
}
});
entaxyService.openAddItemModalAndProcessResults(resolve, updateLocation);
} else {
let mbeanName = workspace.getSelectedMBeanName();
entaxyService.openEditItemModalAndProcessResults(mbeanName, ctrl.itemType, item.name, mode);
}
}
function openEntaxyModal(resolve, mode) {
$uibModal.open({
component: 'entaxyModal',
resolve: resolve,
size: 'xl',
backdrop: 'static'
})
.result.then(args => {
addItem(args, mode)
},
reason => {
if (reason) {
Core.notification('danger', reason, 5000);
}
});
}
function addItem(args, mode) {
let objectId = args.fields.find((field) => field.name === 'objectId').value;
let fields = objectId ? args.fields.filter((field) => field.name !== 'objectId') : args.fields;
let mbeanName = args.factoryId.mbeanName;
let properties = fields.reduce((obj, cur) => ({ ...obj, [cur.name] : cur.value }), {});
let instructions = {"@LIFECYCLE":["general"]};
operationsService.executeOperation(mbeanName, { name: 'createObjectByInstructions' }, [ objectId, 'public', instructions, properties ] )
.then(result => {
let tableHtml = Entaxy.createTableFromResponse(result);
Entaxy.notification('success', tableHtml, 10000);
if (ctrl.isParentDependent || mode === Entaxy.MODAL_MODES.EDIT) {
$scope.$on(Jmx.TreeEvent.Updated, () => populateTable());
} else {
changeLocation(properties[ctrl.objectName] ? properties[ctrl.objectName] : objectId);
}
}).catch(error => {
Core.notification('danger', error, 5000);
Entaxy.log.error(error);
});
function updateLocation(properties, objectId) {
if (!ctrl.isParentDependent) {
changeLocation(properties[ctrl.objectName] ? properties[ctrl.objectName] : objectId);
}
}
function changeLocation(itemName) {
@ -313,11 +221,15 @@ var Entaxy;
$location.search('nid', currentLocation.nid + '-' + itemName);
}
$scope.$on(Jmx.TreeEvent.Updated, () => {
populateTable();
});
function startItem(action, item) {
if (item.status !== 'Active') {
processOperation('start', item.name);
} else {
Core.notification('info', ctrl.itemName + ' has been already started');
Core.notification('info', ctrl.itemType + ' has been already started');
}
}
@ -325,31 +237,31 @@ var Entaxy;
if (item.status !== 'Resolved') {
processOperation('stop', item.name);
} else {
Core.notification('info', ctrl.itemName + ' has been already stopped');
Core.notification('info', ctrl.itemType + ' has been already stopped');
}
}
function uninstallItem(action, item) {
let operationName = ctrl.isParentDependent ? 'remove' : 'uninstall';
processOperation(operationName, item.name);
let title = 'Confirm Uninstalling';
let message = 'Do you want to uninstall ' + ctrl.itemType.toLowerCase() + ' ' + item.displayName + '?';
entaxyService.openConfirmationWindow(title, message).then(() => {
processOperation(operationName, item.name);
});
}
function processOperation(operationName, selectedItemName) {
let mbeanName = workspace.getSelectedMBeanName();
let operation = { name: operationName + ctrl.itemType };
operationsService.executeOperation(mbeanName, { name: operationName + ctrl.itemName }, [ selectedItemName ])
.then(result => {
Core.notification('success', result, 3000);
$scope.$on(Jmx.TreeEvent.Updated, () => populateTable());
}).catch(error => {
Core.notification('danger', error, 5000);
Entaxy.log.error(error);
});
entaxyService.processTableOperation(mbeanName, operation, selectedItemName);
}
ctrl.dismissAlert = () => ctrl.alert = null;
}
EntaxyTableController.$inject = ['workspace', '$location', '$scope', '$q', 'jolokia', 'jolokiaService', '$uibModal', 'operationsService'];
EntaxyTableController.$inject = ['workspace', '$location', '$scope', '$q', 'jolokia', 'jolokiaService', 'operationsService', 'entaxyService'];
})(Entaxy || (Entaxy = {}));

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;

View File

@ -0,0 +1,73 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module
.component('entaxyUrlInput', {
bindings: {
model: '=',
config: '<',
formController: '<'
},
template:
`
<div class="input-with-button">
<input type="text" ng-model="$ctrl.model" ng-class="{'form-control': true}" readonly>
<button class="entaxy-view-resources-form" ng-click="$ctrl.openViewer()">Select...</button>
</div>
`,
controller: entaxyUrlInputController
})
.name;
function entaxyUrlInputController(workspace, $uibModal) {
'ngInject';
let ctrl = this;
ctrl.openViewer = function() {
$uibModal.open({
component: 'entaxyResourceViewerModal',
resolve: {
location: () => ctrl.model,
config: () => ctrl.config
},
size: 'xl',
backdrop: 'static',
windowTopClass: 'modal-top-margin-override'
})
.result.then(location => {
if (ctrl.model !== location && ctrl.formController && !ctrl.formController.$dirty) {
ctrl.formController.$setDirty();
}
ctrl.model = location;
});
}
}
entaxyUrlInputController.$inject = ['workspace', '$uibModal'];
})(Entaxy || (Entaxy = {}));

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
@ -23,11 +29,13 @@ var Entaxy;
.component('entaxyXml', {
bindings: {
ngModel: '=',
mode: '<'
mode: '<',
disabled: '<',
formController: '<'
},
template:
`
<button class="entaxy-xml-form" ng-click="$ctrl.openEditor()">{{$ctrl.mode}}</button>
<button class="entaxy-xml-form" ng-click="$ctrl.openEditor()" ng-disabled="$ctrl.disabled">{{$ctrl.mode}}</button>
`,
controller: entaxyXmlController
})
@ -36,12 +44,12 @@ var Entaxy;
function entaxyXmlController(workspace, $uibModal) {
'ngInject';
var ctrl = this;
let ctrl = this;
ctrl.openEditor = function() {
$uibModal.open({
component: 'xmlModal',
component: 'entaxyXmlModal',
resolve: {
xml: () => ctrl.ngModel,
mode: () => ctrl.mode
@ -51,6 +59,9 @@ var Entaxy;
windowTopClass: 'modal-top-margin-override'
})
.result.then(xml => {
if (ctrl.ngModel !== xml && ctrl.formController && !ctrl.formController.$dirty) {
ctrl.formController.$setDirty();
}
ctrl.ngModel = xml;
});
}

View File

@ -0,0 +1,66 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module
.component('entaxyXmlEditor', {
bindings: {
sourceDoc: '=',
readOnly: '<'
},
template:
`
<div hawtio-editor="xml" mode="'xml'" output-editor="xmlEditor"></div>
`,
controller: entaxyXmlEditorController
})
.name;
function entaxyXmlEditorController($scope) {
'ngInject';
let ctrl = this;
ctrl.$onInit = function () {
$scope.xml = ctrl.sourceDoc;
}
$scope.$watch('xml', function (newValue) {
ctrl.sourceDoc = newValue;
});
setTimeout(function() {
if (ctrl.readOnly === true) {
$scope.xmlEditor.options.readOnly = true;
} else {
$scope.xmlEditor.options.smartIndent = false;
$scope.xmlEditor.options.extraKeys = Entaxy.getExtraKeys();
$scope.xmlEditor.options.hintOptions = Entaxy.getHintOptionsForRouteXml();
}
}, 100);
}
entaxyXmlEditorController.$inject = ['$scope'];
})(Entaxy || (Entaxy = {}));

View File

@ -4,22 +4,28 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module.component('xmlModal', {
Entaxy._module.component('entaxyXmlModal', {
bindings: {
modalInstance: '<',
resolve: '<'
@ -35,7 +41,7 @@ var Entaxy;
</div>
<div class="modal-body-without-header">
<div class="xml-editor-container">
<div hawtio-editor="xml" mode="'xml'" output-editor="xmlEditor"></div>
<entaxy-xml-editor class="xml-editor" source-doc="$ctrl.xml" read-only="$ctrl.readOnly"></entaxy-xml-editor>
</div>
</div>
<div class="modal-footer">
@ -43,11 +49,11 @@ var Entaxy;
</div>
</div>
`,
controller: xmlModalController
controller: entaxyXmlModalController
})
.name;
function xmlModalController(workspace, $uibModal, $scope) {
function entaxyXmlModalController($uibModal) {
'ngInject';
let ctrl = this;
@ -56,8 +62,8 @@ var Entaxy;
ctrl.mode = ctrl.resolve.mode;
ctrl.modalTitle = ctrl.mode + ' XML';
ctrl.btnTitle = Entaxy.getButtonTitleByMode(ctrl.mode);
$scope.xml = ctrl.resolve.xml;
ctrl.readOnly = ctrl.mode === Entaxy.MODAL_MODES.VIEW;
ctrl.xml = ctrl.resolve.xml;
}
ctrl.cancel = function(reason) {
@ -65,18 +71,9 @@ var Entaxy;
}
ctrl.save = function() {
ctrl.modalInstance.close($scope.xml);
ctrl.modalInstance.close(ctrl.xml);
}
setTimeout(function() {
if (ctrl.mode === Entaxy.MODAL_MODES.VIEW) {
$scope.xmlEditor.options.readOnly = true;
} else {
$scope.xmlEditor.options.extraKeys = Entaxy.getExtraKeys();
$scope.xmlEditor.options.hintOptions = Entaxy.getHintOptionsForRouteXml();
}
}, 100);
}
xmlModalController.$inject = ['workspace', '$uibModal', '$scope'];
entaxyXmlModalController.$inject = ['$uibModal'];
})(Entaxy || (Entaxy = {}));

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
@ -39,6 +45,11 @@ var Entaxy;
}
Entaxy.getButtonTitleByMode = getButtonTitleByMode;
function getItemTypeFromRuntimeType(runtimeType) {
return runtimeType.replace('entaxy.runtime.', '');
}
Entaxy.getItemTypeFromRuntimeType = getItemTypeFromRuntimeType;
function capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
@ -77,13 +88,51 @@ var Entaxy;
}
Entaxy.compareBy = compareBy;
function getStandardPageConfig() {
return {
pageNumber: 1,
pageSize: 10,
pageSizeIncrements: [5, 10, 20, 50, 100]
};
}
Entaxy.getStandardPageConfig = getStandardPageConfig;
function applyFilters(items, filters, matchesFilterFn) {
let viewedItems = [];
if (filters && filters.length > 0) {
items.forEach(function (item) {
if (matchesFilters(item, filters, matchesFilterFn)) {
viewedItems.push(item);
}
});
} else {
viewedItems = items;
}
return viewedItems;
};
Entaxy.applyFilters = applyFilters;
function matchesFilters(item, filters, matchesFilterFn) {
let matches = true;
filters.forEach(function(filter) {
if (!matchesFilterFn(item, filter)) {
matches = false;
return false;
}
});
return matches;
};
function convertToHtmlInputType(javaType) {
if (!javaType || javaType.startsWith('entaxy.runtime')) {
return javaType;
}
switch (javaType) {
case 'password':
case 'xml:route':
return javaType;
case 'Url':
return 'url';
case 'boolean':
case 'Boolean':
case 'java.lang.Boolean':

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
/**
@ -39,7 +45,8 @@ var Entaxy = (function (Entaxy) {
Entaxy.log.info("loading entaxy plugin")
Entaxy._module = angular.module(Entaxy.pluginName, [
'angularResizable'
'angularResizable',
'jsonFormatter'
])
.component('entaxy', {
template:
@ -58,10 +65,10 @@ var Entaxy = (function (Entaxy) {
})
.run(configurePlugin);
function configurePlugin(mainNavService, workspace, helpRegistry, preferencesRegistry, localStorage, preLogoutTasks, documentBase, $templateCache, $rootScope) {
function configurePlugin(mainNavService, workspace, helpRegistry, preferencesRegistry, localStorage, preLogoutTasks, documentBase, $templateCache, $rootScope, jolokia) {
var entaxyJmxDomain = localStorage['entaxyJmxDomain'] || "ru.entaxy.esb";
mainNavService.addItem({
title: 'Entaxy',
title: 'Entaxy ION',
basePath: '/entaxy',
template: '<entaxy></entaxy>',
isValid: function () { return workspace.treeContainsDomainAndProperties(entaxyJmxDomain); }
@ -75,21 +82,21 @@ var Entaxy = (function (Entaxy) {
angular.forEach(domain.children, (node) => {
node.class = 'entaxy-node-icon';
angular.forEach(['platform', 'runtime', 'resource'], (folderName) => {
angular.forEach(['platform', 'runtime'], (folderName) => {
let folder = domain.findDescendant(child => child.title === folderName);
if (folder) {
folder.class = createClassName(folderName);
}
});
angular.forEach(['adapter', 'factories', 'connections'], (folderName) => {
angular.forEach(['adapter', 'factories', 'connections', 'resource', 'services', 'connectors'], (folderName) => {
addClassRecursive(
domain.findDescendant(child => child.title === folderName),
createClassName(folderName)
);
});
addClassToParentAndItsChildren(domain, 'profiles');
addClassToParentAndItsChildrenUsingRuntimeType(domain.findDescendant(child => child.title === 'profiles'));
});
}
}
@ -108,22 +115,36 @@ var Entaxy = (function (Entaxy) {
}
}
function addClassToParentAndItsChildren(domain, parentName) {
let className = createClassName(parentName);
let parent = domain.findDescendant(child => child.title === parentName);
function addClassToParentAndItsChildrenUsingRuntimeType(folder) {
if (folder) {
if (folder.objectName) {
let attributes = jolokia.getAttribute(folder.objectName);
if (attributes.RuntimeType) {
folder.class = runtimeTypeToClassName[attributes.RuntimeType];
if (parent) {
parent.class = className;
angular.forEach(parent.children, (child) => {
child.class = className;
if (attributes.Direction) {
folder.class += ' ' + attributes.Direction;
}
} else {
folder.class = createClassName(folder.title);
}
} else {
folder.class = createClassName(folder.title);
}
angular.forEach(child.children, (grandChild) => {
addClassRecursive(grandChild, createClassName(grandChild.title));
})
folder.children.forEach((child) => {
addClassToParentAndItsChildrenUsingRuntimeType(child);
});
}
}
const runtimeTypeToClassName = {
'entaxy.runtime.profile': 'entaxy-profiles-icon',
'entaxy.runtime.connector': 'entaxy-connectors-icon',
'entaxy.runtime.default-route': 'entaxy-routes-icon',
'entaxy.runtime.connection': 'entaxy-connections-icon'
}
function createClassName(folderName) {
return 'entaxy-' + folderName + '-icon';
}
@ -156,6 +177,31 @@ var Entaxy = (function (Entaxy) {
}
});
workspace.addNamedTreePostProcessor('useDisplayName', (tree) => {
if (tree) {
let domain = tree.get(entaxyJmxDomain);
if (domain) {
useDisplayName(domain.children);
}
}
});
function useDisplayName(children) {
children.forEach(child => {
if (child.objectName) {
let attributes = jolokia.getAttribute(child.objectName);
if (attributes.RuntimeType) {
if (attributes.RuntimeType === 'entaxy.runtime.connector') {
if (attributes.DisplayName) {
child.title = attributes.DisplayName;
}
}
}
}
useDisplayName(child.children);
});
}
// clean up local storage upon logout
/* preLogoutTasks.addTask('CleanupArtemisCredentials', function () {
Artemis.log.debug("Clean up Artemis credentials in local storage");
@ -163,7 +209,7 @@ var Entaxy = (function (Entaxy) {
localStorage.removeItem('artemisPassword');
}); */
}
configurePlugin.$inject = ['mainNavService', 'workspace', 'helpRegistry', 'preferencesRegistry', 'localStorage', 'preLogoutTasks', 'documentBase', '$templateCache','$rootScope'];
configurePlugin.$inject = ['mainNavService', 'workspace', 'helpRegistry', 'preferencesRegistry', 'localStorage', 'preLogoutTasks', 'documentBase', '$templateCache', '$rootScope', 'jolokia'];
return Entaxy;
@ -173,7 +219,7 @@ var Entaxy = (function (Entaxy) {
// bootstrapped with the rest of AngularJS
hawtioPluginLoader.addModule(Entaxy.pluginName);
var L10N = {
const L10N = {
platform: 'Платформа',
adapter: 'Адаптеры',
factories: 'Фабрики',
@ -182,5 +228,6 @@ var L10N = {
profiles:'Профили',
connectors:'Коннекторы',
routes:'Маршруты',
resource: 'Ресурсы'
resource: 'Ресурсы',
services: 'Сервисы'
};

View File

@ -1,301 +0,0 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module.factory('entaxyService', ['$q', 'workspace', 'jolokia', 'jolokiaService', 'operationsService',
function($q, workspace, jolokia, jolokiaService, operationsService) {
return {
makeFormField: function (field, objectId, properties, mode) {
return makeFormField(field, objectId, properties, mode);
},
getArguments: function (fields, factories) {
return getArguments(fields, factories);
},
validateFields: function (fields, selectedFactory, itemType) {
return validateFields(fields, selectedFactory, itemType);
}
};
function makeFormField(field, objectId, properties, mode) {
let formField;
if (mode !== Entaxy.MODAL_MODES.ADD) {
if (field.name === 'objectId') {
field.value = objectId;
}
let suitableProperty = properties.find(property => property.name === field.name);
if (suitableProperty) {
if (field.type.startsWith('entaxy.runtime.')) {
field.type = 'string';
}
if (field.defaultValue && field.defaultValue['@RESOURCE'] && field.defaultValue['@RESOURCE'].format === 'base64') {
suitableProperty.value = atob(suitableProperty.value);
}
field.value = suitableProperty.value;
}
if (!field.isHidden && field.defaultValue !== undefined && field.value === undefined) {
field.displayName = field.displayName ? ('* ' + field.displayName) : ('* ' + field.name);
}
if (field['@FACADE'] && field['@FACADE'].useFacade) {
field.type = field['@FACADE'].type;
field.value = field['@FACADE'].value;
field.defaultValue = undefined;
field.immutable = true;
}
formField = {
label: field.displayName ? field.displayName : field.name,
name: field.name,
type: field.type,
description: field.description,
value: field.value ? field.value : field.defaultValue,
isRef: field.isRef,
isBackRef: field.isBackRef,
isHidden: field.isHidden,
group: field.group ? field.group : 'general',
tag: field.label,
readOnly: mode === Entaxy.MODAL_MODES.VIEW ? true : field.immutable,
required: mode === Entaxy.MODAL_MODES.EDIT ? field.required : undefined,
typeInfo: mode === Entaxy.MODAL_MODES.EDIT ? field['@TYPEINFO'] : undefined,
isFromResource: field.defaultValue && field.defaultValue['@RESOURCE'],
defaultValue: field.defaultValue,
isInternal: field['@INTERNAL']
};
} else {
if (field.defaultValue) {
if (JSON.stringify(field.defaultValue).indexOf('@CALCULATED') > -1) {
field.isCalculated = true;
field.placeholder = 'has calculated default value';
} else if (field.defaultValue['@RESOURCE']) {
field.isFromResource = true;
}
}
formField = {
label: field.displayName ? field.displayName : field.name,
name: field.name,
type: field.type,
typeInfo: field['@TYPEINFO'],
description: field.description,
required: field.required,
value: (field.isCalculated || field.isFromResource) ? undefined : field.defaultValue,
defaultValue: field.defaultValue,
conditional: field.conditional,
isRef: field.isRef,
isBackRef: field.isBackRef,
group: field.group ? field.group : 'general',
isHidden: field.isHidden,
filter: field.filter ? field.filter.label : undefined,
placeholder: field.placeholder,
isCalculated: field.isCalculated,
isFromResource: field.isFromResource,
tag: field.label,
uniquenessCheckedProperties: field['@UNIQUE'] ? field['@UNIQUE'].filterProperties : undefined
};
if (formField.isFromResource) {
let resourcePromise = getResource(formField.defaultValue['@RESOURCE']);
if (resourcePromise) {
resourcePromise
.then((response) => { formField.value = response; })
.catch((error) => Entaxy.log.error(error));
} else {
Core.notification('danger', 'Resource service is not found', 5000);
}
}
if (formField.name === '__entaxyContainerId') {
let selectedMbean = workspace.getSelectedMBean();
jolokiaService.getAttribute(selectedMbean.objectName, 'RuntimeType')
.then((runtimeType) => {
if (runtimeType && runtimeType.startsWith('entaxy.runtime.')) {
formField.value = selectedMbean.title;
}
})
.catch((error) => Entaxy.log.error('There is no runtime type'));
}
}
return formField;
}
function getResource(resourceInfo) {
let resource = workspace.tree.findDescendant(child => {
let childObjectName = child.objectName;
if (childObjectName && childObjectName.endsWith('category=resource')) {
return child;
}
});
if (resource) {
return operationsService.executeOperation(
resource.objectName,
{ name: 'getResource' },
[ resourceInfo.provider + ':' + resourceInfo.location ]
);
}
}
function getArguments(fields, factories) {
let factoryIdName = fields.shift().value;
return args = {
factoryId: factories.find((factory) => factory.name === factoryIdName),
fields: fields.map(field => {
if (field.isFromResource && field.defaultValue['@RESOURCE'].format === 'base64') {
field.value = btoa(field.value);
}
if (field.isInternal) {
field.defaultValue = undefined;
field.value = undefined;
}
return {
name: field.name,
value: (field.defaultValue !== undefined && field.defaultValue === field.value) ? undefined : field.value
};
})
};
}
function validateFields(fields, selectedFactory, itemType) {
let errors = {};
_.forEach(fields, (field) => {
if (field.required && !field.isBackRef && !field.isHidden && !field.isCalculated) {
if (field.value === undefined || (typeof field.value === 'string' ? field.value.trim().length === 0 : false)) {
errors[field.name] = 'Please fill out this field';
}
if ((field.name === 'objectId' || field.name === 'systemName') && !errors[field.name]) {
if (field.value.trim().length < 3) {
errors[field.name] = 'Value must contain at least 3 characters';
}
}
}
if (field.uniquenessCheckedProperties && !errors[field.name]) {
errors[field.name] = checkUniqueness(field.name, field.value, field.uniquenessCheckedProperties, fields, selectedFactory, itemType);
}
});
let deferred = $q.defer();
if (Object.keys(errors).length !== 0) {
let errorArrayWithPromises = [];
Object.keys(errors).forEach(key => {
if (typeof errors[key] !== 'string') {
errorArrayWithPromises.push({ name: key, promise: errors[key] });
}
});
if (errorArrayWithPromises.length !== 0) {
$q.all(errorArrayWithPromises.map(obj => { return obj.promise; }))
.then(result => {
for (let i = 0; i < errorArrayWithPromises.length; i++) {
if (result[i]) {
errors[errorArrayWithPromises[i].name] = result[i];
} else {
delete errors[errorArrayWithPromises[i].name];
}
}
deferred.resolve(errors);
});
} else {
deferred.resolve(errors);
}
} else {
deferred.resolve(errors);
}
return deferred.promise;
}
function checkUniqueness(fieldName, fieldValue, properties, fields, selectedFactory, itemType) {
let message = 'Value must be unique';
let isInvalid = false;
let promises = [];
properties.unshift(fieldName);
properties = properties.map(property => {
return Entaxy.capitalize(property);
});
properties.unshift('RuntimeType');
let selectedMbean = workspace.getSelectedMBean();
if (selectedMbean && selectedMbean.isFolder) {
let children = Entaxy.getChildrenRecursive(selectedMbean);
let childrenMbeanNames = children
.map(child => { return child.objectName; })
.filter(child => child !== null);
childrenMbeanNames.forEach(mbeanName => {
promises.push(jolokiaService.getAttributes(mbeanName, properties)
.then((response) => {
if (response[properties[0]] === 'entaxy.runtime.' + itemType.toLowerCase()
&& fieldValue === response[properties[1]]) {
for (let i = 2; i < properties.length; i++) {
let checkedField = fields.find(field => field.name === Entaxy.uncapitalize(properties[i]));
if (checkedField) {
if (checkedField.value === response[properties[i]]) {
isInvalid = true;
}
} else {
return jolokiaService.getAttribute(selectedFactory.mbeanName, 'TypeInfo')
.then((typeInfo) => {
let typeInfoDesiredValue = typeInfo[Entaxy.uncapitalize(properties[i])];
if (typeInfoDesiredValue === response[properties[i]]) {
isInvalid = true;
}
});
}
}
}
}));
});
}
return $q.all(promises).then(() => isInvalid ? message : '');
}
}
])
})(Entaxy || (Entaxy = {}));

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;

View File

@ -0,0 +1,59 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module.factory('entaxyLegacyConnectorService', ['$uibModal',
function($uibModal) {
return {
openAddLegacyConnectorModal: function (resolve) {
return openAddLegacyConnectorModal(resolve);
},
getArguments: function (connectorArgs) {
return getArguments(connectorArgs);
}
};
function openAddLegacyConnectorModal(resolve) {
return $uibModal.open({
component: 'entaxyAddConnectorModal',
resolve: resolve,
size: 'lg',
backdrop: 'static'
}).result;
}
function getArguments(connectorArgs) {
let args = [];
args.push(connectorArgs.connectorTemplateName);
let argParams = connectorArgs.connectorFields.reduce((obj, cur) =>
({ ...obj, [cur.label] : (typeof cur.value === 'string') ? cur.value : JSON.stringify(cur.value) }), {});
args.push(argParams);
return args;
}
}
])
})(Entaxy || (Entaxy = {}));

View File

@ -0,0 +1,821 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-management-plugin
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;
(function (Entaxy) {
Entaxy._module.factory('entaxyService', ['$q', 'workspace', 'jolokia', 'jolokiaService', 'operationsService', '$uibModal',
function($q, workspace, jolokia, jolokiaService, operationsService, $uibModal) {
return {
getDomainFolder: function () {
return getDomainFolder();
},
makeFormField: function (field, objectId, properties, mode, profileName) {
return makeFormField(field, objectId, properties, mode, profileName);
},
getArguments: function (fields, factories) {
return getArguments(fields, factories);
},
getDependentFormFields: function (formFields) {
return getDependentFormFields(formFields);
},
getDefiningFormFields: function (dependentFormFields, formFields) {
return getDefiningFormFields(dependentFormFields, formFields);
},
processDependencies: function (dependentFormFields, definingFormFields, currentDefiningFormFieldName, newValue, oldValue) {
return processDependencies(dependentFormFields, definingFormFields, currentDefiningFormFieldName, newValue, oldValue);
},
validateFields: function (fields, selectedFactory, itemType, profileMBeanName) {
return validateFields(fields, selectedFactory, itemType, profileMBeanName);
},
openAddItemModalAndProcessResults: function (resolve, updateFn) {
return openAddItemModalAndProcessResults(resolve, updateFn);
},
openEditItemModalAndProcessResults: function (mbeanName, itemType, itemName, mode) {
return openEditItemModalAndProcessResults(mbeanName, itemType, itemName, mode);
},
requestConfirmationForSavingIfNeededAndProceed: function (isConfirmationNeeded, saveFn) {
return requestConfirmationForSavingIfNeededAndProceed(isConfirmationNeeded, saveFn);
},
saveItem: function (args, updateFn) {
return saveItem(args, updateFn);
},
processTableOperation: function (mbeanName, operation, selectedItemName, updateTableFn) {
return processTableOperation(mbeanName, operation, selectedItemName, updateTableFn);
},
getAllChildMBeansByRuntimeType: function (folder, runtimeType) {
return getAllChildMBeansByRuntimeType(folder, runtimeType);
},
openConfirmationWindow: function (title, message) {
return openConfirmationWindow(title, message);
},
getActiveTabIndex: function () {
return getActiveTabIndex();
},
updateTabSelection: function (targetTabIndex) {
return updateTabSelection(targetTabIndex);
}
};
function getDomainFolder() {
let entaxyJmxDomain = localStorage['entaxyJmxDomain'] || "ru.entaxy.esb";
return workspace.tree.get(entaxyJmxDomain);
}
function makeFormField(field, objectId, properties, mode, profileName) {
let formField;
if (field['@TYPEINFO']) {
if (field['@TYPEINFO'].dependsOn) {
field.dependsOn = field['@TYPEINFO'].dependsOn;
delete field['@TYPEINFO'].dependsOn;
}
if (field['@TYPEINFO'].validation) {
field.validation = field['@TYPEINFO'].validation;
delete field['@TYPEINFO'].validation;
}
if (Object.keys(field['@TYPEINFO']).length == 0) {
field['@TYPEINFO'] = undefined;
}
}
if (field['@TYPEINFO'] && mode !== Entaxy.MODAL_MODES.VIEW && field['@TYPEINFO'].type === 'enum' && field.required) {
field['@TYPEINFO'].isEmptyIncluded = field['@TYPEINFO'].values.length == 1 ? false : undefined;
}
if (mode !== Entaxy.MODAL_MODES.ADD) {
if (field.name === 'objectId') {
field.value = objectId;
}
let suitableProperty = properties.find(property => property.name === field.name);
if (suitableProperty) {
if (field.type.startsWith('entaxy.runtime.') && field.immutable) {
field.type = 'string';
if (field['@TYPEINFO']) {
delete field['@TYPEINFO'];
}
}
if (field.defaultValue && field.defaultValue['@RESOURCE'] && field.defaultValue['@RESOURCE'].format === 'base64') {
suitableProperty.value = atob(suitableProperty.value);
}
field.value = suitableProperty.value;
}
if (!field.isHidden && field.defaultValue !== undefined && field.value === undefined) {
field.displayName = field.displayName ? ('* ' + field.displayName) : ('* ' + field.name);
}
if (field['@FACADE'] && field['@FACADE'].useFacade) {
field.type = field['@FACADE'].type;
field.value = field['@FACADE'].value;
field.defaultValue = undefined;
field.immutable = true;
}
if (field['@INTERNAL'] === true || (field.isHidden && field.defaultValue && field.value)) {
formField = undefined;
} else {
formField = {
label: field.displayName ? field.displayName : field.name,
name: field.name,
type: field.type,
description: field.description,
value: field.value !== undefined ? field.value : field.defaultValue,
isRef: field.isRef,
isBackRef: field.isBackRef,
isHidden: field.isHidden,
group: field.group ? field.group : 'general',
tag: field.label,
readOnly: mode === Entaxy.MODAL_MODES.VIEW ? true : field.immutable,
required: mode === Entaxy.MODAL_MODES.EDIT ? field.required : undefined,
typeInfo: mode === Entaxy.MODAL_MODES.EDIT ? field['@TYPEINFO'] : undefined,
isFromResource: field.defaultValue && field.defaultValue['@RESOURCE'],
defaultValue: field.defaultValue,
useFacade: (field['@FACADE'] && field['@FACADE'].useFacade) ? field['@FACADE'].useFacade : undefined,
dependsOn: field.dependsOn,
validation: field.validation
};
}
} else {
if (field.defaultValue) {
if (field.defaultValue['@RESOURCE']) {
field.isFromResource = true;
} else if (JSON.stringify(field.defaultValue).indexOf('@CALCULATED') > -1) {
field.isCalculated = true;
field.placeholder = 'has calculated default value';
}
}
formField = {
label: field.displayName ? field.displayName : field.name,
name: field.name,
type: field.type,
typeInfo: field['@TYPEINFO'],
description: field.description,
required: field.required,
value: (field.isCalculated || field.isFromResource) ? undefined : field.defaultValue,
defaultValue: field.defaultValue,
conditional: field.conditional,
isRef: field.isRef,
isBackRef: field.isBackRef,
group: field.group ? field.group : 'general',
isHidden: field.isHidden,
filter: field.filter ? field.filter.label : undefined,
placeholder: field.placeholder,
isCalculated: field.isCalculated,
isFromResource: field.isFromResource,
tag: field.label,
uniquenessCheckedProperties: field['@UNIQUE'] ? field['@UNIQUE'].filterProperties : undefined,
dependsOn: field.dependsOn,
validation: field.validation
};
if (formField.isFromResource && !formField.dependsOn) {
let resourcePromise = getResource(getLocationFromResourceInfo(formField.defaultValue['@RESOURCE']));
if (resourcePromise) {
resourcePromise
.then((response) => { formField.value = response; })
.catch((error) => {
Core.notification('danger', 'An error occurred while loading the resource', 5000);
Entaxy.log.error(error);
});
} else {
Core.notification('danger', 'Resource service is not found', 5000);
}
}
if (formField.name === '__entaxyContainerId') {
if (profileName) {
formField.value = profileName;
} else {
let selectedMbean = workspace.getSelectedMBean();
jolokiaService.getAttributes(selectedMbean.objectName, ['RuntimeType', 'Name'])
.then((response) => {
if (!response['RuntimeType'] || response['RuntimeType'].startsWith('ERROR')) {
Entaxy.log.error('There is no runtime type')
} else {
formField.value = response['Name'];
}
});
}
}
}
return formField;
}
function getResource(location) {
return executeOperationOnResource('getResource', [location]);
}
function getResourceMetadata(location) {
return executeOperationOnResource('getResourceMetadata', [location]);
}
function executeOperationOnResource(operationName, properties) {
let resourceObjectName = getResourceCategoryObjectName();
if (resourceObjectName) {
return operationsService.executeOperation(
resourceObjectName,
{ name: operationName },
properties
);
}
}
function getLocationFromResourceInfo(resourceInfo) {
return resourceInfo.provider + ':' + resourceInfo.location;
}
function getResourceCategoryObjectName() {
let resource = getDomainFolder().findDescendant(child => {
let childObjectName = child.objectName;
if (childObjectName && childObjectName.endsWith('category=resource')) {
return child;
}
});
return resource ? resource.objectName : undefined;
}
function getArguments(fields, factories) {
let factoryIdName = fields.shift().value;
return args = {
factoryId: factories.find((factory) => factory.name === factoryIdName),
fields: fields.map(field => {
if (field.isFromResource && field.defaultValue['@RESOURCE'].format === 'base64') {
field.value = btoa(field.value);
}
if (field.useFacade) {
delete field.defaultValue;
delete field.value;
}
if (field.validation && field.validation.doFix === true && field.value) {
field.value = fixFromRules(field.validation.fixRules, field.value);
}
if (!field.required && typeof field.value === 'string' && field.value.trim().length === 0) {
delete field.value;
}
return {
name: field.name,
value: (field.defaultValue !== undefined && field.defaultValue === field.value) ? undefined : field.value
};
})
};
}
function fixFromRules(rules, value) {
rules.forEach((rule) => {
if (rule.forbid) {
let symbols = rule.forbid.symbols;
if (symbols) {
angular.forEach(symbols, (symbol) => {
if (rule.forbid.start === true && value.startsWith(symbol)) {
value = value.substring(1, value.length);
}
});
}
}
});
return value;
}
function getDependentFormFields(formFields) {
let dependentFormFields = formFields.filter(formField => formField.dependsOn);
dependentFormFields.forEach(formField => {
formField.readOnly = (formField.typeInfo && formField.typeInfo.type !== 'String') ? true : undefined;
});
return dependentFormFields;
}
function getDefiningFormFields(dependentFormFields, formFields) {
let listOfDefiningNames = dependentFormFields.map(field => field.dependsOn);
let definingNames = [];
listOfDefiningNames.forEach(names => { definingNames = definingNames.concat(names); });
definingNames = [...(new Set(definingNames))];
return formFields.filter(formField => definingNames.includes(formField.name));
}
function processDependencies(dependentFormFields, definingFormFields, currentDefiningFormFieldName, newValue, oldValue, index) {
if (oldValue) {
dependentFormFields.forEach(formField => {
if (formField.dependsOn.includes(currentDefiningFormFieldName)) {
formField.readyToCompute = false;
if (formField.typeInfo.type !== 'String') {
formField.readOnly = true;
}
if (formField.typeInfo && formField.typeInfo.type === 'list') {
formField.typeInfo.values = undefined;
formField.typeInfo.isEmptyIncluded = undefined;
}
formField.value = undefined;
}
});
}
if (newValue) {
dependentFormFields.forEach(formField => {
if (formField.dependsOn.includes(currentDefiningFormFieldName)) {
let readyToCompute = true;
formField.dependsOn.forEach(name => {
if (!definingFormFields.find(field => field.name === name).value) {
readyToCompute = false;
}
});
formField.readyToCompute = readyToCompute;
if (formField.typeInfo.type !== 'String') {
formField.readOnly = !readyToCompute;
}
if (formField.readyToCompute) {
if (formField.typeInfo && (formField.typeInfo.type === 'list' || formField.typeInfo.type === 'String')) {
let sourcePropertyName = formField.typeInfo.source.property;
let sourceType = formField.typeInfo.source.sourceType;
let sourcePath = formField.typeInfo.source.path;
// we assume that if the source type is resource
// then source property contains its location
if (sourceType === 'resource') {
let promise = computeResourcePropertyValue(sourcePropertyName, sourcePath, definingFormFields);
if (promise) {
promise
.then(result => {
if (formField.typeInfo.type === 'list') {
formField.typeInfo.values = result;
if (formField.required) {
formField.typeInfo.isEmptyIncluded = (result.length == 1) ? false : undefined;
}
} else if (formField.typeInfo.type === 'String') {
formField.value = result;
}
})
.catch((error) => {
Core.notification('danger', error, 5000);
Entaxy.log.error(error);
});
}
}
} else if (formField.type === 'xml:route') {
let resourceProvider = formField.defaultValue['@RESOURCE'].provider;
let resourceLocation = formField.typeInfo.location;
let splitResourceLocation = resourceLocation.split('/');
let regex = /\${[\w#.-]+}/g;
for (let i = 0; i < splitResourceLocation.length; i++) {
if (splitResourceLocation[i].match(regex)) {
let property = splitResourceLocation[i].substring(2, splitResourceLocation[i].length - 1);
if (formField.typeInfo[property]) {
let sourcePropertyName = formField.typeInfo[property].property;
let sourceType = formField.typeInfo[property].sourceType;
let sourcePath = formField.typeInfo[property].path;
// we assume that if the source type is resource
// then source property contains its location
if (sourceType === 'resource') {
splitResourceLocation[i] = { promise: computeResourcePropertyValue(sourcePropertyName, sourcePath, definingFormFields) };
}
} else {
splitResourceLocation[i] = definingFormFields.find(field => field.name === property).value;
}
}
}
let promises = splitResourceLocation
.filter(chunk => chunk.promise)
.map(chunk => chunk.promise);
$q.all(promises)
.then(results => {
results.forEach(result => {
let index = splitResourceLocation.findIndex(chunk => chunk.promise);
splitResourceLocation[index] = result;
});
let computedResourceLocation = splitResourceLocation.join('/');
let promise = getResource(resourceProvider + ':' + computedResourceLocation);
if (promise) {
promise
.then(response => { formField.value = response; })
.catch((error) => {
Core.notification('danger', 'An error occurred while loading the resource', 5000);
Entaxy.log.error(error);
});;
} else {
Core.notification('danger', 'Resource service is not found', 5000);
}
})
.catch((error) => {
Core.notification('danger', error, 5000);
Entaxy.log.error(error);
});
}
}
}
});
}
}
function computeResourcePropertyValue(sourcePropertyName, sourcePath, definingFormFields) {
let deferred = $q.defer();
let splitSourcePath = sourcePath.split('.');
let sourcePropertyValue = definingFormFields.find(field => field.name === sourcePropertyName).value;
// for now we assume there is always #metadata#
if (splitSourcePath[0] === '#metadata#') {
let promise = getResourceMetadata(sourcePropertyValue);
if (promise) {
promise
.then(response => {
let metadata = JSON.parse(response);
let section = JSON.parse(metadata[splitSourcePath[1]]);
let regex = /\${[\w#.-]+}/g;
let result = section;
for (let i = 2; i < splitSourcePath.length; i++) {
if (!splitSourcePath[i].match(regex)) {
result = result[splitSourcePath[i]];
} else {
let fieldName = splitSourcePath[i].substring(2, splitSourcePath[i].length - 1);
let value = definingFormFields.find(field => field.name === fieldName).value;
result = result[value];
}
}
deferred.resolve(result);
});
} else {
deferred.reject('Resource service is not found');
}
}
return deferred.promise;
}
function validateFields(fields, selectedFactory, itemType, profileMBeanName) {
let errors = {};
_.forEach(fields, (field) => {
if (!field.isBackRef && !field.isHidden && !field.isCalculated) {
if (field.required && (field.value === undefined ||
(typeof field.value === 'string' ? field.value.trim().length === 0 : false))) {
errors[field.name] = 'Please fill out this field';
}
if (!errors[field.name] && field.validation && field.validation.rules) {
validateByRules(field, field.validation.rules, errors);
}
}
if (field.uniquenessCheckedProperties && !errors[field.name]) {
errors[field.name] = checkUniqueness(field.name, field.value, field.uniquenessCheckedProperties,
fields, selectedFactory, itemType, profileMBeanName);
}
});
let deferred = $q.defer();
if (Object.keys(errors).length !== 0) {
let errorArrayWithPromises = [];
Object.keys(errors).forEach(key => {
if (typeof errors[key] !== 'string') {
errorArrayWithPromises.push({ name: key, promise: errors[key] });
}
});
if (errorArrayWithPromises.length !== 0) {
$q.all(errorArrayWithPromises.map(obj => { return obj.promise; }))
.then(result => {
for (let i = 0; i < errorArrayWithPromises.length; i++) {
if (result[i]) {
errors[errorArrayWithPromises[i].name] = result[i];
} else {
delete errors[errorArrayWithPromises[i].name];
}
}
deferred.resolve(errors);
});
} else {
deferred.resolve(errors);
}
} else {
deferred.resolve(errors);
}
return deferred.promise;
}
function validateByRules(field, rules, errors) {
for (let i = 0; i < rules.length; i++) {
validateByRule(field, rules[i], errors);
if (errors[field.name]) {
break;
}
}
}
function validateByRule(field, rule, errors) {
if (rule.length) {
if (rule.length.min) {
if (field.value.trim().length < rule.length.min) {
errors[field.name] = 'Value must contain at least ' + rule.length.min + ' characters';
}
} else if (rule.length.max) {
if (field.value.trim().length > rule.length.max) {
errors[field.name] = 'Value must not contain greater then ' + rule.length.max + ' characters';
}
}
} else if (rule.content) {
if (rule.content.regex) {
let regex = new RegExp(rule.content.regex);
if (!field.value.match(regex)) {
errors[field.name] = rule.content.errorMessage ?
rule.content.errorMessage : 'Value contains invalid characters';
}
}
}
}
function checkUniqueness(fieldName, fieldValue, properties, fields, selectedFactory, itemType, profileMBeanName) {
let message = 'Value must be unique';
let isInvalid = false;
let promises = [];
properties.unshift(fieldName);
properties = properties.map(property => {
return Entaxy.capitalize(property);
});
let profileMBean;
if (profileMBeanName) {
profileMBean = getDomainFolder().findDescendant(child => child.objectName === profileMBeanName);
} else {
profileMBean = workspace.getSelectedMBean();
}
if (profileMBean && profileMBean.isFolder) {
let children = getAllChildMBeansByRuntimeType(profileMBean, 'entaxy.runtime.' + itemType.toLowerCase());
let childrenMbeanNames = children
.map(child => { return child.objectName; })
.filter(child => child !== null);
childrenMbeanNames.forEach(mbeanName => {
promises.push(jolokiaService.getAttributes(mbeanName, properties)
.then((response) => {
if (fieldValue === response[properties[0]]) {
for (let i = 1; i < properties.length; i++) {
let checkedField = fields.find(field => field.name === Entaxy.uncapitalize(properties[i]));
if (checkedField) {
if (checkedField.value === response[properties[i]]) {
isInvalid = true;
}
} else {
return jolokiaService.getAttribute(selectedFactory.mbeanName, 'TypeInfo')
.then((typeInfo) => {
let typeInfoDesiredValue = typeInfo[Entaxy.uncapitalize(properties[i])];
if (typeInfoDesiredValue === response[properties[i]]) {
isInvalid = true;
}
});
}
}
}
}));
});
}
return $q.all(promises).then(() => isInvalid ? message : '');
}
function openAddItemModalAndProcessResults(resolve, updateFn) {
let factories = [];
let promises = [];
let factoryFolder = getDomainFolder()
.findDescendant(child => child.title === 'entaxy.runtime.' + resolve.itemType().toLowerCase());
if (factoryFolder && factoryFolder.children) {
factoryFolder.children.forEach((child) => {
promises.push(jolokiaService.getAttributes(child.objectName, ['Abstract', 'DisplayName', 'Label', 'Description', 'Deprecated'])
.then((result) => {
if (!result['Abstract']) {
factories.push({
name: child.title,
displayName: result['DisplayName'] ? result['DisplayName'] : child.title,
label: result['Label'],
mbeanName: child.objectName,
description: result['Description'] ? result['Description'] : 'There is no description for this factory.',
additionalInfo: result['Deprecated'] ? ['[DEPRECATED]'] : undefined
});
}
}));
});
$q.all(promises).then(() => {
resolve.factories = () => factories;
openModalAndProcessResults(resolve, updateFn);
});
}
}
function openEditItemModalAndProcessResults(mbeanName, itemType, itemName, mode) {
let factoryFolder = getDomainFolder()
.findDescendant(child => child.title === 'entaxy.runtime.' + itemType.toLowerCase());
operationsService
.executeOperation(mbeanName, { name: 'get' + itemType + 'Config' }, [ itemName ])
.then(result => {
let itemInfo = JSON.parse(result);
let factory = factoryFolder.children.find(child => child.title === itemInfo.factoryId);
factory = { name: factory.title, mbeanName: factory.objectName };
openModalAndProcessResults({
itemName: () => itemName,
itemType: () => itemType,
mode: () => mode,
info: () => itemInfo,
factories: () => [ factory ]
});
}).catch(error => {
Core.notification('danger', 'Unable to view configuration of selected item.', 5000);
Entaxy.log.error(error);
});
}
function openModalAndProcessResults(resolve, updateFn) {
openEntaxyModal(resolve)
.then(args => {
saveItem(args, updateFn);
},
reason => {
if (reason) {
Core.notification('danger', reason, 5000);
}
});
}
function openEntaxyModal(resolve) {
return $uibModal.open({
component: 'entaxyModal',
resolve: resolve,
size: 'xl',
backdrop: 'static'
}).result;
}
function requestConfirmationForSavingIfNeededAndProceed(isConfirmationNeeded, saveFn) {
if (isConfirmationNeeded) {
let title = 'Confirm Saving';
let message = 'There are no changes to this object. ' +
'Do you want to continue and recreate object with the same properties?';
openConfirmationWindow(title, message).then(() => {
saveFn();
});
} else {
saveFn();
}
}
function saveItem(args, updateFn) {
let objectId = args.fields.find((field) => field.name === 'objectId').value;
let fields = objectId ? args.fields.filter((field) => field.name !== 'objectId') : args.fields;
let mbeanName = args.factoryId.mbeanName;
let properties = fields.reduce((obj, cur) => ({ ...obj, [cur.name] : cur.value }), {});
let instructions = {"@LIFECYCLE":["general"]};
operationsService.executeOperation(mbeanName, { name: 'createObjectByInstructions' }, [ objectId, 'public', instructions, properties ] )
.then(result => {
let tableHtml = Entaxy.createTableFromResponse(result);
Entaxy.notification('success', tableHtml, 10000);
if (updateFn) {
updateFn(properties, objectId);
}
}).catch(error => {
Core.notification('danger', error, 5000);
Entaxy.log.error(error);
});
}
function processTableOperation(mbeanName, operation, selectedItemName, updateTableFn) {
operationsService.executeOperation(mbeanName, operation, [ selectedItemName ])
.then(result => {
Core.notification('success', result, 3000);
if (updateTableFn) {
updateTableFn();
}
}).catch(error => {
Core.notification('danger', error, 5000);
Entaxy.log.error(error);
});
}
function getAllChildMBeansByRuntimeType(folder, runtimeType) {
let mbeans = [];
if (folder.children) {
getAllChildMBeansByRuntimeTypeRecursive(folder.children, runtimeType, mbeans);
}
return mbeans;
}
function getAllChildMBeansByRuntimeTypeRecursive(children, runtimeType, mbeans) {
children.forEach(child => {
if (child.objectName) {
let attributes = jolokia.getAttribute(child.objectName);
if (attributes.RuntimeType === runtimeType) {
mbeans.push(child);
}
}
if (child.children) {
getAllChildMBeansByRuntimeTypeRecursive(child.children, runtimeType, mbeans);
}
});
}
function openConfirmationWindow(title, message) {
return $uibModal.open({
component: 'entaxyConfirmationModal',
resolve: {
title: () => title,
message: () => message
},
size: 'sm-custom',
backdrop: 'static',
windowTopClass: 'modal-top-margin-center-override'
}).result;
}
function getActiveTabIndex() {
let hawtioTabs = document.getElementsByClassName("hawtio-tab");
for (let i = 0; i < hawtioTabs.length; i++) {
if (hawtioTabs[i].classList.contains('active')) {
return i;
}
}
return -1;
}
function updateTabSelection(targetTabIndex) {
let currentActiveTabIndex = getActiveTabIndex();
if (targetTabIndex !== currentActiveTabIndex) {
document.getElementsByClassName("hawtio-tab")[targetTabIndex].children[0].click();
}
}
}
])
})(Entaxy || (Entaxy = {}));

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;

View File

@ -4,17 +4,23 @@
* ==========
* Copyright (C) 2020 - 2023 EmDev LLC
* ==========
* 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
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* http://www.apache.org/licenses/LICENSE-2.0
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* 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.
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
var Entaxy;