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 2018/02/02 01:43:15 UTC
[7/7] knox git commit: KNOX-1040 - Initial changes to support simple
descriptors and provider configurations in the Admin UI.
KNOX-1040 - Initial changes to support simple descriptors and provider configurations in the Admin UI.
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/e8ba712c
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/e8ba712c
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/e8ba712c
Branch: refs/heads/master
Commit: e8ba712c8b5a102c95aa2e70d27b2fe32f9d620c
Parents: 7025086
Author: Phil Zampino <pz...@apache.org>
Authored: Fri Jan 26 22:14:50 2018 -0500
Committer: Phil Zampino <pz...@apache.org>
Committed: Thu Feb 1 20:27:07 2018 -0500
----------------------------------------------------------------------
gateway-admin-ui/README.md | 2 +-
gateway-admin-ui/package.json | 20 +-
gateway-admin-ui/src/app/app.component.ts | 27 ++-
gateway-admin-ui/src/app/app.module.ts | 60 ++++--
.../src/app/descriptor/descriptor.component.css | 0
.../app/descriptor/descriptor.component.html | 3 +
.../app/descriptor/descriptor.component.spec.ts | 41 ++++
.../src/app/descriptor/descriptor.component.ts | 31 +++
.../src/app/gateway-version.service.ts | 26 +--
.../src/app/resource-detail/descriptor.ts | 46 ++++
.../src/app/resource-detail/provider-config.ts | 23 ++
.../resource-detail.component.css | 0
.../resource-detail.component.html | 151 ++++++++++++++
.../resource-detail.component.spec.ts | 41 ++++
.../resource-detail.component.ts | 209 +++++++++++++++++++
.../src/app/resource/resource.component.css | 0
.../src/app/resource/resource.component.html | 22 ++
.../src/app/resource/resource.component.spec.ts | 41 ++++
.../src/app/resource/resource.component.ts | 92 ++++++++
.../src/app/resource/resource.service.ts | 199 ++++++++++++++++++
gateway-admin-ui/src/app/resource/resource.ts | 24 +++
gateway-admin-ui/src/app/resource/service.ts | 22 ++
.../resourcetypes/resourcetypes.component.css | 0
.../resourcetypes/resourcetypes.component.html | 14 ++
.../resourcetypes.component.spec.ts | 41 ++++
.../resourcetypes/resourcetypes.component.ts | 44 ++++
.../app/resourcetypes/resourcetypes.service.ts | 37 ++++
.../src/app/topology-detail.component.ts | 129 ++++++------
gateway-admin-ui/src/app/topology.component.ts | 6 +-
gateway-admin-ui/src/app/topology.service.ts | 60 +++---
gateway-admin-ui/src/index.html | 49 ++---
gateway-admin-ui/src/styles.css | 6 +
.../applications/admin-ui/app/index.html | 14 +-
.../app/inline.1b8a794b441ffd968489.bundle.js | 1 +
.../app/inline.b47d11937c275f76ce02.bundle.js | 1 -
.../app/main.10e7c17d5707ac382dbb.bundle.js | 1 +
.../app/main.a69408978854e3a77fb2.bundle.js | 1 -
.../app/scripts.2c89ed78f648df44c10f.bundle.js | 12 --
.../app/scripts.c50bb762c438ae0f8842.bundle.js | 1 +
.../app/styles.2ee5b7f4cd59a6cf015e.bundle.css | 1 +
.../app/styles.d41d8cd98f00b204e980.bundle.css | 0
.../service/admin/TopologiesResource.java | 2 +-
.../gateway/GatewayAdminTopologyFuncTest.java | 8 -
43 files changed, 1292 insertions(+), 216 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/README.md
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/README.md b/gateway-admin-ui/README.md
index c5e8a4e..7cef27b 100644
--- a/gateway-admin-ui/README.md
+++ b/gateway-admin-ui/README.md
@@ -1,7 +1,7 @@
# NgKnoxUi
-This project was generated with [Angular CLI](https://cli.angular.io/) version 1.5.3.
+This project was generated with [Angular CLI](https://cli.angular.io/) version 1.6.5.
## Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/package.json
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/package.json b/gateway-admin-ui/package.json
index 4218fd5..9f6548c 100644
--- a/gateway-admin-ui/package.json
+++ b/gateway-admin-ui/package.json
@@ -12,9 +12,9 @@
},
"private": true,
"dependencies": {
- "@angular/common": "^5.0.0",
- "@angular/compiler": "^5.0.0",
- "@angular/core": "^5.0.0",
+ "@angular/common": "^5.2.0",
+ "@angular/compiler": "^5.2.0",
+ "@angular/core": "^5.2.0",
"@angular/forms": "^5.0.0",
"@angular/http": "^5.0.0",
"@angular/platform-browser": "^5.0.0",
@@ -24,17 +24,21 @@
"rxjs": "^5.5.2",
"zone.js": "^0.8.14",
"ng2-ace-editor": "0.3.3",
- "ng2-bs3-modal": "^0.10.4",
- "ts-helpers": "^1.1.1"
+ "ng2-bs3-modal": "^0.13.0",
+ "ts-helpers": "^1.1.1",
+ "jquery": "^1.12.4",
+ "js-yaml": "^3.10.0",
+ "popper.js": "^1.12.9"
},
"devDependencies": {
- "@angular/cli": "1.5.3",
- "@angular/compiler-cli": "^5.0.0",
+ "@angular/cli": "^1.6.5",
+ "@angular/compiler-cli": "^5.2.0",
"@angular/language-service": "^5.0.0",
"@types/jasmine": "~2.5.53",
"@types/jasminewd2": "~2.0.2",
"@types/node": "~6.0.60",
- "codelyzer": "~3.2.0",
+ "codelyzer": "^4.1.0",
+ "bootstrap": "^3.3.7",
"jasmine-core": "~2.6.2",
"jasmine-spec-reporter": "~4.1.0",
"karma": "~1.7.0",
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/app.component.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/app.component.ts b/gateway-admin-ui/src/app/app.component.ts
index cee1178..bff7ec8 100644
--- a/gateway-admin-ui/src/app/app.component.ts
+++ b/gateway-admin-ui/src/app/app.component.ts
@@ -15,26 +15,31 @@
* limitations under the License.
*/
import { Component } from '@angular/core';
-import {TopologyService} from "./topology.service";
+import { TopologyService } from './topology.service';
+import { ResourceTypesService } from './resourcetypes/resourcetypes.service'
@Component({
- selector: 'topology-management',
+ selector: 'resource-management',
template: `
- <div class="container">
+ <div class="container-fluid">
<div class="row">
- <div class="col-md-5">
- <topology></topology>
- </div>
- <div class="col-md-7">
- <topology-detail></topology-detail>
+ <div class="col-md-2 col-lg-2">
+ <app-resourcetypes></app-resourcetypes>
+ </div>
+ <div class="col-md-3 col-lg-3">
+ <app-resource></app-resource>
+ </div>
+ <div class="col-md-7 col-lg-7">
+ <app-resource-detail></app-resource-detail>
</div>
</div>
</div>
- `,
- providers: [TopologyService]
+ `,
+ providers: [TopologyService, ResourceTypesService]
})
export class AppComponent {
- constructor(private topologyService : TopologyService) {
+ constructor(private topologyService : TopologyService,
+ private resourcetypesService: ResourceTypesService) {
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/app.module.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/app.module.ts b/gateway-admin-ui/src/app/app.module.ts
index a081ead..173a638 100644
--- a/gateway-admin-ui/src/app/app.module.ts
+++ b/gateway-admin-ui/src/app/app.module.ts
@@ -16,41 +16,57 @@
*/
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
-import { HttpModule } from '@angular/http';
+import { HttpClientModule } from "@angular/common/http";
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
-import {TopologyService} from "./topology.service";
-import {GatewayVersionService} from "./gateway-version.service";
-import {GatewayVersionComponent} from "./gateway-version.component";
-import {TopologyComponent} from "./topology.component";
-import {TopologyDetailComponent} from "./topology-detail.component";
-import {XmlPipe} from "./utils/xml.pipe";
-import {JsonPrettyPipe} from "./utils/json-pretty.pipe";
+import { TopologyService } from './topology.service';
+import { GatewayVersionService } from "./gateway-version.service";
+import { GatewayVersionComponent } from "./gateway-version.component";
+import { TopologyComponent } from "./topology.component";
+import { TopologyDetailComponent } from "./topology-detail.component";
+import { XmlPipe } from './utils/xml.pipe';
+import { JsonPrettyPipe } from './utils/json-pretty.pipe';
import { TabComponent } from './utils/tab.component';
import { TabsComponent } from './utils/tabs.component';
import { AceEditorModule } from 'ng2-ace-editor';
-import { Ng2Bs3ModalModule } from 'ng2-bs3-modal/ng2-bs3-modal'
+import { BsModalModule } from 'ng2-bs3-modal/ng2-bs3-modal';
+import { ResourcetypesComponent } from './resourcetypes/resourcetypes.component';
+import { ResourceTypesService } from './resourcetypes/resourcetypes.service';
+import { ResourceComponent } from './resource/resource.component';
+import { ResourceService } from './resource/resource.service';
+import { DescriptorComponent } from './descriptor/descriptor.component';
+import { ResourceDetailComponent } from './resource-detail/resource-detail.component'
@NgModule({
imports: [ BrowserModule,
- HttpModule,
- FormsModule,
- Ng2Bs3ModalModule,
- AceEditorModule
+ HttpClientModule,
+ FormsModule,
+ BsModalModule,
+ AceEditorModule
],
declarations: [ AppComponent,
- TopologyComponent,
- TopologyDetailComponent,
- GatewayVersionComponent,
- XmlPipe,
- JsonPrettyPipe,
- TabsComponent,
- TabComponent ],
+ TopologyComponent,
+ TopologyDetailComponent,
+ GatewayVersionComponent,
+ XmlPipe,
+ JsonPrettyPipe,
+ TabsComponent,
+ TabComponent,
+ ResourcetypesComponent,
+ ResourceComponent,
+ DescriptorComponent,
+ ResourceDetailComponent
+ ],
providers: [ TopologyService,
- GatewayVersionService ],
+ GatewayVersionService,
+ ResourceComponent,
+ ResourceTypesService,
+ ResourceService
+ ],
bootstrap: [ AppComponent,
- GatewayVersionComponent]
+ GatewayVersionComponent
+ ]
})
export class AppModule { }
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/descriptor/descriptor.component.css
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/descriptor/descriptor.component.css b/gateway-admin-ui/src/app/descriptor/descriptor.component.css
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/descriptor/descriptor.component.html
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/descriptor/descriptor.component.html b/gateway-admin-ui/src/app/descriptor/descriptor.component.html
new file mode 100644
index 0000000..938689f
--- /dev/null
+++ b/gateway-admin-ui/src/app/descriptor/descriptor.component.html
@@ -0,0 +1,3 @@
+<p>
+ descriptor works!
+</p>
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/descriptor/descriptor.component.spec.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/descriptor/descriptor.component.spec.ts b/gateway-admin-ui/src/app/descriptor/descriptor.component.spec.ts
new file mode 100644
index 0000000..8ecf460
--- /dev/null
+++ b/gateway-admin-ui/src/app/descriptor/descriptor.component.spec.ts
@@ -0,0 +1,41 @@
+/*
+ * 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 { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DescriptorComponent } from './descriptor.component';
+
+describe('DescriptorComponent', () => {
+ let component: DescriptorComponent;
+ let fixture: ComponentFixture<DescriptorComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ DescriptorComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DescriptorComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/descriptor/descriptor.component.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/descriptor/descriptor.component.ts b/gateway-admin-ui/src/app/descriptor/descriptor.component.ts
new file mode 100644
index 0000000..211d7bd
--- /dev/null
+++ b/gateway-admin-ui/src/app/descriptor/descriptor.component.ts
@@ -0,0 +1,31 @@
+/*
+ * 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 } from '@angular/core';
+
+@Component({
+ selector: 'app-descriptor',
+ templateUrl: './descriptor.component.html',
+ styleUrls: ['./descriptor.component.css']
+})
+export class DescriptorComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/gateway-version.service.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/gateway-version.service.ts b/gateway-admin-ui/src/app/gateway-version.service.ts
index cdd7679..38b247c 100644
--- a/gateway-admin-ui/src/app/gateway-version.service.ts
+++ b/gateway-admin-ui/src/app/gateway-version.service.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
-import { Headers, Http } from '@angular/http';
+import { HttpHeaders, HttpClient } from '@angular/common/http';
import 'rxjs/add/operator/toPromise';
@@ -26,22 +26,22 @@ export class GatewayVersionService {
private apiUrl = '/gateway/manager/api/v1/version';
- constructor(private http: Http) { }
+ constructor(private http: HttpClient) { }
getVersion(): Promise<GatewayVersion> {
- let headers = new Headers();
- this.addHeaders(headers);
- return this.http.get(this.apiUrl, {
- headers: headers
- } )
- .toPromise()
- .then(response => response.json().ServerVersion as GatewayVersion)
- .catch(this.handleError);
+ let headers = new HttpHeaders();
+ headers = this.addHeaders(headers);
+ return this.http.get(this.apiUrl, { headers: headers } )
+ .toPromise()
+ .then(response => {
+ return response['ServerVersion'] as GatewayVersion;
+ })
+ .catch(this.handleError);
}
- addHeaders(headers: Headers) {
- headers.append('Accept', 'application/json');
- headers.append('Content-Type', 'application/json');
+ addHeaders(headers: HttpHeaders) {
+ return headers.append('Accept', 'application/json')
+ .append('Content-Type', 'application/json');
}
private handleError(error: any): Promise<any> {
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resource-detail/descriptor.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resource-detail/descriptor.ts b/gateway-admin-ui/src/app/resource-detail/descriptor.ts
new file mode 100644
index 0000000..c407f96
--- /dev/null
+++ b/gateway-admin-ui/src/app/resource-detail/descriptor.ts
@@ -0,0 +1,46 @@
+/*
+ * 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 {Service} from "../resource/service";
+
+
+export class Descriptor {
+ discoveryAddress: string;
+ discoveryUser: string;
+ discoveryPassAlias: string;
+ discoveryCluster: string;
+ providerConfig: string;
+ services: Service[];
+
+ getServiceParamKeys(service: Service): string[] {
+ let result = [];
+ for(let key in service.params){
+ if (service.params.hasOwnProperty(key)){
+ result.push(key);
+ }
+ }
+ return result;
+ }
+
+ getServiceParamValue(service: Service, name: string): string {
+ return service.params[name];
+ }
+
+ setProviderConfig(providerConfigRef: string) {
+ this.providerConfig = providerConfigRef;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resource-detail/provider-config.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resource-detail/provider-config.ts b/gateway-admin-ui/src/app/resource-detail/provider-config.ts
new file mode 100644
index 0000000..0811b9a
--- /dev/null
+++ b/gateway-admin-ui/src/app/resource-detail/provider-config.ts
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+export class ProviderConfig {
+ name: string;
+ role: string;
+ enabled: string;
+ params: Object;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resource-detail/resource-detail.component.css
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resource-detail/resource-detail.component.css b/gateway-admin-ui/src/app/resource-detail/resource-detail.component.css
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resource-detail/resource-detail.component.html
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resource-detail/resource-detail.component.html b/gateway-admin-ui/src/app/resource-detail/resource-detail.component.html
new file mode 100644
index 0000000..79d3ba8
--- /dev/null
+++ b/gateway-admin-ui/src/app/resource-detail/resource-detail.component.html
@@ -0,0 +1,151 @@
+<div *ngIf="resourceType && resourceType !== 'Topologies'" class="panel panel-default">
+ <div class="panel-heading">
+ <h4 class="panel-title">
+ {{ getTitleSubject() }} Detail <span *ngIf="hasSelectedResource()" class="pull-right">{{resourceService.getResourceDisplayName(resource)}}</span>
+ </h4>
+ </div>
+
+ <!-- Provider Configuration Details -->
+ <div class="panel-body" *ngIf="hasSelectedResource() && resourceType === 'Provider Configurations'">
+ <div *ngIf="hasSelectedResource()">
+ <div class="panel panel-default" *ngFor="let provider of providers">
+ <span [class]="'clickable glyhpicon glyphicon-' + (provider.show ? 'minus' : 'plus')"
+ (click)="provider.show = !provider.show"></span>
+ <span><b>{{ provider.name }}</b></span>
+ <span class="glyphicon glyphicon-remove-sign pull-right" data-toggle="tooltip" [title]="'Remove ' + provider.name"></span>
+ <div *ngIf="provider.show">
+ <b>Role</b> {{ provider.role }}<br>
+ <b>Enabled</b> {{ provider.enabled }}<br>
+ <div>
+ <span> </span>
+ <span [class]="'clickable glyhpicon glyphicon-' + (provider.paramDetails ? 'minus' : 'plus')"
+ (click)="provider.paramDetails = !provider.paramDetails"></span>
+ <span><b>Params</b></span>
+ <span class="glyphicon glyphicon-plus-sign pull-right" data-toggle="tooltip" title="Add Param"></span>
+
+ <div class="panel panel-default table-responsive" *ngIf="provider.paramDetails">
+ <table class="table table-sm">
+ <tr *ngFor="let key of getParamKeys(provider)">
+ <td>
+ <span class="glyphicon glyphicon-remove-sign"></span>
+ </td>
+ <td><b>{{ key }}</b></td>
+ <td>{{ provider.params[key] }}</td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ </div>
+ <br><br>
+ </div>
+ </div>
+ </div>
+
+ <!-- Descriptor Details -->
+ <div class="panel-body" *ngIf="hasSelectedResource() && resourceType === 'Descriptors'">
+ <!-- The resource name is undefined if it's the empty descriptor because none has been selected yet. -->
+ <div *ngIf="hasSelectedResource()">
+ <div>
+ <div class="panel panel-default col-md-12">
+ <span class="col-md-4"><b>Provider Configuration</b></span>
+ <span class="col-md-7">
+ <input type="text" class="col-md-sm form-control input-sm" [(ngModel)]="descriptor.providerConfig" id="textbox"/>
+ </span>
+ <span class="col-md-1 pull-left">
+ <button id="chooseProviderConfig" (click)="chooseProviderConfigModal.open('sm')" class="btn btn-default btn-xs glyphicon glyphicon-edit" type="submit">
+ <!-- <span class="glyphicon glyphicon-edit"></span>-->
+ </button>
+ </span>
+ </div>
+ <bs-modal (onClose)="descriptor.setProviderConfig(newProviderConfigRef)" #chooseProviderConfigModal>
+ <!--<bs-modal-header [show-close]="true">-->
+ <bs-modal-header>
+ <label class="modal-title">Choose a Provider Configuration</label>
+ </bs-modal-header>
+ <bs-modal-body>
+ <div class="form-group">
+ <select autofocus required class="md-select form-control" required [(ngModel)]="newProviderConfigRef" id="select" >
+ <option *ngFor="let pc of availableProviderConfigs"
+ class="md-option"
+ [value]="pc.name"
+ [selected]="pc.name === descriptor.providerConfig">{{pc.name}}</option>
+ </select>
+ </div>
+ </bs-modal-body>
+ <bs-modal-footer>
+ <button type="button" class="btn btn-default btn-sm" data-dismiss="chooseProviderConfigModal" (click)="chooseProviderConfigModal.dismiss()">Cancel</button>
+ <button type="button" class="btn btn-primary btn-sm" [disabled]="!newProviderConfigRef" (click)="chooseProviderConfigModal.close()">Ok</button>
+ </bs-modal-footer>
+ </bs-modal>
+ </div>
+
+ <br><br>
+
+ <div class="panel panel-default col-md-12">
+ <span [class]="'clickable glyhpicon glyphicon-' + (showServiceDetails ? 'minus' : 'plus')"
+ (click)="showServiceDetails = !showServiceDetails"></span>
+ <span><b>Services</b></span>
+ <span class="glyphicon glyphicon-plus-sign pull-right" data-toggle="tooltip" title="Add Service"></span>
+ <div class="col-md-12 table-responsive" *ngIf="showServiceDetails">
+ <table class="table table-striped table-sm">
+ <tr *ngFor="let service of descriptor.services">
+ <td>
+ <div>
+ <span><b>{{ service.name }}</b></span>
+ <span class="glyphicon glyphicon-remove-sign pull-right" data-toggle="tooltip" [title]="'Remove ' + service.name"></span>
+ </div>
+ <div>
+ <span [class]="'clickable glyhpicon glyphicon-' + (service.showParams ? 'minus' : 'plus')"
+ (click)="service.showParams = !service.showParams"></span>
+ <span>Params</span><span> </span><span class="glyphicon glyphicon-plus-sign" data-toggle="tooltip" title="Add param"></span>
+ <!--<span class="btn btn-default btn-xs" data-toggle="tooltip" title="Add param">add</span>-->
+ </div>
+ <div class="table-responsive" *ngIf="service.showParams">
+ <table class="table table-sm" *ngIf="descriptor.getServiceParamKeys(service).length > 0">
+ <tr *ngFor="let paramKey of descriptor.getServiceParamKeys(service)">
+ <td width="5%"><span class="glyphicon glyphicon-remove-sign"></span></td>
+ <td width="30%"><b>{{ paramKey }}</b></td>
+ <td width="65%" align="left">{{ descriptor.getServiceParamValue(service, paramKey) }}</td>
+ </tr>
+ </table>
+ </div>
+ <div>
+ <span [class]="'clickable glyhpicon glyphicon-' + (service.showUrls ? 'minus' : 'plus')"
+ (click)="service.showUrls = !service.showUrls"></span>
+ <span>URLs</span><span> </span><span class="glyphicon glyphicon-plus-sign" data-toggle="tooltip" title="Add URL"></span>
+ </div>
+ <div class="table-responsive" *ngIf="service.showUrls">
+ <table class="table table-sm" *ngIf="service.urls && service.urls.length > 0">
+ <tr *ngFor="let url of service.urls">
+ <td width="5%"><span class="glyphicon glyphicon-remove-sign"></span></td>
+ <td width="95%">{{ url }}</td>
+ </tr>
+ </table>
+ </div>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ <br><br>
+ <div class="panel panel-default col-md-12">
+ <span [class]="'clickable glyhpicon glyphicon-' + (showDiscDetails ? 'minus' : 'plus')"
+ (click)="showDiscDetails = !showDiscDetails"></span>
+ <span><b>Discovery Details</b></span>
+ <div class="col-md-12" *ngIf="showDiscDetails">
+ <table class="table table-sm">
+ <tr><td>Discovery Address</td><td>{{ descriptor.discoveryAddress }}</td></tr>
+ <tr><td>Discovery User</td><td>{{ descriptor.discoveryUser }}</td></tr>
+ <tr><td>Discovery Password Alias</td><td>{{ descriptor.discoveryPassAlias }}</td></tr>
+ <tr><td>Discovery Cluster</td><td>{{ descriptor.discoveryCluster }}</td></tr>
+ </table>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
+<!-- Topology Details -->
+<div *ngIf="resourceType === 'Topologies'">
+ <topology-detail></topology-detail>
+</div>
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resource-detail/resource-detail.component.spec.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resource-detail/resource-detail.component.spec.ts b/gateway-admin-ui/src/app/resource-detail/resource-detail.component.spec.ts
new file mode 100644
index 0000000..9503223
--- /dev/null
+++ b/gateway-admin-ui/src/app/resource-detail/resource-detail.component.spec.ts
@@ -0,0 +1,41 @@
+/*
+ * 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 { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ResourceDetailComponent } from './resource-detail.component';
+
+describe('ResourceDetailComponent', () => {
+ let component: ResourceDetailComponent;
+ let fixture: ComponentFixture<ResourceDetailComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ResourceDetailComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ResourceDetailComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resource-detail/resource-detail.component.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resource-detail/resource-detail.component.ts b/gateway-admin-ui/src/app/resource-detail/resource-detail.component.ts
new file mode 100644
index 0000000..acbe71b
--- /dev/null
+++ b/gateway-admin-ui/src/app/resource-detail/resource-detail.component.ts
@@ -0,0 +1,209 @@
+/*
+ * 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} from '@angular/core';
+import { ResourceService } from '../resource/resource.service';
+import { Resource } from '../resource/resource';
+import { ProviderConfig } from './provider-config';
+import { Descriptor } from "./descriptor";
+import { Service } from "../resource/service";
+import { parseString } from 'xml2js';
+
+import 'brace/theme/monokai';
+import 'brace/mode/xml';
+
+@Component({
+ selector: 'app-resource-detail',
+ templateUrl: './resource-detail.component.html',
+ styleUrls: ['./resource-detail.component.css']
+})
+export class ResourceDetailComponent implements OnInit {
+
+ // Static "empty" Resource used for clearing the display between resource selections
+ private static emptyResource: Resource = new Resource();
+
+ private static emptyDescriptor: Descriptor = new Descriptor();
+
+ title: string;
+
+ resourceType: string;
+ resource: Resource;
+ resourceContent: string;
+
+ providers: Array<ProviderConfig>;
+
+ descriptor: Descriptor;
+
+ availableProviderConfigs: Resource[];
+
+ constructor(private resourceService: ResourceService) {
+ }
+
+ ngOnInit() {
+ this.resourceService.getResources('Provider Configurations').then(pcs => {
+ this.availableProviderConfigs = pcs;
+ });
+
+ this.resourceService.selectedResourceType$.subscribe(type => this.setResourceType(type));
+ this.resourceService.selectedResource$.subscribe(value => this.setResource(value));
+ }
+
+ get self() {
+ return this;
+ }
+
+ setResourceType(resType: string) {
+ if (resType !== this.resourceType) {
+
+ if (resType === 'Descriptors') {
+ // Update the available provider configurations if we're dealing with descriptors
+ this.resourceService.getResources("Provider Configurations").then(result => this.availableProviderConfigs = result);
+ }
+
+ // Clear the current resource details
+ if (this.resource) {this.resource.name = '';} // This clears the details title when the type context changes
+ this.resource = ResourceDetailComponent.emptyResource;
+ this.providers = null;
+ this.descriptor = ResourceDetailComponent.emptyDescriptor;
+ this.resourceContent = ''; // Clear the content area
+ this.resourceType = resType;
+ }
+ }
+
+ setResource(res: Resource) {
+ this.resource = res;
+ this.providers = [];
+ this.resourceService.getResource(this.resourceType, res).then(content => this.setResourceContent(res, content));
+ }
+
+ setResourceContent(res: Resource, content: string) {
+ switch(this.resourceType) {
+ case 'Provider Configurations': {
+ this.setProviderConfigContent(res, content);
+ break;
+ }
+ case 'Descriptors': {
+ this.setDescriptorContent(res, content);
+ break;
+ }
+ }
+ }
+
+ setProviderConfigContent(res: Resource, content: string) {
+ this.resourceContent = content;
+ if (this.resourceContent) {
+ try {
+ let contentObj;
+ if (res.name.endsWith('json')) {
+ // Parse the JSON representation
+ contentObj = JSON.parse(this.resourceContent);
+ this.providers = contentObj['providers'];
+ } else if (res.name.endsWith('yaml') || res.name.endsWith('yml')) {
+ // Parse the YAML representation
+ let yaml = require('js-yaml');
+ contentObj = yaml.load(this.resourceContent);
+ this.providers = contentObj['providers'];
+ } else if (res.name.endsWith('xml')) {
+ // Parse the XML representation
+ parseString(this.resourceContent, (err, result) => {
+ let tempProviders = new Array<ProviderConfig>();
+ result['gateway'].provider.forEach(entry => {
+ let providerConfig: ProviderConfig = entry;
+ let params = {};
+ entry.param.forEach(param => {
+ params[param.name] = param.value;
+ });
+ providerConfig.params = params;
+ tempProviders.push(providerConfig);
+ });
+ this.providers = tempProviders;
+ });
+ }
+ } catch (e) {
+ console.log('Error parsing resource content: ' + e);
+ }
+ }
+ }
+
+ setDescriptorContent(res: Resource, content: string) {
+ this.resourceContent = content;
+ if (this.resourceContent) {
+ try {
+ console.log('Parsing descriptor ' + res.name);
+ let contentObj;
+ if (res.name.endsWith('json')) {
+ contentObj = JSON.parse(this.resourceContent);
+ } else if (res.name.endsWith('yaml') || res.name.endsWith('yml')) {
+ let yaml = require('js-yaml');
+ contentObj = yaml.load(this.resourceContent);
+ }
+ let tempDesc = new Descriptor();
+ if (contentObj) {
+ tempDesc.discoveryAddress = contentObj['discovery-address'];
+ tempDesc.discoveryUser = contentObj['discovery-user'];
+ tempDesc.discoveryPassAlias = contentObj['discovery-pwd-alias'];
+ tempDesc.discoveryCluster = contentObj['cluster'];
+ tempDesc.providerConfig = contentObj['provider-config-ref'];
+ tempDesc.services = contentObj['services'];
+ }
+ this.descriptor = tempDesc;
+ } catch (e) {
+ console.log('Error parsing resource content: ' + e);
+ }
+ }
+ }
+
+ getParamKeys(provider: ProviderConfig): string[] {
+ let result = [];
+ for(let key in provider.params){
+ if (provider.params.hasOwnProperty(key)){
+ result.push(key);
+ }
+ }
+ return result;
+ }
+
+
+ getServiceParamKeys(service: Service): string[] {
+ let result = [];
+ for(let key in service.params){
+ if (service.params.hasOwnProperty(key)){
+ result.push(key);
+ }
+ }
+ return result;
+ }
+
+ hasSelectedResource(): boolean {
+ return Boolean(this.resource) && Boolean(this.resource.name);
+ }
+
+ getTitleSubject(): string {
+ switch(this.resourceType) {
+ case 'Topologies': {
+ return 'Topology';
+ }
+ case 'Provider Configurations':
+ case 'Descriptors': {
+ return this.resourceType.substring(0, this.resourceType.length - 1);
+ }
+ default: {
+ return 'Resource';
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resource/resource.component.css
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resource/resource.component.css b/gateway-admin-ui/src/app/resource/resource.component.css
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resource/resource.component.html
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resource/resource.component.html b/gateway-admin-ui/src/app/resource/resource.component.html
new file mode 100644
index 0000000..f0bdeb2
--- /dev/null
+++ b/gateway-admin-ui/src/app/resource/resource.component.html
@@ -0,0 +1,22 @@
+<div>
+ <div class="table-responsive" style="max-height: 400px; width:100%; overflow: auto;">
+ <table class="table table-hover">
+ <thead>
+ <tr>
+ <th>{{ getResourceTypeSingularDisplayName(resourceType) }}</th>
+ <th *ngIf="resourceType === 'Topologies'">Timestamp</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr *ngFor="let resource of resources"
+ [class.selected]="resource === selectedResource"
+ [class.active]="resource === selectedResource"
+ (click)="onSelect(resource)"
+ class="clickable">
+ <td>{{resourceService.getResourceDisplayName(resource)}}</td>
+ <td *ngIf="resourceType === 'Topologies'">{{resource.timestamp | date:'medium'}}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resource/resource.component.spec.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resource/resource.component.spec.ts b/gateway-admin-ui/src/app/resource/resource.component.spec.ts
new file mode 100644
index 0000000..fa69cd0
--- /dev/null
+++ b/gateway-admin-ui/src/app/resource/resource.component.spec.ts
@@ -0,0 +1,41 @@
+/*
+ * 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 { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ResourceComponent } from './resource.component';
+
+describe('ResourceComponent', () => {
+ let component: ResourceComponent;
+ let fixture: ComponentFixture<ResourceComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ResourceComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ResourceComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resource/resource.component.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resource/resource.component.ts b/gateway-admin-ui/src/app/resource/resource.component.ts
new file mode 100644
index 0000000..c46b732
--- /dev/null
+++ b/gateway-admin-ui/src/app/resource/resource.component.ts
@@ -0,0 +1,92 @@
+/*
+ * 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 } from '@angular/core';
+import { ResourceTypesService } from '../resourcetypes/resourcetypes.service';
+import { ResourceService } from './resource.service';
+import { Resource } from './resource';
+import {TopologyService} from "../topology.service";
+import {Topology} from "../topology";
+
+
+@Component({
+ selector: 'app-resource',
+ templateUrl: './resource.component.html',
+ styleUrls: ['./resource.component.css']
+})
+export class ResourceComponent implements OnInit {
+
+ resourceType: string;
+
+ value: any;
+ resources: Resource[];
+ selectedResource: Resource;
+
+ constructor(private resourceTypesService: ResourceTypesService,
+ private resourceService: ResourceService,
+ private topologyService: TopologyService) { }
+
+
+ ngOnInit() {
+ this.resourceTypesService.selectedResourceType$.subscribe(value => this.setResourceType(value));
+ }
+
+
+ setResourceType(resType: string) {
+ this.resourceType = resType;
+ this.resourceService.selectedResourceType(this.resourceType);
+ this.resources = []; // Clear the table before loading the new resources
+ this.resourceService.getResources(resType).then(resources => {
+ this.resources = resources;
+ console.log('Found ' + resources.length + ' ' + this.resourceType + ' resources');
+ for (let resource of resources) {
+ console.log('Resource: ' + resource.name);
+ }
+ });
+ }
+
+ onSelect(resource: Resource) {
+ this.selectedResource = resource;
+
+ // If it's a topology resource, notify the topology service
+ if (this.resourceType === 'Topologies') {
+ let topology = new Topology();
+ topology.name = resource.name;
+ topology.href = resource.href;
+ this.topologyService.selectedTopology(topology);
+ } else {
+ // Otherwise, notify the resource service
+ this.resourceService.selectedResource(resource);
+ }
+ }
+
+
+ getResourceTypeSingularDisplayName(resType: string): string {
+ switch(resType) {
+ case 'Topologies': {
+ return 'Topology';
+ }
+ case 'Provider Configurations':
+ case 'Descriptors': {
+ return resType.substring(0, resType.length - 1);
+ }
+ default: {
+ return 'Resource';
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resource/resource.service.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resource/resource.service.ts b/gateway-admin-ui/src/app/resource/resource.service.ts
new file mode 100644
index 0000000..009ca2a
--- /dev/null
+++ b/gateway-admin-ui/src/app/resource/resource.service.ts
@@ -0,0 +1,199 @@
+/*
+ * 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 { Injectable } from '@angular/core';
+import { HttpHeaders, HttpClient} from '@angular/common/http';
+import 'rxjs/add/operator/toPromise';
+import { Subject } from 'rxjs/Subject';
+import { Resource } from './resource';
+
+
+@Injectable()
+export class ResourceService {
+
+ apiUrl = '/gateway/manager/api/v1/';
+ providersUrl = this.apiUrl + 'providerconfig';
+ descriptorsUrl = this.apiUrl + 'descriptors';
+ topologiesUrl = this.apiUrl + 'topologies';
+
+ selectedResourceTypeSource = new Subject<string>();
+ selectedResourceType$ = this.selectedResourceTypeSource.asObservable();
+
+ selectedResourceSource = new Subject<Resource>();
+ selectedResource$ = this.selectedResourceSource.asObservable();
+
+ changedResourceSource = new Subject<string>();
+ changedResource$ = this.changedResourceSource.asObservable();
+
+ constructor(private http: HttpClient) { }
+
+ getResources(resType: string): Promise<Resource[]> {
+ switch(resType) {
+ case 'Provider Configurations': {
+ return this.getProviderConfigResources();
+ }
+ case 'Descriptors': {
+ return this.getDescriptorResources();
+ }
+ case 'Topologies': {
+ return this.getTopologyResources();
+ }
+ }
+ }
+
+ getProviderConfigResources(): Promise<Resource[]> {
+ let headers = new HttpHeaders();
+ headers = this.addJsonHeaders(headers);
+ return this.http.get(this.providersUrl, { headers: headers })
+ .toPromise()
+ .then(response => response['items'] as Resource[])
+ .catch(this.handleError);
+ }
+
+ getDescriptorResources(): Promise<Resource[]> {
+ let headers = new HttpHeaders();
+ headers = this.addJsonHeaders(headers);
+ return this.http.get(this.descriptorsUrl, { headers: headers })
+ .toPromise()
+ .then(response => response['items'] as Resource[])
+ .catch(this.handleError);
+ }
+
+ getTopologyResources(): Promise<Resource[]> {
+ let headers = new HttpHeaders();
+ headers = this.addJsonHeaders(headers);
+ return this.http.get(this.topologiesUrl, { headers: headers })
+ .toPromise()
+ .then(response => response['topologies'].topology as Resource[])
+ .catch(this.handleError);
+ }
+
+ getResource(resType: string, res : Resource): Promise<string> {
+ let headers = new HttpHeaders();
+ headers = (resType === 'Topologies') ? this.addXmlHeaders(headers) : this.addHeaders(headers, res.name);
+
+ return this.http.get(res.href, { headers: headers, responseType: 'text' })
+ .toPromise()
+ .then(response => { return response; })
+ .catch(this.handleError);
+ }
+
+ saveResource(url: string, xml : string): Promise<string> {
+ let xheaders = new HttpHeaders();
+ this.addXmlHeaders(xheaders);
+ this.addCsrfHeaders(xheaders);
+ return this.http.put(url, xml, {headers: xheaders})
+ .toPromise()
+ .then(() => xml)
+ .catch(this.handleError);
+ }
+
+ createResource(name: string, xml : string): Promise<string> {
+ let xheaders = new HttpHeaders();
+ this.addXmlHeaders(xheaders);
+ this.addCsrfHeaders(xheaders);
+ let url = this.topologiesUrl + "/" + name;
+ return this.http.put(url, xml, {headers: xheaders})
+ .toPromise()
+ .then(() => xml)
+ .catch(this.handleError);
+ }
+
+ deleteResource(href: string): Promise<string> {
+ let headers = new HttpHeaders();
+ this.addJsonHeaders(headers);
+ this.addCsrfHeaders(headers);
+ return this.http.delete(href, { headers: headers } )
+ .toPromise()
+ .then(response => response)
+ .catch(this.handleError);
+ }
+
+ addHeaders(headers: HttpHeaders, resName: string): HttpHeaders {
+ let ext = resName.split('.').pop();
+ switch(ext) {
+ case 'xml': {
+ headers = this.addXmlHeaders(headers);
+ break;
+ }
+ case 'json': {
+ headers = this.addJsonHeaders(headers);
+ break;
+ }
+ case 'yaml':
+ case 'yml': {
+ headers = this.addTextPlainHeaders(headers);
+ break;
+ }
+ }
+ return headers;
+ }
+
+ addTextPlainHeaders(headers: HttpHeaders) {
+ return headers.append('Accept', 'text/plain')
+ .append('Content-Type', 'text/plain');
+ }
+
+ addJsonHeaders(headers: HttpHeaders): HttpHeaders {
+ return headers.append('Accept', 'application/json')
+ .append('Content-Type', 'application/json');
+ }
+
+ addXmlHeaders(headers: HttpHeaders): HttpHeaders {
+ return headers.append('Accept', 'application/xml')
+ .append('Content-Type', 'application/xml');
+ }
+
+ addCsrfHeaders(headers: HttpHeaders): HttpHeaders {
+ return headers.append('X-XSRF-Header', 'admin-ui');
+ }
+
+ selectedResourceType(value: string) {
+ this.selectedResourceTypeSource.next(value);
+ }
+
+ selectedResource(value: Resource) {
+ this.selectedResourceSource.next(value);
+ }
+
+ changedResource(value: string) {
+ this.changedResourceSource.next(value);
+ }
+
+
+ public getResourceDisplayName(res: Resource): string {
+ if (res.name) {
+ let idx = res.name.lastIndexOf('.');
+ return idx >0 ? res.name.substring(0, res.name.lastIndexOf('.')) : res.name;
+ } else {
+ return null;
+ }
+ }
+
+ private handleError(error: any): Promise<any> {
+ console.error('An error occurred', error); // for demo purposes only
+ return Promise.reject(error.message || error);
+ }
+
+ private logHeaders(headers: HttpHeaders) {
+ console.log('Header count: ' + headers.keys().length);
+ headers.keys().forEach(key => {
+ console.log('Header: ' + key + '=' + headers.get(key));
+ });
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resource/resource.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resource/resource.ts b/gateway-admin-ui/src/app/resource/resource.ts
new file mode 100644
index 0000000..cb5ba6f
--- /dev/null
+++ b/gateway-admin-ui/src/app/resource/resource.ts
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+export class Resource {
+ timestamp: number;
+ name: string;
+ uri: string;
+ href: string;
+ content: string;
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resource/service.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resource/service.ts b/gateway-admin-ui/src/app/resource/service.ts
new file mode 100644
index 0000000..3997290
--- /dev/null
+++ b/gateway-admin-ui/src/app/resource/service.ts
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+export class Service {
+ name: string;
+ params: Object;
+ urls: string[]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resourcetypes/resourcetypes.component.css
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resourcetypes/resourcetypes.component.css b/gateway-admin-ui/src/app/resourcetypes/resourcetypes.component.css
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resourcetypes/resourcetypes.component.html
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resourcetypes/resourcetypes.component.html b/gateway-admin-ui/src/app/resourcetypes/resourcetypes.component.html
new file mode 100644
index 0000000..8909df3
--- /dev/null
+++ b/gateway-admin-ui/src/app/resourcetypes/resourcetypes.component.html
@@ -0,0 +1,14 @@
+<div class="table-responsive" style="max-height: 400px; width:100%; overflow: auto;">
+ <table class="table table-hover">
+ <thead><tr><th>Resource Types</th></tr></thead>
+ <tbody>
+ <tr *ngFor="let type of resourceTypes"
+ [class.selected]="type === selectedResourceType"
+ [class.active]="type === selectedResourceType"
+ (click)="onSelect(type)"
+ class="clickable">
+ <td>{{type}}</td>
+ </tr>
+ </tbody>
+ </table>
+</div>
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resourcetypes/resourcetypes.component.spec.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resourcetypes/resourcetypes.component.spec.ts b/gateway-admin-ui/src/app/resourcetypes/resourcetypes.component.spec.ts
new file mode 100644
index 0000000..43bdf40
--- /dev/null
+++ b/gateway-admin-ui/src/app/resourcetypes/resourcetypes.component.spec.ts
@@ -0,0 +1,41 @@
+/*
+ * 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 { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ResourcetypesComponent } from './resourcetypes.component';
+
+describe('ResourcetypesComponent', () => {
+ let component: ResourcetypesComponent;
+ let fixture: ComponentFixture<ResourcetypesComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ResourcetypesComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ResourcetypesComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resourcetypes/resourcetypes.component.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resourcetypes/resourcetypes.component.ts b/gateway-admin-ui/src/app/resourcetypes/resourcetypes.component.ts
new file mode 100644
index 0000000..ae98b5d
--- /dev/null
+++ b/gateway-admin-ui/src/app/resourcetypes/resourcetypes.component.ts
@@ -0,0 +1,44 @@
+/*
+ * 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, Injectable, OnInit } from '@angular/core';
+import { ResourceTypesService } from '../resourcetypes/resourcetypes.service';
+
+@Component({
+ selector: 'app-resourcetypes',
+ templateUrl: './resourcetypes.component.html',
+ styleUrls: ['./resourcetypes.component.css']
+})
+
+@Injectable()
+export class ResourcetypesComponent implements OnInit {
+
+ resourceTypes = [];
+ selectedResourceType;
+
+ constructor(private resourceTypeService: ResourceTypesService) {
+ }
+
+ ngOnInit() {
+ this.resourceTypes = this.resourceTypeService.getResourceTypes();
+ }
+
+ onSelect(resType: string) {
+ this.selectedResourceType = resType;
+ this.resourceTypeService.selectResourceType(resType);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/resourcetypes/resourcetypes.service.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resourcetypes/resourcetypes.service.ts b/gateway-admin-ui/src/app/resourcetypes/resourcetypes.service.ts
new file mode 100644
index 0000000..456d22f
--- /dev/null
+++ b/gateway-admin-ui/src/app/resourcetypes/resourcetypes.service.ts
@@ -0,0 +1,37 @@
+/*
+ * 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 { Injectable, OnInit } from '@angular/core';
+import { Subject } from 'rxjs/Subject';
+
+@Injectable()
+export class ResourceTypesService {
+
+ resourceTypes = ['Provider Configurations', 'Descriptors', 'Topologies'];
+ selectedResourceTypeSource = new Subject<string>();
+ public selectedResourceType$ = this.selectedResourceTypeSource.asObservable();
+
+ constructor() {
+ }
+
+ getResourceTypes(): string[] {
+ return this.resourceTypes;
+ }
+
+ selectResourceType(resType: string) {
+ this.selectedResourceTypeSource.next(resType);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/topology-detail.component.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/topology-detail.component.ts b/gateway-admin-ui/src/app/topology-detail.component.ts
index e93aaaa..a4e4713 100644
--- a/gateway-admin-ui/src/app/topology-detail.component.ts
+++ b/gateway-admin-ui/src/app/topology-detail.component.ts
@@ -14,11 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { Component, OnInit, ViewChild, ViewEncapsulation} from '@angular/core';
+import { Component, OnInit, ViewChild } from '@angular/core';
import { Topology } from './topology';
-import {TopologyService} from "./topology.service";
-import { ModalComponent } from 'ng2-bs3-modal/ng2-bs3-modal';
-import { ViewChildren } from '@angular/core/src/metadata/di';
+import { TopologyService } from "./topology.service";
+import { BsModalComponent } from 'ng2-bs3-modal/ng2-bs3-modal';
+import { ResourceService } from "./resource/resource.service";
import 'brace/theme/monokai';
import 'brace/mode/xml';
@@ -27,59 +27,62 @@ import 'brace/mode/xml';
selector: 'topology-detail',
template: `
<div class="panel panel-default">
- <div class="panel-heading">
- <h4 class="panel-title">{{title}} <span *ngIf="showEditOptions == false" style="padding-left: 15%;" class="text-danger text-center" > Ready Only (generated file) </span> <span class="label label-default pull-right">{{titleSuffix}}</span></h4>
- </div>
- <div *ngIf="topologyContent" class="panel-body">
- <ace-editor
- [(text)]="topologyContent"
- [mode]="'xml'"
- [options]="options"
- [theme]="theme"
- style="min-height: 430px; width:100%; overflow: auto;"
- (textChanged)="onChange($event)">
- </ace-editor>
- <div *ngIf="showEditOptions" class="panel-footer">
- <button id="duplicateTopology" (click)="duplicateModal.open('sm')" class="btn btn-default btn-sm" type="submit" >
- <span class="glyphicon glyphicon-duplicate" aria-hidden="true"></span>
- </button>
- <button id="deleteTopology" (click)="deleteConfirmModal.open('sm')" class="btn btn-default btn-sm" type="submit" >
- <span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
- </button>
- <button id="saveTopology" (click)="saveTopology()" class="btn btn-default btn-sm pull-right" [disabled]="!changedTopology" type="submit" >
- <span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>
- </button>
+ <div class="panel-heading">
+ <h4 class="panel-title">{{title}} <span *ngIf="showEditOptions == false" style="padding-left: 15%;" class="text-danger text-center" > Ready Only (generated file) </span> <span class="pull-right">{{titleSuffix}}</span></h4>
</div>
+ <div *ngIf="topologyContent" class="panel-body">
+ <ace-editor
+ [(text)]="topologyContent"
+ [mode]="'xml'"
+ [options]="options"
+ [theme]="theme"
+ [readOnly]="!showEditOptions"
+ style="min-height: 430px; width:100%; overflow: auto;"
+ (textChanged)="onChange($event)">
+ </ace-editor>
+ <div *ngIf="showEditOptions" class="panel-footer">
+ <button id="duplicateTopology" (click)="duplicateModal.open('sm')" class="btn btn-default btn-sm" type="submit" >
+ <span class="glyphicon glyphicon-duplicate" aria-hidden="true"></span>
+ </button>
+ <button id="deleteTopology" (click)="deleteConfirmModal.open('sm')" class="btn btn-default btn-sm" type="submit" >
+ <span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
+ </button>
+ <button id="saveTopology" (click)="saveTopology()" class="btn btn-default btn-sm pull-right" [disabled]="!changedTopology" type="submit" >
+ <span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>
+ </button>
+ </div>
- </div>
- <modal (onClose)="createTopology()" #duplicateModal>
-
- <modal-header [show-close]="true">
- <h4 class="modal-title">Create a copy</h4>
- </modal-header>
- <modal-body>
- <div class="form-group">
- <label for="textbox">Name the new topology</label>
- <input autofocus type="text" class="form-control" required [(ngModel)]="newTopologyName" id="textbox">
- </div>
- </modal-body>
- <modal-footer>
- <button type="button" class="btn btn-default btn-sm" data-dismiss="duplicateModal" (click)="duplicateModal.dismiss()">Cancel</button>
- <button type="button" class="btn btn-primary btn-sm" [disabled]="!newTopologyName" (click)="duplicateModal.close()">Ok</button>
- </modal-footer>
- </modal>
- <modal (onClose)="deleteTopology()" #deleteConfirmModal>
- <modal-header [show-close]="true">
- <h4 class="modal-title">Deleting Topology {{titleSuffix}}</h4>
- </modal-header>
- <modal-body>
- Are you sure you want to delete the topology?
- </modal-body>
- <modal-footer>
- <button type="button" class="btn btn-default btn-sm" data-dismiss="deleteConfirmModal" (click)="deleteConfirmModal.dismiss()">Cancel</button>
- <button type="button" class="btn btn-primary btn-sm" (click)="deleteConfirmModal.close()">Ok</button>
- </modal-footer>
- </modal>
+ </div>
+ <bs-modal (onClose)="createTopology()" #duplicateModal>
+ <!--<bs-modal-header [show-close]="true">-->
+ <bs-modal-header>
+ <h4 class="modal-title">Create a copy</h4>
+ </bs-modal-header>
+ <bs-modal-body>
+ <div class="form-group">
+ <label for="textbox">Name the new topology</label>
+ <input autofocus type="text" class="form-control" required [(ngModel)]="newTopologyName" id="textbox">
+ </div>
+ </bs-modal-body>
+ <bs-modal-footer>
+ <button type="button" class="btn btn-default btn-sm" data-dismiss="duplicateModal" (click)="duplicateModal.dismiss()">Cancel</button>
+ <button type="button" class="btn btn-primary btn-sm" [disabled]="!newTopologyName" (click)="duplicateModal.close()">Ok</button>
+ </bs-modal-footer>
+ </bs-modal>
+ <bs-modal (onClose)="deleteTopology()" #deleteConfirmModal>
+ <!--<bs-modal-header [show-close]="true">-->
+ <bs-modal-header>
+ <h4 class="modal-title">Deleting Topology {{titleSuffix}}</h4>
+ </bs-modal-header>
+ <bs-modal-body>
+ Are you sure you want to delete the topology?
+ </bs-modal-body>
+ <bs-modal-footer>
+ <button type="button" class="btn btn-default btn-sm" data-dismiss="deleteConfirmModal" (click)="deleteConfirmModal.dismiss()">Cancel</button>
+ <button type="button" class="btn btn-primary btn-sm" (click)="deleteConfirmModal.close()">Ok</button>
+ </bs-modal-footer>
+ </bs-modal>
+ </div>
`
})
export class TopologyDetailComponent implements OnInit {
@@ -96,14 +99,14 @@ export class TopologyDetailComponent implements OnInit {
options:any = {useWorker: false, printMargin: false};
@ViewChild('duplicateModal')
- duplicateModal: ModalComponent;
+ duplicateModal: BsModalComponent;
@ViewChild('deleteConfirmModal')
- deleteConfirmModal: ModalComponent;
+ deleteConfirmModal: BsModalComponent;
@ViewChild('editor') editor;
- constructor(private topologyService : TopologyService) {
+ constructor(private topologyService : TopologyService, private resourceService: ResourceService) {
}
ngOnInit(): void {
@@ -152,12 +155,12 @@ export class TopologyDetailComponent implements OnInit {
* provided tag value make the editor read only
*/
makeReadOnly(text, tag) {
- var parser = new DOMParser();
- var parsed = parser.parseFromString(text,"text/xml");
+ let parser = new DOMParser();
+ let parsed = parser.parseFromString(text,"text/xml");
+
+ let tagValue = parsed.getElementsByTagName(tag);
+ let result = tagValue[0].childNodes[0].nodeValue;
- var tagValue = parsed.getElementsByTagName(tag);
- var result = tagValue[0].childNodes[0].nodeValue;
-
if(result === 'true') {
this.showEditOptions = false;
this.options = {readOnly: true, useWorker: false, printMargin: false, highlightActiveLine: false, highlightGutterLine: false};
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/topology.component.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/topology.component.ts b/gateway-admin-ui/src/app/topology.component.ts
index d0d17a6..3d6b7a2 100644
--- a/gateway-admin-ui/src/app/topology.component.ts
+++ b/gateway-admin-ui/src/app/topology.component.ts
@@ -14,9 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import {Component, OnInit} from '@angular/core';
-import {Topology} from './topology';
-import {TopologyService} from "./topology.service";
+import { Component, OnInit } from '@angular/core';
+import { Topology } from './topology';
+import { TopologyService } from './topology.service';
import { Subscription } from 'rxjs/Subscription';
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/app/topology.service.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/topology.service.ts b/gateway-admin-ui/src/app/topology.service.ts
index 15d9986..dc2559f 100644
--- a/gateway-admin-ui/src/app/topology.service.ts
+++ b/gateway-admin-ui/src/app/topology.service.ts
@@ -15,12 +15,10 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
-import { Headers, Http } from '@angular/http';
+import { HttpHeaders, HttpClient } from '@angular/common/http';
import 'rxjs/add/operator/toPromise';
import { Subject } from 'rxjs/Subject';
-import { Observable } from 'rxjs/Observable';
-
import { Topology } from './topology';
@Injectable()
@@ -33,37 +31,37 @@ export class TopologyService {
changedTopologySource = new Subject<string>();
changedTopology$ = this.changedTopologySource.asObservable();
- constructor(private http: Http) { }
+ constructor(private http: HttpClient) { }
getTopologies(): Promise<Topology[]> {
- let headers = new Headers();
+ let headers = new HttpHeaders();
this.addJsonHeaders(headers);
return this.http.get(this.topologiesUrl, {
headers: headers
} )
.toPromise()
- .then(response => response.json().topologies.topology as Topology[])
+ .then(response => response['topologies'].topology as Topology[])
.catch(this.handleError);
}
getTopology(href : string): Promise<string> {
- let headers = new Headers();
- this.addXmlHeaders(headers);
+ let headers = new HttpHeaders();
+ headers = this.addXmlHeaders(headers);
return this.http.get(href, {
- headers: headers
+ headers: headers, responseType: 'text'
} )
.toPromise()
- .then(response => response.text())
+ .then(response => response)
.catch(this.handleError);
}
saveTopology(url: string, xml : string): Promise<string> {
- let xheaders = new Headers();
- this.addXmlHeaders(xheaders);
- this.addCsrfHeaders(xheaders);
+ let xheaders = new HttpHeaders();
+ xheaders = this.addXmlHeaders(xheaders);
+ xheaders = this.addCsrfHeaders(xheaders);
return this.http
- .put(url, xml, {headers: xheaders})
+ .put(url, xml, { headers: xheaders, responseType: 'text' })
.toPromise()
.then(() => xml)
.catch(this.handleError);
@@ -71,41 +69,41 @@ export class TopologyService {
}
createTopology(name: string, xml : string): Promise<string> {
- let xheaders = new Headers();
- this.addXmlHeaders(xheaders);
- this.addCsrfHeaders(xheaders);
+ let xheaders = new HttpHeaders();
+ xheaders = this.addXmlHeaders(xheaders);
+ xheaders = this.addCsrfHeaders(xheaders);
let url = this.topologiesUrl + "/" + name;
return this.http
- .put(url, xml, {headers: xheaders})
+ .put(url, xml, { headers: xheaders, responseType: 'text' })
.toPromise()
.then(() => xml)
.catch(this.handleError);
}
deleteTopology(href: string): Promise<string> {
- let headers = new Headers();
- this.addJsonHeaders(headers);
- this.addCsrfHeaders(headers);
+ let headers = new HttpHeaders();
+ headers = this.addJsonHeaders(headers);
+ headers = this.addCsrfHeaders(headers);
return this.http.delete(href, {
- headers: headers
+ headers: headers, responseType: 'text'
} )
.toPromise()
- .then(response => response.text())
+ .then(response => response)
.catch(this.handleError);
}
- addJsonHeaders(headers: Headers) {
- headers.append('Accept', 'application/json');
- headers.append('Content-Type', 'application/json');
+ addJsonHeaders(headers: HttpHeaders): HttpHeaders {
+ return headers.append('Accept', 'application/json')
+ .append('Content-Type', 'application/json');
}
- addXmlHeaders(headers: Headers) {
- headers.append('Accept', 'application/xml');
- headers.append('Content-Type', 'application/xml');
+ addXmlHeaders(headers: HttpHeaders): HttpHeaders {
+ return headers.append('Accept', 'application/xml')
+ .append('Content-Type', 'application/xml');
}
- addCsrfHeaders(headers: Headers) {
- headers.append('X-XSRF-Header', 'admin-ui');
+ addCsrfHeaders(headers: HttpHeaders): HttpHeaders {
+ return headers.append('X-XSRF-Header', 'admin-ui');
}
selectedTopology(value: Topology) {
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/index.html
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/index.html b/gateway-admin-ui/src/index.html
index 02bc3bd..e2b3be4 100644
--- a/gateway-admin-ui/src/index.html
+++ b/gateway-admin-ui/src/index.html
@@ -19,20 +19,23 @@
<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">
+ <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">
- <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
- <!-- Latest compiled and minified JavaScript -->
- <script 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>
+ <!-- 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/1.12.4/jquery.min.js"></script>
+ <!-- Latest compiled and minified JavaScript -->
+ <script 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>
+ <!--
+ <script src="assets/esprima.js"></script>
+ <script src="assets/js-yaml.min.js"></script>
+ -->
</head>
<body>
<div class="navbar-wrapper">
@@ -47,34 +50,18 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
- <a class="navbar-brand" href="#"> <img style="max-width:100px; margin-top: -9px;" src="assets/knox-logo-transparent.gif" alt="Apache Knox Manager"> </a>
+ <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 id="navbar" class="navbar-collapse collapse">
- <ul class="nav navbar-nav navbar-right">
- <li><a href="./">Logout</a></li>
- </ul>
- </div>-->
</div>
</nav>
</div>
- <div class="container">
-
- <!-- Main component for a primary marketing message or call to action -->
- <!--
- <div class="jumbotron">
- <h3>Topology Management</h3>
- <p>Resource Access Management</p>
- </div>
- -->
- </div>
-
<!-- Content -->
- <topology-management></topology-management>
+ <resource-management></resource-management>
<footer class="footer">
- <div>Knox Manager Version 0.0.1</div>
+ <div>Knox Manager Version 0.1.0</div>
<gateway-version></gateway-version>
</footer>
</body>
http://git-wip-us.apache.org/repos/asf/knox/blob/e8ba712c/gateway-admin-ui/src/styles.css
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/styles.css b/gateway-admin-ui/src/styles.css
index 90d4ee0..b6aa3e6 100644
--- a/gateway-admin-ui/src/styles.css
+++ b/gateway-admin-ui/src/styles.css
@@ -1 +1,7 @@
/* You can add global styles to this file, and also import other style files */
+
+.navbar-static-top {
+ min-height: 110px;
+}
+
+.clickable { cursor: pointer; }
\ No newline at end of file