You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by lm...@apache.org on 2019/11/02 17:34:21 UTC

[knox] branch master updated: KNOX-2068 - Let end-users add a new service definition from scratch (#173)

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

lmccay 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 d99f1e5  KNOX-2068 - Let end-users add a new service definition from scratch (#173)
d99f1e5 is described below

commit d99f1e50e07ce2910efdf8d681b17ad86623115e
Author: Sandor Molnar <sm...@apache.org>
AuthorDate: Sat Nov 2 18:34:14 2019 +0100

    KNOX-2068 - Let end-users add a new service definition from scratch (#173)
---
 gateway-admin-ui/admin-ui/app/app.module.ts        |  2 +
 .../admin-ui/app/resource/resource.component.html  |  6 ++
 .../new-service-definition.component.css           |  5 ++
 .../new-service-definition.component.html          | 27 +++++++
 .../new-service-definition.component.ts            | 82 ++++++++++++++++++++++
 .../servicedefinition-detail.component.ts          | 17 +++--
 .../servicedefinition.service.ts                   | 23 +++++-
 .../assets/new-service-definition-template.xml     |  8 +++
 gateway-admin-ui/package-lock.json                 | 19 +++++
 gateway-admin-ui/package.json                      |  1 +
 pom.xml                                            |  1 +
 11 files changed, 180 insertions(+), 11 deletions(-)

diff --git a/gateway-admin-ui/admin-ui/app/app.module.ts b/gateway-admin-ui/admin-ui/app/app.module.ts
index c33cf20..5af7431 100644
--- a/gateway-admin-ui/admin-ui/app/app.module.ts
+++ b/gateway-admin-ui/admin-ui/app/app.module.ts
@@ -26,6 +26,7 @@ import {AppComponent} from './app.component';
 import {TopologyService} from './topology.service';
 import {ServiceDefinitionService} from './service-definition/servicedefinition.service';
 import {ServiceDefinitionDetailComponent} from './service-definition/servicedefinition-detail.component';
+import {NewServiceDefinitionComponent} from './service-definition/new-service-definition.component';
 import {GatewayVersionService} from './gateway-version.service';
 import {GatewayVersionComponent} from './gateway-version.component';
 import {TopologyComponent} from './topology.component';
@@ -61,6 +62,7 @@ import {ProviderConfigWizardComponent} from './provider-config-wizard/provider-c
         TopologyComponent,
         TopologyDetailComponent,
         ServiceDefinitionDetailComponent,
+        NewServiceDefinitionComponent,
         GatewayVersionComponent,
         XmlPipe,
         JsonPrettyPipe,
diff --git a/gateway-admin-ui/admin-ui/app/resource/resource.component.html b/gateway-admin-ui/admin-ui/app/resource/resource.component.html
index c586ce2..4845e60 100644
--- a/gateway-admin-ui/admin-ui/app/resource/resource.component.html
+++ b/gateway-admin-ui/admin-ui/app/resource/resource.component.html
@@ -18,6 +18,11 @@
                           (click)="newDescriptorModal.open()"
                           title="Create New Descriptor"
                           data-toggle="tooltip"></span>
+                    <span class="clickable inline-glyph glyphicon glyphicon-plus-sign btn btn-xs pull-right"
+                          *ngIf="resourceType === 'Service Definitions'"
+                          (click)="newServiceDefinitionModal.open()"
+                          title="Create New Service Definition"
+                          data-toggle="tooltip"></span>
                 </th>
                 <th *ngIf="resourceType === 'Topologies'">Timestamp</th>
             </tr>
@@ -44,5 +49,6 @@
     <div>
         <app-new-desc-wizard #newDescriptorModal></app-new-desc-wizard>
         <app-provider-config-wizard #newProviderConfigModal></app-provider-config-wizard>
+        <app-service-definition-wizard #newServiceDefinitionModal></app-service-definition-wizard>
     </div>
 </div>
diff --git a/gateway-admin-ui/admin-ui/app/service-definition/new-service-definition.component.css b/gateway-admin-ui/admin-ui/app/service-definition/new-service-definition.component.css
new file mode 100644
index 0000000..0cc494a
--- /dev/null
+++ b/gateway-admin-ui/admin-ui/app/service-definition/new-service-definition.component.css
@@ -0,0 +1,5 @@
+td {
+    border-collapse: collapse;
+    padding: 8px;
+    vertical-align: top;
+}
\ No newline at end of file
diff --git a/gateway-admin-ui/admin-ui/app/service-definition/new-service-definition.component.html b/gateway-admin-ui/admin-ui/app/service-definition/new-service-definition.component.html
new file mode 100644
index 0000000..96b9205
--- /dev/null
+++ b/gateway-admin-ui/admin-ui/app/service-definition/new-service-definition.component.html
@@ -0,0 +1,27 @@
+<bs-modal (onClose)="onClose()" #newServiceDefinitionModal xmlns="http://www.w3.org/1999/html"> 
+    <bs-modal-header [showDismiss]="true">
+        <label class="modal-title">Create a New Service Definition</label>
+    </bs-modal-header>
+    <bs-modal-body>
+        <div class="panel-body">
+            <div>
+                <span style="text-shadow: infotext; text-align: center;">At a minimum you must modify the service's name and role attributes!</span>
+            </div>
+            <br />
+            <div>
+                <ace-editor
+                        [(text)]="serviceDefinitionContent"
+                        [mode]="'xml'"
+                        [options]="options"
+                        [theme]="theme"
+                        style="min-height: 430px; width:100%; overflow: auto;">
+                </ace-editor>
+            </div>
+        </div>
+    </bs-modal-body>
+    <bs-modal-footer>
+        <button type="button" class="btn btn-default btn-sm" (click)="newServiceDefinitionModal.dismiss()">Cancel</button>
+        <button type="button" class="btn btn-primary btn-sm" (click)="newServiceDefinitionModal.close()"
+                [disabled]="!validate()">Ok</button>
+    </bs-modal-footer>
+</bs-modal>
diff --git a/gateway-admin-ui/admin-ui/app/service-definition/new-service-definition.component.ts b/gateway-admin-ui/admin-ui/app/service-definition/new-service-definition.component.ts
new file mode 100644
index 0000000..669d302
--- /dev/null
+++ b/gateway-admin-ui/admin-ui/app/service-definition/new-service-definition.component.ts
@@ -0,0 +1,82 @@
+/*
+ * 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 {Component, OnInit, ViewChild} from '@angular/core';
+import {HttpClient} from '@angular/common/http';
+import {BsModalComponent} from 'ng2-bs3-modal';
+import swal from 'sweetalert';
+
+import {ServiceDefinitionService} from './servicedefinition.service';
+import {ResourceTypesService} from '../resourcetypes/resourcetypes.service';
+
+import 'brace/theme/monokai';
+import 'brace/mode/xml';
+
+@Component({
+    selector: 'app-service-definition-wizard',
+    templateUrl: './new-service-definition.component.html',
+    styleUrls: ['./new-service-definition.component.css']
+})
+export class NewServiceDefinitionComponent implements OnInit {
+
+    serviceDefinitionXmlTemplate = 'assets/new-service-definition-template.xml';
+    defaultServiceDefinitionContent: string;
+    serviceDefinitionContent: string;
+    theme: String = 'monokai';
+    options: any = {useWorker: false, printMargin: false};
+
+    @ViewChild('newServiceDefinitionModal')
+    childModal: BsModalComponent;
+
+    constructor(private http: HttpClient,
+                private serviceDefinitionService: ServiceDefinitionService,
+                private resourceTypesService: ResourceTypesService) {
+    }
+
+    ngOnInit() {
+        this.http.get(this.serviceDefinitionXmlTemplate, {responseType: 'text'})
+                     .subscribe(data => this.defaultServiceDefinitionContent = data);
+    }
+
+    open(size?: string) {
+        this.reset();
+        this.childModal.open(size ? size : 'lg');
+    }
+
+    reset() {
+        this.serviceDefinitionContent = this.defaultServiceDefinitionContent;
+    }
+
+    onClose() {
+        this.serviceDefinitionService.saveNewServiceDefinition(this.serviceDefinitionContent)
+                                     .then(response => {
+                                           swal('Saved successfully!');
+                                           this.resourceTypesService.selectResourceType('Service Definitions');
+                                           this.serviceDefinitionService.selectedServiceDefinition(null);
+                                     });
+    }
+
+    validate(): boolean {
+        if (this.serviceDefinitionContent) {
+            if (this.serviceDefinitionContent.indexOf('your_service_name') >= 0
+                || this.serviceDefinitionContent.indexOf('YOUR_ROLE') >= 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}
diff --git a/gateway-admin-ui/admin-ui/app/service-definition/servicedefinition-detail.component.ts b/gateway-admin-ui/admin-ui/app/service-definition/servicedefinition-detail.component.ts
index 02e4461..b370142 100644
--- a/gateway-admin-ui/admin-ui/app/service-definition/servicedefinition-detail.component.ts
+++ b/gateway-admin-ui/admin-ui/app/service-definition/servicedefinition-detail.component.ts
@@ -16,6 +16,8 @@
  */
 import {Component, OnInit, ViewChild} from '@angular/core';
 import {BsModalComponent} from 'ng2-bs3-modal/ng2-bs3-modal';
+import swal from 'sweetalert';
+
 import {ServiceDefinition} from './servicedefinition';
 import {ServiceDefinitionService} from './servicedefinition.service';
 import {ResourceTypesService} from '../resourcetypes/resourcetypes.service';
@@ -123,22 +125,19 @@ export class ServiceDefinitionDetailComponent implements OnInit {
     updateServiceDefinition() {
         this.serviceDefinitionService.updateServiceDefinition(this.changedServiceDefinitionContent ? this.changedServiceDefinitionContent
                                                                 : this.serviceDefinitionContent)
-            .then(() => {
-                // This refreshes the list of service definitions
+            .then(response => {
+                swal('Updated successfully!');
                 this.resourceTypesService.selectResourceType('Service Definitions');
+                this.serviceDefinitionService.selectedServiceDefinition(null);
             });
     }
 
     deleteServiceDefinition() {
         this.serviceDefinitionService.deleteServiceDefinition(this.serviceDefinition)
-            .then(() => {
-                // This refreshes the list of service definitions
+            .then(response => {
+                swal('Deleted successfully!');
                 this.resourceTypesService.selectResourceType('Service Definitions');
-                // This refreshes the service definition content panel to the first one in the list
-                this.serviceDefinitionService.getServiceDefinitions()
-                    .then(serviceDefinitions => {
-                        this.serviceDefinitionService.selectedServiceDefinition(serviceDefinitions[0]);
-                    });
+                this.serviceDefinitionService.selectedServiceDefinition(null);
             });
     }
 }
diff --git a/gateway-admin-ui/admin-ui/app/service-definition/servicedefinition.service.ts b/gateway-admin-ui/admin-ui/app/service-definition/servicedefinition.service.ts
index 75e6b6c..cdb29c7 100644
--- a/gateway-admin-ui/admin-ui/app/service-definition/servicedefinition.service.ts
+++ b/gateway-admin-ui/admin-ui/app/service-definition/servicedefinition.service.ts
@@ -17,6 +17,7 @@
 import {Injectable} from '@angular/core';
 import {HttpClient, HttpErrorResponse, HttpHeaders} from '@angular/common/http';
 import {RestURLBuilder} from 'rest-url-builder';
+import swal from 'sweetalert';
 
 import 'rxjs/add/operator/toPromise';
 import {Subject} from 'rxjs/Subject';
@@ -73,6 +74,24 @@ export class ServiceDefinitionService {
             });
     }
 
+    saveNewServiceDefinition(xml: string): Promise<string> {
+        let xheaders = new HttpHeaders();
+        xheaders = this.addXmlHeaders(xheaders);
+        let serviceDefintionXml = xml.replace('<serviceDefinitions>', '').replace('</serviceDefinitions>', '');
+        return this.http.post(this.serviceDefinitionsBaseUrl, serviceDefintionXml, {headers: xheaders, responseType: 'text'})
+            .toPromise()
+            .then(response => response)
+            .catch((err: HttpErrorResponse) => {
+                console.debug('ServiceDefinitionService --> saveNewServiceDefinition() --> ' + this.serviceDefinitionsBaseUrl
+                              + '\n  error: ' + err.status + ' ' + err.message);
+                if (err.status === 401) {
+                    window.location.assign(document.location.pathname);
+                } else {
+                    return this.handleError(err);
+                }
+            });
+    }
+
     updateServiceDefinition(xml: string): Promise<string> {
         let xheaders = new HttpHeaders();
         xheaders = this.addXmlHeaders(xheaders);
@@ -134,8 +153,8 @@ export class ServiceDefinitionService {
         return headers.append('X-Requested-With', 'XMLHttpRequest');
     }
 
-    private handleError(error: any): Promise<any> {
-        console.error('An error occurred', error); // for demo purposes only
+    private handleError(error: HttpErrorResponse): Promise<any> {
+        swal('Oops!', 'Something went wrong!\n' + (error.error ? error.error : error.statusText), 'error');
         return Promise.reject(error.message || error);
     }
 
diff --git a/gateway-admin-ui/admin-ui/assets/new-service-definition-template.xml b/gateway-admin-ui/admin-ui/assets/new-service-definition-template.xml
new file mode 100644
index 0000000..2361638
--- /dev/null
+++ b/gateway-admin-ui/admin-ui/assets/new-service-definition-template.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<serviceDefinition>
+	<service name="your_service_name" role="YOUR_ROLE" version="1.0.0">
+		<dispatch classname="org.apache.knox.gateway.dispatch.DefaultDispatch" use-two-way-ssl="false" />
+		<routes />
+	</service>
+	<rules />
+</serviceDefinition>
diff --git a/gateway-admin-ui/package-lock.json b/gateway-admin-ui/package-lock.json
index 584b8a7..1840163 100644
--- a/gateway-admin-ui/package-lock.json
+++ b/gateway-admin-ui/package-lock.json
@@ -2309,6 +2309,11 @@
         "event-emitter": "~0.3.5"
       }
     },
+    "es6-object-assign": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
+      "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw="
+    },
     "es6-set": {
       "version": "0.1.5",
       "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
@@ -6216,6 +6221,11 @@
       "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
       "dev": true
     },
+    "promise-polyfill": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz",
+      "integrity": "sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc="
+    },
     "proxy-addr": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
@@ -7862,6 +7872,15 @@
         "has-flag": "^2.0.0"
       }
     },
+    "sweetalert": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/sweetalert/-/sweetalert-2.1.2.tgz",
+      "integrity": "sha512-iWx7X4anRBNDa/a+AdTmvAzQtkN1+s4j/JJRWlHpYE8Qimkohs8/XnFcWeYHH2lMA8LRCa5tj2d244If3S/hzA==",
+      "requires": {
+        "es6-object-assign": "^1.1.0",
+        "promise-polyfill": "^6.0.2"
+      }
+    },
     "symbol-observable": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz",
diff --git a/gateway-admin-ui/package.json b/gateway-admin-ui/package.json
index ee6309f..bed8a70 100644
--- a/gateway-admin-ui/package.json
+++ b/gateway-admin-ui/package.json
@@ -29,6 +29,7 @@
     "popper.js": "^1.14.7",
     "rest-url-builder": "^1.0.6",
     "rxjs": "^5.5.2",
+    "sweetalert": "^2.1.2",
     "ts-helpers": "^1.1.1",
     "zone.js": "^0.8.29"
   },
diff --git a/pom.xml b/pom.xml
index 18bfa5c..60fa4bd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -407,6 +407,7 @@
                         <exclude>**/admin-ui/**/*.html</exclude>
                         <exclude>atlassian-ide-plugin.xml</exclude>
                         <exclude>**/PULL_REQUEST_TEMPLATE*</exclude>
+                        <exclude>**/new-service-definition-template.xml</exclude>
                     </excludes>
                 </configuration>
             </plugin>