You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by pz...@apache.org on 2019/07/01 18:06:10 UTC

[knox] branch master updated: KNOX-1911 - Support ClouderaManager Service Discovery in Admin UI

This is an automated email from the ASF dual-hosted git repository.

pzampino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git


The following commit(s) were added to refs/heads/master by this push:
     new 0ac46f3  KNOX-1911 - Support ClouderaManager Service Discovery in Admin UI
0ac46f3 is described below

commit 0ac46f34a14b6c89e497e551c8cb583fdf8dc832
Author: pzampino <pz...@cloudera.com>
AuthorDate: Thu Jun 27 14:38:41 2019 -0500

    KNOX-1911 - Support ClouderaManager Service Discovery in Admin UI
---
 .../new-desc-wizard/new-desc-wizard.component.html | 15 +++++++++++--
 .../new-desc-wizard/new-desc-wizard.component.ts   |  8 -------
 .../admin-ui/app/resource-detail/descriptor.ts     |  1 +
 .../resource-detail/resource-detail.component.html | 23 +++++++++++++++++++
 .../resource-detail/resource-detail.component.ts   |  1 +
 .../admin-ui/app/resource/resource.service.ts      | 10 +++++++++
 .../topology/discovery/ambari/AmbariCluster.java   |  6 ++---
 .../discovery/ambari/AmbariServiceDiscovery.java   | 26 ++++++++++++++++------
 8 files changed, 69 insertions(+), 21 deletions(-)

diff --git a/gateway-admin-ui/admin-ui/app/new-desc-wizard/new-desc-wizard.component.html b/gateway-admin-ui/admin-ui/app/new-desc-wizard/new-desc-wizard.component.html
index 68b3122..c709991 100644
--- a/gateway-admin-ui/admin-ui/app/new-desc-wizard/new-desc-wizard.component.html
+++ b/gateway-admin-ui/admin-ui/app/new-desc-wizard/new-desc-wizard.component.html
@@ -80,6 +80,19 @@
                 <div>
                     <table>
                         <tr>
+                            <td><strong>Type</strong></td>
+                            <td>
+                              <span>
+                                <select id="select" autofocus required class="md-select form-control"
+                                        [(ngModel)]="descriptor.discoveryType" (change)="descriptor.setDirty()">
+                                  <option *ngFor="let typeOption of resourceService.getSupportedDiscoveryTypes()"
+                                          class="md-option"
+                                          [value]="typeOption">{{typeOption}}</option>
+                                </select>
+                              </span>
+                            </td>
+                        </tr>
+                        <tr>
                             <td><strong>Address</strong></td>
                             <td>
                 <span>
@@ -95,8 +108,6 @@
                 <span>
                   <input type="text" [(ngModel)]="descriptor.discoveryCluster">
                 </span>
-                                <span *ngIf="!isValidDiscoveryCluster()"
-                                      style="color: red">invalid</span>
                             </td>
                         </tr>
                         <tr>
diff --git a/gateway-admin-ui/admin-ui/app/new-desc-wizard/new-desc-wizard.component.ts b/gateway-admin-ui/admin-ui/app/new-desc-wizard/new-desc-wizard.component.ts
index 36cab9e..24d0d89 100644
--- a/gateway-admin-ui/admin-ui/app/new-desc-wizard/new-desc-wizard.component.ts
+++ b/gateway-admin-ui/admin-ui/app/new-desc-wizard/new-desc-wizard.component.ts
@@ -198,7 +198,6 @@ export class NewDescWizardComponent implements OnInit {
             // Validate the discovery address
             if (this.descriptor.discoveryAddress) {
                 isValid = isValid && this.isValidDiscoveryAddress();
-                isValid = isValid && this.isValidDiscoveryCluster();
             }
         } else {
             isValid = false;
@@ -243,11 +242,4 @@ export class NewDescWizardComponent implements OnInit {
         }
     }
 
-    isValidDiscoveryCluster(): boolean {
-        if (this.descriptor.discoveryCluster) {
-            return (ValidationUtils.isValidResourceName(this.descriptor.discoveryCluster));
-        } else {
-            return true;
-        }
-    }
 }
