added policyService, backend calls and extended Interfaces for plans and policies
ADD
src/app/interfaces/IPolicyExt.ts
+import {IPolicy} from "./ICommunication";
+
+export interface IPolicyExt extends IPolicy {
+ planId: string;
+ planVersion: string;
+ shortName: string;
+ shortDescription: string;
+}

ADD
src/app/interfaces/IPolicySummaryExt.ts
+import {IPolicySummary} from "./ICommunication";
+
+export interface IPolicySummaryExt extends IPolicySummary {
+ planId: string;
+ planVersion: string;
+}

MODIFY
src/app/services/backend/backend.service.ts
src/app/services/backend/backend.service.ts
@@ -4,17 +4,15 @@ import { Observable } from 'rxjs';
import { ConfigService } from '../config/config.service';
import { KeycloakService } from 'keycloak-angular';
import {
- IApi,
+ IApi, IApiPlanSummary,
IApiVersion,
IApiVersionEndpointSummary,
IApiVersionSummary,
- IClient,
- IClientSummary,
IContract,
IContractSummary,
INewContract,
IOrganization,
- IOrganizationSummary,
+ IOrganizationSummary, IPolicy, IPolicySummary,
ISearchCriteria,
ISearchResultsApiSummary,
} from '../../interfaces/ICommunication';
@@ -22,6 +20,7 @@ import {
IClientSummaryBean,
IClientVersionSummaryBean,
} from '../../interfaces/ICommunication';
+import {IPolicySummaryExt} from "../../interfaces/IPolicySummaryExt";
export interface ApiSummaryBean {
organizationId?: string;
@@ -259,6 +258,43 @@ export class BackendService {
) as Observable<IApiVersionEndpointSummary>;
}
+ public getApiVersionPlans(organizationId: string,
+ apiId: string,
+ apiVersion: string): Observable<IApiPlanSummary[]> {
+ const path = `/organizations/${organizationId}/apis/${apiId}/versions/${apiVersion}/plans`
+ return this.http.get<IApiPlanSummary[]>(this.generateUrl(path));
+ }
+
+ public getPlanPolicySummaries(organizationId: string,
+ planId: string,
+ planVersion: string): Observable<IPolicySummaryExt[]> {
+ const path = `/organizations/${organizationId}/plans/${planId}/versions/${planVersion}/policies`
+ return this.http.get<IPolicySummaryExt[]>(this.generateUrl(path))
+ }
+
+ public getPlanPolicy(organizationId: string,
+ planId: string,
+ planVersion: string,
+ policyId: string): Observable<IPolicy> {
+ const path = `/organizations/${organizationId}/plans/${planId}/versions/${planVersion}/policies/${policyId}`
+ return this.http.get<IPolicy>(this.generateUrl(path))
+ }
+
+ public getApiPolicySummaries(organizationId: string,
+ apiId: string,
+ apiVersion: string): Observable<IPolicySummaryExt[]> {
+ const path = `/organizations/${organizationId}/apis/${apiId}/versions/${apiVersion}/policies`
+ return this.http.get<IPolicySummary[]>(this.generateUrl(path)) as Observable<IPolicySummaryExt[]>
+ }
+
+ public getApiPolicy(organizationId: string,
+ apiId: string,
+ apiVersion: string,
+ policyId: string): Observable<IPolicy> {
+ const path = `/organizations/${organizationId}/apis/${apiId}/versions/${apiVersion}/policies/${policyId}`
+ return this.http.get<IPolicy>(this.generateUrl(path))
+ }
+
/********* Helper **********/
private generateUrl(path: string) {
return `${this.endpoint}/${path}`;

MODIFY
src/app/services/plan/plan.service.ts
src/app/services/plan/plan.service.ts
import { Injectable } from '@angular/core';
-import { Plan } from '../../interfaces/plan';
-import { Observable, of } from 'rxjs';
+import {Observable} from 'rxjs';
+import {BackendService} from "../backend/backend.service";
+import {IApiPlanSummary} from "../../interfaces/ICommunication";
@Injectable({
providedIn: 'root',
})
export class PlanService {
- constructor() {}
+ constructor(private backendService: BackendService) {}
+
+ getPlans(organizationId: string,
+ apiId: string,
+ apiVersion: string): Observable<IApiPlanSummary[]> {
+ return this.backendService.getApiVersionPlans(organizationId, apiId, apiVersion)
- // ToDo Change to backend call
- getPlans(): Observable<Plan[]> {
- return of([
- {
- id: '1',
- title: 'Sandbox',
- subtitle: 'Try this Api in a sandbox',
- policies: [
- {
- title: 'Rate Limiting',
- configuration: '500 Requests per day',
- },
- {
- title: 'Quota',
- configuration: '500 MB per day',
- },
- ],
- },
- {
- id: '2',
- title: 'Small Business',
- subtitle: 'For small business just getting started',
- policies: [
- {
- title: 'Rate Limiting',
- configuration: '5000 Requests per day',
- },
- {
- title: 'Quota',
- configuration: '2 GB per day',
- },
- ],
- },
- {
- id: '3',
- title: 'Corporate Plan',
- subtitle: 'For heavy usage business partners',
- policies: [
- {
- title: 'Rate Limiting',
- configuration: '1000 Requests per minute',
- },
- {
- title: 'Quota',
- configuration: '10 GB per hour',
- },
- ],
- },
- ]);
}
+
+
}

ADD
src/app/services/policy/policy.service.spec.ts
+import { TestBed } from '@angular/core/testing';
+
+import { PolicyService } from './policy.service';
+
+describe('PolicyService', () => {
+ let service: PolicyService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(PolicyService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});

ADD
src/app/services/policy/policy.service.ts
+import { Injectable } from '@angular/core';
+import {flatMap} from "rxjs/internal/operators";
+import {IPolicy} from "../../interfaces/ICommunication";
+import {IPolicySummaryExt} from "../../interfaces/IPolicySummaryExt";
+import {IPolicyExt} from "../../interfaces/IPolicyExt";
+import {map, tap} from "rxjs/operators";
+import {BackendService} from "../backend/backend.service";
+import {Observable} from "rxjs";
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PolicyService {
+
+ constructor(private backendService: BackendService) {}
+
+ public getPlanPolicies(orgId: string, planId: string, planVersion: string): Observable<IPolicyExt> {
+ return this.getExtendedPolicySummaries(orgId, planId, planVersion).pipe(
+ flatMap((policySummaries: IPolicySummaryExt[]) => {
+ return policySummaries
+ }),
+ flatMap((policySummary: IPolicySummaryExt) => {
+ return this.getExtendedPlanPolicy(orgId, policySummary);
+ })
+ )
+ };
+
+ public getApiPolicies(orgId: string, apiId: string, apiVersion: string): Observable<IPolicyExt> {
+ return this.backendService.getApiPolicySummaries(orgId, apiId, apiVersion).pipe(
+ flatMap((apiPolicySummaries: IPolicySummaryExt[]) => {
+ return apiPolicySummaries;
+ }),
+ flatMap((apiPolicySummary: IPolicySummaryExt) => {
+ return this.getExtendedApiPolicy(orgId, apiId, apiVersion, apiPolicySummary.id.toString());
+ })
+ )
+ }
+
+ private getExtendedApiPolicy(orgId: string, apiId: string, apiVersion: string, apiPolicyId: string) {
+ return this.backendService.getApiPolicy(orgId, apiId, apiVersion, apiPolicyId).pipe(
+ map((policy: IPolicy) => {
+ const extendedPolicy: IPolicyExt = policy as IPolicyExt;
+ this.extendPolicy(extendedPolicy);
+ return extendedPolicy;
+ })
+ )
+ }
+
+ private getExtendedPlanPolicy(orgId: string, policySummary: IPolicySummaryExt) {
+ return this.backendService.getPlanPolicy(orgId,
+ policySummary.planId,
+ policySummary.planVersion,
+ policySummary.id.toString()).pipe(
+ map((policy: IPolicy) => {
+ return this.extendPlanPolicy(policySummary, policy);
+ })
+ )
+ }
+
+ private extendPolicy(extendedPolicy: IPolicyExt) {
+ const policyConfig = JSON.parse(extendedPolicy.configuration);
+ switch (extendedPolicy.definition.id) {
+ case 'RateLimitingPolicy': {
+ extendedPolicy.shortName = 'Rate Limit'
+ extendedPolicy.shortDescription = `${policyConfig.limit} Request${policyConfig.limit > 1 ? 's' : ''} per ${policyConfig.period}`
+ break;
+ }
+ case 'TransferQuotaPolicy': {
+ extendedPolicy.shortName = 'Quota'
+ extendedPolicy.shortDescription = `${this.formatBytes(policyConfig.limit)} per ${policyConfig.period}`
+ break;
+ }
+ }
+ }
+
+ private extendPlanPolicy(policySummary: IPolicySummaryExt, policy: IPolicy): IPolicyExt {
+ const extendedPolicy: IPolicyExt = policy as IPolicyExt;
+ extendedPolicy.planId = policySummary.planId;
+ extendedPolicy.planVersion = policySummary.planVersion;
+ this.extendPolicy(extendedPolicy);
+ return extendedPolicy;
+ }
+
+ private getExtendedPolicySummaries(orgId: string, planId: string, planVersion: string) {
+ return this.backendService.getPlanPolicySummaries(
+ orgId,
+ planId,
+ planVersion).pipe<IPolicySummaryExt[]>(
+ tap(policySummaries => {
+ policySummaries.forEach(policySummary => {
+ const policySummaryExt = policySummary as IPolicySummaryExt;
+ policySummaryExt.planId = planId
+ policySummaryExt.planVersion = planVersion
+ })
+ })
+ )
+ }
+
+ private formatBytes(bytes: number, decimals = 0): string {
+ // Thankfully taken from https://stackoverflow.com/a/18650828
+ if (bytes === 0) return '0 Bytes';
+
+ const k = 1024;
+ const dm = decimals < 0 ? 0 : decimals;
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
+
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
+
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
+ }
+}

added policyService, backend calls and extended Interfaces for plans and policies