KNOX-1276 - Improve HA provider configuration wizard
Project: http://git-wip-us.apache.org/repos/asf/knox/repo Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/f36f6591 Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/f36f6591 Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/f36f6591 Branch: refs/heads/master Commit: f36f65911bcb33953d34f88bf8add9895cedee63 Parents: 31e8dc0 Author: Phil Zampino <pzamp...@apache.org> Authored: Tue Apr 24 15:22:59 2018 -0400 Committer: Phil Zampino <pzamp...@apache.org> Committed: Tue Apr 24 15:26:57 2018 -0400 ---------------------------------------------------------------------- .../ProviderContributorWizard.ts | 32 ++++++++ .../ha-provider-config.ts | 85 ++++++++++++++++++++ .../src/app/provider-config-wizard/ha-wizard.ts | 49 ++++++++--- .../provider-config-wizard.component.ts | 46 ++++++++++- .../applications/admin-ui/app/index.html | 2 +- .../app/inline.16974ba5282691a55526.bundle.js | 1 - .../app/inline.45a383ca05ad5b8aeba5.bundle.js | 1 + .../app/main.5a33727bde77ca75fd8c.bundle.js | 1 + .../app/main.99134704228150aa98b5.bundle.js | 1 - 9 files changed, 203 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/knox/blob/f36f6591/gateway-admin-ui/src/app/provider-config-wizard/ProviderContributorWizard.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/ProviderContributorWizard.ts b/gateway-admin-ui/src/app/provider-config-wizard/ProviderContributorWizard.ts new file mode 100644 index 0000000..957d8c4 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/ProviderContributorWizard.ts @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import {ProviderConfig} from "../resource-detail/provider-config"; + +export interface ProviderContributorWizard { + + // Returns the type of provider to which the implementation contributes + getProviderRole() : string; + + // Contribute the wizard state to the specified provider + contribute(providerConfig: ProviderConfig); + + // Create a new ProviderConfig of the type to which the implementation can contribute + createNewProviderConfig(): ProviderConfig; + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/f36f6591/gateway-admin-ui/src/app/provider-config-wizard/ha-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/ha-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/ha-provider-config.ts new file mode 100644 index 0000000..3ae31d9 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/ha-provider-config.ts @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {ValidationUtils} from "../utils/validation-utils"; +import {DisplayBindingProviderConfig} from "./display-binding-provider-config"; + +export class HaProviderConfig extends DisplayBindingProviderConfig { + + public static TYPE: string = 'HaProvider'; + + public static SERVICE_NAME = 'Service Name'; + public static MAX_FAILOVER_ATTEMPTS = 'Failover Atttempts Limit'; + public static FAILOVER_SLEEP = 'Failover Interval'; + public static MAX_RETRY_ATTEMPTS = 'Retry Attempts Limit'; + public static RETRY_SLEEP = 'Retry Interval'; + + private static displayPropertyNames = [ HaProviderConfig.SERVICE_NAME, + HaProviderConfig.MAX_FAILOVER_ATTEMPTS, + HaProviderConfig.FAILOVER_SLEEP, + HaProviderConfig.MAX_RETRY_ATTEMPTS, + HaProviderConfig.RETRY_SLEEP + ]; + + private static displayPropertyNameBindings: Map<string, string> = + new Map([ + [HaProviderConfig.SERVICE_NAME, 'serviceName'], + [HaProviderConfig.MAX_FAILOVER_ATTEMPTS, 'maxFailoverAttempts'], + [HaProviderConfig.FAILOVER_SLEEP, 'failoverSleep'], + [HaProviderConfig.MAX_RETRY_ATTEMPTS, 'maxRetryAttempts'], + [HaProviderConfig.RETRY_SLEEP, 'retrySleep'] + ] as [string, string][]); + + constructor() { + super(); + this.name = HaProviderConfig.TYPE; + } + + getDisplayPropertyNames(): string[] { + return HaProviderConfig.displayPropertyNames; + } + + getDisplayNamePropertyBinding(name: string): string { + return HaProviderConfig.displayPropertyNameBindings.get(name); + } + + getType(): string { + return HaProviderConfig.TYPE; + } + + isValidParamValue(paramName: string): boolean { + let isValid: boolean = true; + + let value = this.getParam(this.getDisplayNamePropertyBinding(paramName)); + if (value) { + switch (paramName) { + case HaProviderConfig.SERVICE_NAME: + isValid = ValidationUtils.isValidString(value) && !ValidationUtils.isValidNumber(value); + break; + default: + isValid = ValidationUtils.isValidNumber(value); + if (!isValid) { + console.debug(paramName + ' value is not valid.'); + } + } + } + + return isValid; + } + +} + http://git-wip-us.apache.org/repos/asf/knox/blob/f36f6591/gateway-admin-ui/src/app/provider-config-wizard/ha-wizard.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/ha-wizard.ts b/gateway-admin-ui/src/app/provider-config-wizard/ha-wizard.ts index df742bb..e2afbf7 100644 --- a/gateway-admin-ui/src/app/provider-config-wizard/ha-wizard.ts +++ b/gateway-admin-ui/src/app/provider-config-wizard/ha-wizard.ts @@ -17,13 +17,18 @@ import {CategoryWizard} from "./category-wizard"; import {ProviderConfig} from "../resource-detail/provider-config"; +import {ProviderContributorWizard} from "./ProviderContributorWizard"; +import {HaProviderConfig} from "./ha-provider-config"; +import {DisplayBindingProviderConfig} from "./display-binding-provider-config"; -export class HaWizard extends CategoryWizard { +export class HaWizard extends CategoryWizard implements ProviderContributorWizard { - private stepCount: number = 2; + private static DEFAULT_TYPE: string = HaProviderConfig.TYPE; + + private stepCount: number = 4; getTypes(): string[] { - return []; + return [HaWizard.DEFAULT_TYPE]; } getSteps(): number { @@ -31,16 +36,40 @@ export class HaWizard extends CategoryWizard { } onChange() { - // Nothing to do + this.providerConfig = this.createNewProviderConfig(); } getProviderConfig(): ProviderConfig { - this.providerConfig = new ProviderConfig(); - this.providerConfig.role = 'ha'; - this.providerConfig.name = 'HaProvider'; - this.providerConfig.enabled = 'true'; - this.providerConfig.params = new Map<string, string>(); - return this.providerConfig; + return (this.providerConfig as HaProviderConfig); + } + + getProviderRole(): string { + return this.providerConfig.role; + } + + createNewProviderConfig(): ProviderConfig { + let pc = new HaProviderConfig(); + pc.role = 'ha'; +// pc.name = HaProviderConfig.TYPE; // TODO: PJZ: DELETE ME + pc.enabled = 'true'; + pc.params = new Map<string, string>(); + return (pc as HaProviderConfig); + } + + contribute(target: ProviderConfig) { + let svcNameProperty = + (this.providerConfig as DisplayBindingProviderConfig).getDisplayNamePropertyBinding(HaProviderConfig.SERVICE_NAME); + let serviceName = (this.providerConfig as DisplayBindingProviderConfig).getParam(svcNameProperty); + + let paramValue: string = "enabled=true"; + + for (let propertyName in this.providerConfig.params) { + if (propertyName !== svcNameProperty) { + paramValue += ',' +propertyName + '=' + (this.providerConfig as DisplayBindingProviderConfig).getParam(propertyName); + } + } + + (target as DisplayBindingProviderConfig).setParam(serviceName, paramValue); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/f36f6591/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.ts b/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.ts index 6985355..0504707 100644 --- a/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.ts +++ b/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.ts @@ -29,6 +29,7 @@ import {Resource} from "../resource/resource"; import {DisplayBindingProviderConfig} from "./display-binding-provider-config"; import {OrderedParamContainer} from "./ordered-param-container"; import {HostMapProviderWizard} from "./hostmap-provider-wizard"; +import {ProviderContributorWizard} from "./ProviderContributorWizard"; @Component({ @@ -106,9 +107,45 @@ export class ProviderConfigWizardComponent implements OnInit { console.debug('ProviderConfigWizard --> Selected provider type: ' + type); if (catWizard) { - let pc: ProviderConfig = catWizard.getProviderConfig(); + let pc: ProviderConfig; + + let isContributed: boolean = false; + + if (this.isProviderContributorWizard(catWizard)) { + let contribWiz = catWizard as ProviderContributorWizard; + let role = contribWiz.getProviderRole(); + console.debug('Wizard is ProviderContributorWizard for role ' + role); + for (let provider of this.providers) { + if (role === provider.role) { + console.debug('Found existing provider config for ' + role); + pc = provider; + break; + } + } + + if (!pc) { + console.debug('No existing provider config found for ' + role + ", so creating one..."); + pc = contribWiz.createNewProviderConfig(); + this.providers.push(pc); + } + + // If there is an existing provider config of the current type + if (pc) { + if (this.isProviderConfigValid(catWizard.getProviderConfig())) { + contribWiz.contribute(pc); + isContributed = true; + } + } + } + + if (!pc) { // If not a contributing wizard, just use the category wizard's provider config + pc = catWizard.getProviderConfig(); + } + if (pc && this.isProviderConfigValid(pc)) { - this.providers.push(pc); + if (!isContributed) { + this.providers.push(pc); + } console.debug('ProviderConfigWizard --> Provider: name=' + pc.name + ', role=' + pc.role + ', enabled=' + pc.enabled); if (pc.params) { // If the provider is managing its own param order, allow it to re-order the params now @@ -220,6 +257,11 @@ export class ProviderConfigWizardComponent implements OnInit { return ProviderConfigWizardComponent.CATEGORY_TYPES.get(category ? category : this.selectedCategory); } + // Type guard function to determine if a CategoryWizard is a ProviderContributorWizard + isProviderContributorWizard(wizard: any): wizard is ProviderContributorWizard { + return (<ProviderContributorWizard>wizard).getProviderRole !== undefined; + } + getProviderTypes(category?: string) : string[] { let catWizard = this.getCategoryWizard(category); if (catWizard) { http://git-wip-us.apache.org/repos/asf/knox/blob/f36f6591/gateway-applications/src/main/resources/applications/admin-ui/app/index.html ---------------------------------------------------------------------- diff --git a/gateway-applications/src/main/resources/applications/admin-ui/app/index.html b/gateway-applications/src/main/resources/applications/admin-ui/app/index.html index dd4572e..368348e 100644 --- a/gateway-applications/src/main/resources/applications/admin-ui/app/index.html +++ b/gateway-applications/src/main/resources/applications/admin-ui/app/index.html @@ -11,4 +11,4 @@ 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. ---><!doctype html><html><head><meta charset="utf-8"><title>Apache Knox Manager</title><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" type="image/x-icon" href="favicon.ico"><meta name="viewport" content="width=device-width,initial-scale=1"><!-- Latest compiled and minified CSS --><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"><!-- Optional theme --><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"><!-- Custom styles for this template --><link href="assets/sticky-footer.css" rel="stylesheet"><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script><!-- Latest compiled and minified JavaScript --><scr ipt src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script><script src="assets/vkbeautify.js"></script><link href="styles.2ee5b7f4cd59a6cf015e.bundle.css" rel="stylesheet"/></head><body><div class="navbar-wrapper"><div class="container-fluid"><nav class="navbar navbar-inverse navbar-static-top"><div class="container-fluid"><div class="navbar-header"><button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"><span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span></button> <a class="navbar-brand" href="#"><img style="max-width:200px; margin-top: -9px;" src="assets/knox-logo-transparent.gif" alt="Apache Knox Manager"></a></div></div></nav></div><!-- Content --><resource-management></res ource-management><footer class="footer"><div class="container-fluid"><div>Knox Manager Version 1.0.0</div><gateway-version></gateway-version></div></footer><script type="text/javascript" src="inline.16974ba5282691a55526.bundle.js"></script><script type="text/javascript" src="scripts.c50bb762c438ae0f8842.bundle.js"></script><script type="text/javascript" src="main.99134704228150aa98b5.bundle.js"></script></div></body></html> \ No newline at end of file +--><!doctype html><html><head><meta charset="utf-8"><title>Apache Knox Manager</title><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" type="image/x-icon" href="favicon.ico"><meta name="viewport" content="width=device-width,initial-scale=1"><!-- Latest compiled and minified CSS --><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"><!-- Optional theme --><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"><!-- Custom styles for this template --><link href="assets/sticky-footer.css" rel="stylesheet"><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script><!-- Latest compiled and minified JavaScript --><scr ipt src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script><script src="assets/vkbeautify.js"></script><link href="styles.2ee5b7f4cd59a6cf015e.bundle.css" rel="stylesheet"/></head><body><div class="navbar-wrapper"><div class="container-fluid"><nav class="navbar navbar-inverse navbar-static-top"><div class="container-fluid"><div class="navbar-header"><button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"><span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span></button> <a class="navbar-brand" href="#"><img style="max-width:200px; margin-top: -9px;" src="assets/knox-logo-transparent.gif" alt="Apache Knox Manager"></a></div></div></nav></div><!-- Content --><resource-management></res ource-management><footer class="footer"><div class="container-fluid"><div>Knox Manager Version 1.0.0</div><gateway-version></gateway-version></div></footer><script type="text/javascript" src="inline.45a383ca05ad5b8aeba5.bundle.js"></script><script type="text/javascript" src="scripts.c50bb762c438ae0f8842.bundle.js"></script><script type="text/javascript" src="main.5a33727bde77ca75fd8c.bundle.js"></script></div></body></html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/f36f6591/gateway-applications/src/main/resources/applications/admin-ui/app/inline.16974ba5282691a55526.bundle.js ---------------------------------------------------------------------- diff --git a/gateway-applications/src/main/resources/applications/admin-ui/app/inline.16974ba5282691a55526.bundle.js b/gateway-applications/src/main/resources/applications/admin-ui/app/inline.16974ba5282691a55526.bundle.js deleted file mode 100644 index f3ba438..0000000 --- a/gateway-applications/src/main/resources/applications/admin-ui/app/inline.16974ba5282691a55526.bundle.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,a,c){for(var u,i,f,l=0,s=[];l<r.length;l++)t[i=r[l]]&&s.push(t[i][0]),t[i]=0;for(u in a)Object.prototype.hasOwnProperty.call(a,u)&&(e[u]=a[u]);for(n&&n(r,a,c);s.length;)s.shift()();if(c)for(l=0;l<c.length;l++)f=o(o.s=c[l]);return f};var r={},t={2:0};function o(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,o){n=t[e]=[r,o]});n[2]=r;var a=document.getElementsByTagName("head")[0],c=document.createElement("script");c.type="text/javascript",c.charset="utf-8",c.async=!0,c.timeout=12e4,o.nc&&c.setAttribute("nonce",o.nc),c.src=o.p+""+e+"."+{0:"99134704228150aa98b5",1:"aed76669724804835353"}[e]+".chunk.js";var u=setTimeout(i,12e4);function i(){c.onerror=c.onload=null,clearTimeout(u);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chu nk "+e+" failed.")),t[e]=void 0)}return c.onerror=c.onload=i,a.appendChild(c),r},o.m=e,o.c=r,o.d=function(e,n,r){o.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="",o.oe=function(e){throw console.error(e),e}}([]); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/f36f6591/gateway-applications/src/main/resources/applications/admin-ui/app/inline.45a383ca05ad5b8aeba5.bundle.js ---------------------------------------------------------------------- diff --git a/gateway-applications/src/main/resources/applications/admin-ui/app/inline.45a383ca05ad5b8aeba5.bundle.js b/gateway-applications/src/main/resources/applications/admin-ui/app/inline.45a383ca05ad5b8aeba5.bundle.js new file mode 100644 index 0000000..a42746c --- /dev/null +++ b/gateway-applications/src/main/resources/applications/admin-ui/app/inline.45a383ca05ad5b8aeba5.bundle.js @@ -0,0 +1 @@ +!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,c,a){for(var u,i,f,l=0,s=[];l<r.length;l++)t[i=r[l]]&&s.push(t[i][0]),t[i]=0;for(u in c)Object.prototype.hasOwnProperty.call(c,u)&&(e[u]=c[u]);for(n&&n(r,c,a);s.length;)s.shift()();if(a)for(l=0;l<a.length;l++)f=o(o.s=a[l]);return f};var r={},t={2:0};function o(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,o){n=t[e]=[r,o]});n[2]=r;var c=document.getElementsByTagName("head")[0],a=document.createElement("script");a.type="text/javascript",a.charset="utf-8",a.async=!0,a.timeout=12e4,o.nc&&a.setAttribute("nonce",o.nc),a.src=o.p+""+e+"."+{0:"5a33727bde77ca75fd8c",1:"aed76669724804835353"}[e]+".chunk.js";var u=setTimeout(i,12e4);function i(){a.onerror=a.onload=null,clearTimeout(u);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chu nk "+e+" failed.")),t[e]=void 0)}return a.onerror=a.onload=i,c.appendChild(a),r},o.m=e,o.c=r,o.d=function(e,n,r){o.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="",o.oe=function(e){throw console.error(e),e}}([]); \ No newline at end of file