diff --git a/gateway-admin-ui/admin-ui/app/resource-detail/descriptor.ts b/gateway-admin-ui/admin-ui/app/resource-detail/descriptor.ts
index 6e5a6ca..0a22117 100644
--- a/gateway-admin-ui/admin-ui/app/resource-detail/descriptor.ts
+++ b/gateway-admin-ui/admin-ui/app/resource-detail/descriptor.ts
@@ -17,6 +17,7 @@
 import {Service} from '../resource/service';
 
 export class Descriptor {
+    discoveryType: string;
     discoveryAddress: string;
     discoveryUser: string;
     discoveryPassAlias: string;
diff --git a/gateway-admin-ui/admin-ui/app/resource-detail/resource-detail.component.html b/gateway-admin-ui/admin-ui/app/resource-detail/resource-detail.component.html
index 8bb25e0..c110af3 100644
--- a/gateway-admin-ui/admin-ui/app/resource-detail/resource-detail.component.html
+++ b/gateway-admin-ui/admin-ui/app/resource-detail/resource-detail.component.html
@@ -355,6 +355,26 @@
             </div>
             <div class="panel-body" *ngIf="isShowServiceDiscovery()">
                 <table class="table table-sm">
+                    <!-- Discovery type field -->
+                    <tr>
+                        <td width="20%">
+                            <span>
+                              <strong>Type</strong>
+                            </span>
+                        </td>
+                        <td>
+                            <span>
+                              <select id="select" autofocus required class="md-select form-control"
+                                      [(ngModel)]="descriptor.discoveryType" (change)="descriptor.setDirty()">
+                                <option *ngFor="let typeOption of resourceService.getSupportedDiscoveryTypes()"
+                                        class="md-option"
+                                        [value]="typeOption"
+                                        [selected]="descriptor.discoveryType === typeOption">{{typeOption}}</option>
+                              </select>
+                            </span>
+                        </td>
+                    </tr>
+                    <!-- Discovery address field -->
                     <tr>
                         <td width="20%">
               <span [class]="!editModeAddress && !descriptor.discoveryAddress ? 'inline-editable' : ''"
@@ -378,6 +398,7 @@
               </span>
                         </td>
                     </tr>
+                    <!-- Discovery cluster field -->
                     <tr>
                         <td width="20%">
               <span [class]="!editModeCluster && !descriptor.discoveryCluster ? 'inline-editable' : ''"
@@ -401,6 +422,7 @@
               </span>
                         </td>
                     </tr>
+                    <!-- Discovery user field -->
                     <tr>
                         <td width="20%">
               <span [class]="!editModeUser && !descriptor.discoveryUser ? 'inline-editable' : ''"
@@ -424,6 +446,7 @@
               </span>
                         </td>
                     </tr>
+                    <!-- Discovery password alias field -->
                     <tr>
                         <td width="20%">
               <span [class]="!editModeAlias && !descriptor.discoveryPassAlias ? 'inline-editable' : ''"
diff --git a/gateway-admin-ui/admin-ui/app/resource-detail/resource-detail.component.ts b/gateway-admin-ui/admin-ui/app/resource-detail/resource-detail.component.ts
index 2e9a7e0..234e2ff 100644
--- a/gateway-admin-ui/admin-ui/app/resource-detail/resource-detail.component.ts
+++ b/gateway-admin-ui/admin-ui/app/resource-detail/resource-detail.component.ts
@@ -169,6 +169,7 @@ export class ResourceDetailComponent implements OnInit {
                 }
                 let tempDesc = new Descriptor();
                 if (contentObj) {
+                    tempDesc.discoveryType = contentObj['discovery-type'];
                     tempDesc.discoveryAddress = contentObj['discovery-address'];
                     tempDesc.discoveryUser = contentObj['discovery-user'];
                     tempDesc.discoveryPassAlias = contentObj['discovery-pwd-alias'];
diff --git a/gateway-admin-ui/admin-ui/app/resource/resource.service.ts b/gateway-admin-ui/admin-ui/app/resource/resource.service.ts
index 6095423..ba1c8e3 100644
--- a/gateway-admin-ui/admin-ui/app/resource/resource.service.ts
+++ b/gateway-admin-ui/admin-ui/app/resource/resource.service.ts
@@ -26,6 +26,9 @@ import {Descriptor} from '../resource-detail/descriptor';
 @Injectable()
 export class ResourceService {
 
+    // TODO: PJZ: Get this list dynamically?
+    private static discoveryTypes: Array<string> = ['ClouderaManager', 'Ambari'];
+
     apiUrl = '/gateway/manager/api/v1/';
     providersUrl = this.apiUrl + 'providerconfig';
     descriptorsUrl = this.apiUrl + 'descriptors';
@@ -46,6 +49,10 @@ export class ResourceService {
     constructor(private http: HttpClient) {
     }
 
+    getSupportedDiscoveryTypes(): string[] {
+        return ResourceService.discoveryTypes;
+    }
+
     getResources(resType: string): Promise<Resource[]> {
         switch (resType) {
             case 'Provider Configurations': {
@@ -184,6 +191,9 @@ export class ResourceService {
         let serialized: string;
 
         let tmp = {};
+        if (desc.discoveryType) {
+            tmp['discovery-type'] = desc.discoveryType;
+        }
         if (desc.discoveryAddress) {
             tmp['discovery-address'] = desc.discoveryAddress;
         }
diff --git a/gateway-discovery-ambari/src/main/java/org/apache/knox/gateway/topology/discovery/ambari/AmbariCluster.java b/gateway-discovery-ambari/src/main/java/org/apache/knox/gateway/topology/discovery/ambari/AmbariCluster.java
index 7a46133..f5bfff2 100644
--- a/gateway-discovery-ambari/src/main/java/org/apache/knox/gateway/topology/discovery/ambari/AmbariCluster.java
+++ b/gateway-discovery-ambari/src/main/java/org/apache/knox/gateway/topology/discovery/ambari/AmbariCluster.java
@@ -258,10 +258,8 @@ class AmbariCluster implements ServiceDiscovery.Cluster {
             int index = 0;
             for (String host : hosts) {
                 int portIndex = host.indexOf(':');
-                if (portIndex > 0) {
-                    host = host.substring(0, portIndex);
-                }
-                updatedEnsemble.append(host).append(':').append(port);
+                String qualifiedHost = (portIndex > 0) ? host.substring(0, portIndex) : host;
+                updatedEnsemble.append(qualifiedHost).append(':').append(port);
                 index += 1;
                 if (index < hosts.length) {
                     updatedEnsemble.append(',');
diff --git a/gateway-discovery-ambari/src/main/java/org/apache/knox/gateway/topology/discovery/ambari/AmbariServiceDiscovery.java b/gateway-discovery-ambari/src/main/java/org/apache/knox/gateway/topology/discovery/ambari/AmbariServiceDiscovery.java
index d1cbab9..6e891c7 100644
--- a/gateway-discovery-ambari/src/main/java/org/apache/knox/gateway/topology/discovery/ambari/AmbariServiceDiscovery.java
+++ b/gateway-discovery-ambari/src/main/java/org/apache/knox/gateway/topology/discovery/ambari/AmbariServiceDiscovery.java
@@ -31,7 +31,10 @@ import org.apache.knox.gateway.topology.discovery.ServiceDiscoveryConfig;
 
 import java.io.File;
 import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
 import java.lang.reflect.Method;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.util.ArrayList;
@@ -251,12 +254,21 @@ class AmbariServiceDiscovery implements ServiceDiscovery {
         if (discoveryAddress != null && clusterName != null) {
             cluster = new AmbariCluster(clusterName);
 
+            String encodedClusterName;
+            try {
+                encodedClusterName = URLEncoder.encode(clusterName, StandardCharsets.UTF_8.name());
+            } catch (UnsupportedEncodingException e) {
+                e.printStackTrace(); // TODO: Logging
+                encodedClusterName = clusterName;
+            }
+
             Map<String, String> serviceComponents = new HashMap<>();
 
             init(gatewayConfig);
 
             Map<String, List<String>> componentHostNames = new HashMap<>();
-            String hostRolesURL = String.format(Locale.ROOT, "%s" + AMBARI_HOSTROLES_URI, discoveryAddress, clusterName);
+            String hostRolesURL =
+                        String.format(Locale.ROOT, "%s" + AMBARI_HOSTROLES_URI, discoveryAddress, encodedClusterName);
             JSONObject hostRolesJSON = restClient.invoke(hostRolesURL, discoveryUser, discoveryPwdAlias);
             if (hostRolesJSON != null) {
                 // Process the host roles JSON
@@ -298,7 +310,7 @@ class AmbariServiceDiscovery implements ServiceDiscovery {
             // Service configurations
             Map<String, Map<String, AmbariCluster.ServiceConfiguration>> serviceConfigurations =
                 ambariClient.getActiveServiceConfigurations(discoveryAddress,
-                                                            clusterName,
+                                                            encodedClusterName,
                                                             discoveryUser,
                                                             discoveryPwdAlias);
             if (serviceConfigurations.isEmpty()) {
@@ -321,11 +333,11 @@ class AmbariServiceDiscovery implements ServiceDiscovery {
                     AmbariCluster.ServiceConfiguration svcConfig = configs.get(configType);
                     if (svcConfig != null) {
                         AmbariComponent c = new AmbariComponent(componentName,
-                            svcConfig.getVersion(),
-                            clusterName,
-                            serviceName,
-                            hostNames,
-                            svcConfig.getProperties());
+                                                                svcConfig.getVersion(),
+                                                                encodedClusterName,
+                                                                serviceName,
+                                                                hostNames,
+                                                                svcConfig.getProperties());
                         cluster.addComponent(c);
                     }
                 }