List private apis for developers
MODIFY
src/app/api-data.service.ts
src/app/api-data.service.ts
import {Inject, Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
-import {Observable} from 'rxjs';
+import {from, Observable} from 'rxjs';
+import {mergeMap} from 'rxjs/operators';
-export interface ApiSearchData {
- beans: Array<ApiDetails>;
- totalSize: number;
-}
-
-export interface ApiDetails {
- name: string;
- id: string;
- description: string;
- createdOn: string;
- organizationName: string;
- organizationId: string;
-}
-
-export interface ApiEndpointDetails {
- managedEndpoint: string;
-}
-
-export interface ApiKeyDetails {
- apiKey: string;
-}
-
-export interface ClientDetails {
- name: string;
- id: string;
- description: string;
- organizationName: string;
- organizationId: string;
- numContracts: number;
-}
-
-export interface ApiVersionsDetails {
- name: string;
- id: string;
- description: string;
- version: string;
+/**
+ * Api Version
+ */
+export interface ApiVersion {
+ id: number;
+ api: Api;
status: 'Created' | 'Ready' | 'Published' | 'Retired';
- organizationName: string;
- organizationId: string;
+ endpoint: string;
+ endpointType: 'rest' | 'soap';
+ endpointContentType: 'json' | 'xml';
+ endpointProperties: object;
+ gateways: Array<Gateway>;
publicAPI: boolean;
-}
-
-export interface ClientVersionDetails {
- name: string;
- id: string;
- description: string;
- version: string;
- status: 'Created' | 'Ready' | 'Registered' | 'Retired';
- apiKey: string;
- organizationName: string;
- organizationId: string;
-}
-
-export interface ContractDetails {
- createdOn: string;
- clientVersion: string;
- apiVersion: string;
- planVersion: string;
- clientOrganizationId: string;
- clientOrganizationName: string;
- apiOrganizationId: string;
- apiOrganizationName: string;
- apiDescription: string;
- clientId: string;
- planName: string;
- contractId: number;
- apiName: string;
- clientName: string;
- planId: string;
- apiId: string;
-}
-
-export interface ApiVersionDetails {
- id: number;
+ plans: Array<Plan>;
version: string;
- status: 'Created' | 'Ready' | 'Published' | 'Retired';
- modifiedOn: string;
- createdOn: string;
- modifiedBy: string;
createdBy: string;
+ createdOn: number;
+ modifiedBy: string;
+ modifiedOn: number;
+ publishedOn: number;
retiredOn: string;
- publishedOn: string;
- api: Api;
definitionType: 'None' | 'SwaggerJSON' | 'SwaggerYAML' | 'WSDL' | 'WADL' | 'RAML' | 'External';
- endpointContentType: 'json' | 'xml';
- endpointProperties: object;
- endpointType: 'rest' | 'soap';
- plans: Array<Plan>;
- endpoint: string;
- publicAPI: boolean;
parsePayload: boolean;
- gateways: Array<Gateway>;
+ definitionUrl: string;
}
+/**
+ * Plan
+ */
export interface Plan {
version: string;
planId: string;
}
+/**
+ * Gateway
+ */
export interface Gateway {
gatewayId: string;
}
+/**
+ * Api definition
+ */
export interface Api {
- name: string;
+ organization: Organization;
id: string;
+ name: string;
description: string;
- organization: Organization;
- createdOn: string;
createdBy: string;
+ createdOn: number;
numPublished: number;
}
+/**
+ * Organization
+ */
export interface Organization {
+ id: string;
name: string;
+ description: string;
+ createdBy: string;
+ createdOn: number;
+ modifiedBy: string;
+ modifiedOn: number;
+}
+
+/**
+ * Client
+ */
+export interface Client {
+ organizationId: string;
+ organizationName: string;
id: string;
+ name: string;
description: string;
- modifiedOn: string;
+ status: 'Created' | 'Ready' | 'Registered' | 'Retired';
+ version: string;
+ apiKey: string;
+}
+
+/**
+ * Contract
+ */
+export interface Contract {
+ contractId: number;
+ clientOrganizationId: string;
+ clientOrganizationName: string;
+ clientId: string;
+ clientName: string;
+ clientVersion: string;
+ apiOrganizationId: string;
+ apiOrganizationName: string;
+ apiId: string;
+ apiName: string;
+ apiVersion: string;
+ apiDescription: string;
+ planName: string;
+ planId: string;
+ planVersion: string;
createdOn: string;
- modifiedBy: string;
- createdBy: string;
}
+/**
+ * Gateway Details
+ */
export interface GatewayDetails {
name: string;
id: string;
@@ -132,6 +116,9 @@ export interface GatewayDetails {
description: string;
}
+/**
+ * Gateway Endpoint
+ */
export interface GatewayEndpoint {
endpoint: string;
}
@@ -144,59 +131,53 @@ export interface GatewayEndpoint {
* A service which executes the REST calls to Apiman UI REST Interface
*/
export class ApiDataService {
- constructor(private http: HttpClient, @Inject('APIMAN_UI_REST_URL') private apimanUiRestUrl: string) { }
- public getAllApis(): Observable<ApiSearchData> {
- const url = this.apimanUiRestUrl + '/search/apis/';
- const body = { filters: [{name: 'name', value: '***', operator: 'like'}], page: 1, pageSize: 10000};
- return this.http.post(url, body) as Observable<ApiSearchData>;
- }
-
- public getApiEndpoint(organizationId, apiId, apiVersion) {
- const url = this.apimanUiRestUrl + '/organizations/' + organizationId + '/apis/' + apiId + '/versions/' + apiVersion + '/endpoint/';
- return this.http.get(url) as Observable<ApiEndpointDetails>;
- }
-
- public getApiKey(organizationId, clientId, clientVersion) {
- const url = this.apimanUiRestUrl + '/organizations/' + organizationId + '/clients/' + clientId + '/versions/' + clientVersion + '/apikey/';
- return this.http.get(url) as Observable<ApiKeyDetails>;
- }
-
- public getUserClients() {
- const url = this.apimanUiRestUrl + '/currentuser/clients/';
- return this.http.get(url) as Observable<Array<ClientDetails>>;
- }
-
- public getUserApis() {
- const url = this.apimanUiRestUrl + '/currentuser/apis/';
- return this.http.get(url) as Observable<Array<ApiDetails>>;
- }
-
- public getApiVersions(organizationId, apiId) {
- const url = this.apimanUiRestUrl + '/organizations/' + organizationId + '/apis/' + apiId + '/versions/';
- return this.http.get(url) as Observable<Array<ApiVersionsDetails>>;
- }
+ /**
+ * Contructor
+ * @param http The http client
+ * @param apimanUiRestUrl The apiman UI REST url
+ */
+ constructor(private http: HttpClient, @Inject('APIMAN_UI_REST_URL') private apimanUiRestUrl: string) { }
- public getApiVersionDetails(organizationId, apiId, apiVersion) {
- const url = this.apimanUiRestUrl + '/organizations/' + organizationId + '/apis/' + apiId + '/versions/' + apiVersion;
- return this.http.get(url) as Observable<ApiVersionDetails>;
+ /**
+ * Get developer clients by developer id
+ * @param developerId The developer Id
+ */
+ public getDeveloperClients(developerId: string) {
+ const url = this.apimanUiRestUrl + '/developers/' + developerId + '/clients';
+ return this.http.get(url) as Observable<Array<Client>>;
}
- public getClientVersions(organizationId, clientId) {
- const url = this.apimanUiRestUrl + '/organizations/' + organizationId + '/clients/' + clientId + '/versions/';
- return this.http.get(url) as Observable<Array<ClientVersionDetails>>;
+ /**
+ * Get developer contracts by developer id
+ * @param developerId The developer Id
+ */
+ public getDeveloperContracts(developerId: string) {
+ const url = this.apimanUiRestUrl + '/developers/' + developerId + '/contracts';
+ return this.http.get(url) as Observable<Array<Contract>>;
}
- public getContracts(organizationId, clientId, clientVersion) {
- const url = this.apimanUiRestUrl + '/organizations/' + organizationId + '/clients/' + clientId + '/versions/' + clientVersion + '/contracts';
- return this.http.get(url) as Observable<Array<ContractDetails>>;
+ /**
+ * Get developer apis by developer id
+ * @param developerId The developer Id
+ */
+ public getDeveloperApis(developerId: string) {
+ const url = this.apimanUiRestUrl + '/developers/' + developerId + '/apis';
+ return this.http.get(url) as Observable<Array<ApiVersion>>;
}
+ /**
+ * Get available api gateways
+ */
public getGateways() {
const url = this.apimanUiRestUrl + '/gateways';
return this.http.get(url) as Observable<Array<GatewayDetails>>;
}
+ /**
+ * Get gateway endpoint by gateway id
+ * @param gatewayId The gateway id
+ */
public getGatewayEndpoint(gatewayId) {
const url = this.apimanUiRestUrl + '/gateways/' + gatewayId + '/endpoint';
return this.http.get(url) as Observable<GatewayEndpoint>;

MODIFY
src/app/api-list/api-list.component.html
src/app/api-list/api-list.component.html
<td mat-cell *matCellDef="let element"> {{element.version}} </td>
</ng-container>
<ng-container matColumnDef="ispublic">
- <th mat-header-cell *matHeaderCellDef>is public</th>
- <td mat-cell *matCellDef="let element"> {{element.ispublic}} </td>
+ <th mat-header-cell *matHeaderCellDef>API Organization</th>
+ <td mat-cell *matCellDef="let element"> {{element.organizationName}} </td>
</ng-container>
<ng-container matColumnDef="endpoint">
<th mat-header-cell *matHeaderCellDef>Endpoint</th>
<td mat-cell *matCellDef="let element"> {{element.endpoint}} </td>
</ng-container>
- <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
- <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
+ <tr mat-header-row *matHeaderRowDef="columnHeaders"></tr>
+ <tr mat-row *matRowDef="let row; columns: columnHeaders;"></tr>
</table>

MODIFY
src/app/api-list/api-list.component.ts
src/app/api-list/api-list.component.ts
-import { Component, OnInit } from '@angular/core';
+import { Component, Input, SimpleChanges, OnChanges} from '@angular/core';
import {forkJoin, Observable, from, pipe} from 'rxjs';
import {map, mergeMap, toArray, mergeAll} from 'rxjs/operators';
-import {ApiDataService} from '../api-data.service';
+import {ApiDataService, ApiVersion, Client, Contract} from '../api-data.service';
import {element} from 'protractor';
+import {emit} from 'cluster';
-export interface ApiListView {
+export interface ApiListElement {
id: string;
name: string;
version: string;
endpoint: string;
- ispublic: boolean;
+ organizationName: string;
}
@Component({
- selector: 'app-api-list',
+ selector: 'api-list',
templateUrl: './api-list.component.html',
styleUrls: ['./api-list.component.scss']
})
-export class ApiListComponent implements OnInit {
+export class ApiListComponent implements OnChanges {
- apiData: Array<ApiListView> = [];
+ columnHeaders: string[] = ['ispublic', 'name', 'version', 'endpoint'];
- displayedColumns: string[] = ['ispublic', 'name', 'version', 'endpoint'];
+ apiData: Array<ApiListElement> = [];
+
+ @Input('developerId') developerId;
/**
* An observer to get all gateway details (gateway endpoint) from api data service
@@ -35,42 +38,32 @@ export class ApiListComponent implements OnInit {
.pipe(toArray());
/**
- * An observer to access all data of private apis
+ * An observer to get all developer data from api data service
*/
- getPrivateApiData: Observable<ApiListView> = this.getGatewayDataObservable.pipe(mergeMap(gateways =>
- this.apiDataService.getUserClients()
- .pipe(mergeAll())
- .pipe(mergeMap(userClient =>
- this.apiDataService.getClientVersions(userClient.organizationId, userClient.id)
- .pipe(mergeAll())
- .pipe(mergeMap(clientVersion =>
- this.apiDataService.getContracts(userClient.organizationId, userClient.id, clientVersion.version)
- .pipe(mergeAll())
- .pipe(mergeMap(contract =>
- //fork data to receive api key and api details
- forkJoin(
- this.apiDataService.getApiKey(contract.clientOrganizationId, contract.clientId, contract.clientVersion)
- //extract the api key
- .pipe(map(source => source.apiKey)),
- this.apiDataService.getApiVersionDetails(contract.clientOrganizationId, contract.apiId, contract.apiVersion)
- //determine the first possible gateway endpoint and wether the api is public
- .pipe(map(source => ({gatewayId: source.gateways[0].gatewayId, isPublic: source.publicAPI})))
- //use the contract, gateway and forked api data to construct the view data
- ).pipe(map((forkedApiData) => (this.buildViewData(contract, gateways, forkedApiData[0], forkedApiData[1]))))
- ))
- ))
- ))
- ));
+ getDeveloperData: (developer: string) => Observable<ApiListElement> = (developer: string) => forkJoin(this.apiDataService.getDeveloperClients(developer),
+ this.apiDataService.getDeveloperContracts(developer),
+ this.apiDataService.getDeveloperApis(developer),
+ this.getGatewayDataObservable)
+ .pipe(mergeMap(forkedData => {
+ const [clients, contracts, apiVersions, gateways] = forkedData;
+ return from(contracts)
+ .pipe(map(contract => {
+ const apiVersion = apiVersions.find(version => version.api.id === contract.apiId);
+ const clientVersion = clients.find(version => version.id === contract.clientId);
+ const gateway = gateways.find(g => g.id === apiVersion.gateways[0].gatewayId);
+ return this.buildViewData(contract, gateway, clientVersion, apiVersion);
+ }));
+ }))
constructor(private apiDataService: ApiDataService) {
}
/**
- * ngOnInit is executed if the component is initialized
+ * ngOnChanges is executed if the changes are applied to component
*/
- ngOnInit() {
+ ngOnChanges(changes: SimpleChanges): void {
//subscribe for the private api data to fill the view
- this.getPrivateApiData.subscribe(data => {
+ this.getDeveloperData(this.developerId).subscribe(data => {
this.apiData = this.apiData.concat(data);
});
}
@@ -81,13 +74,13 @@ export class ApiListComponent implements OnInit {
* @param gateways: the gateways which contains the gateway endpoints
* @param apiVersionDetails: the api version data containing the apikey and gateway id
*/
- private buildViewData(contract, gateways, apiKey, apiVersionDetails) {
+ private buildViewData(contract: Contract, gateway, clientVersion: Client, apiVersionDetails: ApiVersion): ApiListElement {
return {
id: contract.apiId,
name: contract.apiName,
version: contract.apiVersion,
- endpoint: this.buildApiEndpoint(gateways.find(g => g.id === apiVersionDetails.gatewayId).endpoint, contract.clientOrganizationId, contract.apiId, contract.apiVersion, apiKey),
- ispublic: apiVersionDetails.isPublic
+ endpoint: this.buildApiEndpoint(gateway.endpoint, contract.apiOrganizationId, contract.apiId, contract.apiVersion, clientVersion.apiKey),
+ organizationName: contract.apiOrganizationId
};
}
@@ -99,7 +92,7 @@ export class ApiListComponent implements OnInit {
* @param apiVersion: version of api
* @param apiKey: apikey of api
*/
- buildApiEndpoint(gatewayEndpoint: string, organizationId: string, apiId: string, apiVersion: string, apiKey: string) {
+ buildApiEndpoint(gatewayEndpoint: string, organizationId: string, apiId: string, apiVersion: string, apiKey: string): string {
return gatewayEndpoint + [organizationId, apiId, apiVersion].join('/') + '?apiKey=' + apiKey;
}

MODIFY
src/app/app.component.html
src/app/app.component.html
<app-pas-header></app-pas-header>
-<app-api-list></app-api-list>
+<div *ngFor="let developerId of developers">
+ <h2 *ngIf="developers.length > 1">{{developerId}}</h2>
+ <api-list [developerId]="developerId"></api-list>
+</div>
+
+<div id="noData" *ngIf="developers.length === 0">
+ <p>No developers defined for this user.</p>
+</div>
<router-outlet></router-outlet>

MODIFY
src/app/app.component.scss
src/app/app.component.scss
+
+h2 {
+ padding-left: 10px;
+ font-weight: normal;
+}
+
+p {
+ text-align: center;
+ vertical-align: bottom;
+}

MODIFY
src/app/app.component.ts
src/app/app.component.ts
import { Component } from '@angular/core';
+import { KeycloakService } from 'keycloak-angular';
@Component({
selector: 'app-root',
@@ -6,5 +7,14 @@ import { Component } from '@angular/core';
styleUrls: ['./app.component.scss']
})
export class AppComponent {
- title = 'API-Mgmt Developer Portal';
+
+ public developers: Array<string> = [];
+
+ constructor(private keycloak: KeycloakService) {
+ // get keycloak client roles of devportal
+ const resourceAccess = this.keycloak.getKeycloakInstance().tokenParsed.resource_access['apiman-devportal'];
+ if (resourceAccess && resourceAccess.roles) {
+ this.developers = resourceAccess.roles;
+ }
+ }
}

GW-251: List private apis for developers