Skip to content

Commit

Permalink
Traffic Portal v2 Topologies details page (#7615)
Browse files Browse the repository at this point in the history
* Traffic Portal v2 Topologies details page

* Require at least trafficops-types version 4.0.11

* Tests pass

* Fix whitespace

* Code review updates

* Add test coverage

* use .toBeDefined()

* Use tab, not space

* Increase topology.service test coverage to 100%

* topologies-new -> new-topology

* Use typeof, not instanceof

* Match call signature of concrete service

* Make topology name field mutable

* Use ngModel
  • Loading branch information
zrhoffman authored Aug 1, 2023
1 parent a86a4a8 commit 1193ccb
Show file tree
Hide file tree
Showing 12 changed files with 816 additions and 8 deletions.
14 changes: 7 additions & 7 deletions experimental/traffic-portal/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion experimental/traffic-portal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"express": "^4.15.2",
"node-forge": "^1.3.1",
"rxjs": "~6.6.0",
"trafficops-types": "^4.0.10",
"trafficops-types": "^4.0.11",
"tslib": "^2.0.0",
"zone.js": "~0.13.0"
},
Expand Down
3 changes: 3 additions & 0 deletions experimental/traffic-portal/src/app/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { MiscAPIsService } from "./misc-apis.service";
import { PhysicalLocationService } from "./physical-location.service";
import { ProfileService } from "./profile.service";
import { ServerService } from "./server.service";
import { TopologyService } from "./topology.service";
import { TypeService } from "./type.service";
import { UserService } from "./user.service";

Expand All @@ -38,6 +39,7 @@ export * from "./misc-apis.service";
export * from "./physical-location.service";
export * from "./profile.service";
export * from "./server.service";
export * from "./topology.service";
export * from "./type.service";
export * from "./user.service";

Expand All @@ -59,6 +61,7 @@ export * from "./user.service";
PhysicalLocationService,
ProfileService,
ServerService,
TopologyService,
TypeService,
UserService,
]
Expand Down
3 changes: 3 additions & 0 deletions experimental/traffic-portal/src/app/api/testing/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
PhysicalLocationService,
ProfileService,
ServerService,
TopologyService,
TypeService,
UserService
} from "..";
Expand All @@ -38,6 +39,7 @@ import { MiscAPIsService as TestingMiscAPIsService } from "./misc-apis.service";
import { PhysicalLocationService as TestingPhysicalLocationService } from "./physical-location.service";
import { ProfileService as TestingProfileService } from "./profile.service";
import { ServerService as TestingServerService } from "./server.service";
import { TopologyService as TestingTopologyService } from "./topology.service";
import { TypeService as TestingTypeService } from "./type.service";
import { UserService as TestingUserService } from "./user.service";

Expand All @@ -60,6 +62,7 @@ import { UserService as TestingUserService } from "./user.service";
{provide: PhysicalLocationService, useClass: TestingPhysicalLocationService},
{provide: ProfileService, useClass: TestingProfileService},
{provide: ServerService, useClass: TestingServerService},
{provide: TopologyService, useClass: TestingTopologyService},
{provide: TypeService, useClass: TestingTypeService},
{provide: UserService, useClass: TestingUserService},
TestingServerService,
Expand Down
154 changes: 154 additions & 0 deletions experimental/traffic-portal/src/app/api/testing/topology.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
* Licensed 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 {
RequestTopology,
ResponseTopology,
ResponseTopologyNode
} from "trafficops-types";

import { TopologyService as ConcreteService, TopTreeNode } from "src/app/api";

/**
* TopologyService expose API functionality relating to Topologies.
*/
@Injectable()
export class TopologyService {
private readonly topologies: ResponseTopology[] = [
{
description: "",
lastUpdated: new Date(),
name: "test",
nodes: [
{
cachegroup: "Edge",
parents: [1],
},
{
cachegroup: "Mid",
parents: [2],
},
{
cachegroup: "Origin",
parents: [],
},
],
},
];

/**
* Gets one or all Topologies from Traffic Ops
*
* @param name The unique name of a single Topology to be returned
* @returns An Array of Topologies
*/
public async getTopologies(name?: string): Promise<Array<ResponseTopology>> {
if (name !== undefined) {
const topology = this.topologies.find(t => t.name === name);
if (!topology) {
throw new Error(`no such Topology ${name}`);
}
return [topology];
}
return this.topologies;
}

/**
* Deletes a Topology.
*
* @param topology The Topology to be deleted, or just its name.
*/
public async deleteTopology(topology: ResponseTopology | string): Promise<void> {
const name = typeof topology === "string" ? topology : topology.name;
const idx = this.topologies.findIndex(t => t.name === name);
if (idx < 0) {
throw new Error(`no such Topology: ${name}`);
}
this.topologies.splice(idx, 1);
}

/**
* Creates a new Topology.
*
* @param topology The Topology to create.
*/
public async createTopology(topology: RequestTopology): Promise<ResponseTopology> {
const nodes: ResponseTopologyNode[] = topology.nodes.map(node => {
if (!Array.isArray(node.parents)) {
node.parents = [];
}
const responseNode: ResponseTopologyNode = {
cachegroup: node.cachegroup,
parents: node.parents || [],
};
return responseNode;
});
const t: ResponseTopology = {
description: topology.description || "",
lastUpdated: new Date(),
name: topology.name,
nodes,
};
this.topologies.push(t);
return t;
}

/**
* Replaces an existing Topology with the provided new definition of a
* Topology.
*
* @param topology The full new definition of the Topology being updated
* @param name What the topology was named before it was updated
*/
public async updateTopology(topology: ResponseTopology, name?: string): Promise<ResponseTopology> {
if (typeof name === "undefined") {
name = topology.name;
}
const idx = this.topologies.findIndex(t => t.name === name);
topology = {
...topology,
lastUpdated: new Date()
};

if (idx < 0) {
throw new Error(`no such Topology: ${topology}`);
}

this.topologies[idx] = topology;
return topology;
}

/**
* Generates a material tree from a topology.
*
* @param topology The topology to generate a material tree from.
* @returns a material tree.
*/
public static topologyToTree(topology: ResponseTopology): Array<TopTreeNode> {
return ConcreteService.topologyToTree(topology);
}

/**
* Generates a topology from a material tree.
*
* @param name The topology name
* @param description The topology description
* @param treeNodes The data for a material tree
* @returns a topology.
*/
public static treeToTopology(name: string, description: string, treeNodes: Array<TopTreeNode>): ResponseTopology {
return ConcreteService.treeToTopology(name, description, treeNodes);
}
}
Loading

0 comments on commit 1193ccb

Please sign in to comment.