Added subscriber S/C tags
diff --git a/views/ngXosViews/diagnostic/mocks/data/subscribers.json b/views/ngXosViews/diagnostic/mocks/data/subscribers.json
index 26cb9d3..e84673d 100644
--- a/views/ngXosViews/diagnostic/mocks/data/subscribers.json
+++ b/views/ngXosViews/diagnostic/mocks/data/subscribers.json
@@ -13,7 +13,7 @@
"lazy_blocked":false,
"no_sync":false,
"kind":"CordSubscriberRoot",
- "name":"My House",
+ "name":"Marc Twain",
"service_specific_attribute":"{\"url_filter_enable\": false, \"cdn_enable\": false, \"url_filter_level\": \"R\", \"users\": [{\"mac\": \"01:02:03:04:05:06\", \"level\": \"PG_13\", \"id\": 0, \"name\": \"Mom's PC\"}, {\"mac\": \"34:36:3B:C9:B6:A6\", \"id\": 1, \"name\": \"Jill's Laptop\", \"level\": \"PG_13\"}, {\"mac\": \"68:5B:35:9D:91:D5\", \"level\": \"PG_13\", \"id\": 2, \"name\": \"Jack's Laptop\"}, {\"id\": 3, \"mac\": \"90:E2:BA:82:F9:75\", \"name\": \"Dad's PC\", \"level\": \"PG_13\"}], \"firewall_enable\": false}",
"service_specific_id":"123"
},
diff --git a/views/ngXosViews/diagnostic/mocks/data/tenants.json b/views/ngXosViews/diagnostic/mocks/data/tenants.json
index 16ede99..d6288a5 100644
--- a/views/ngXosViews/diagnostic/mocks/data/tenants.json
+++ b/views/ngXosViews/diagnostic/mocks/data/tenants.json
@@ -66,7 +66,8 @@
"subscriber_root": null,
"service_specific_id": null,
"service_specific_attribute": "{\"instance_id\": 1, \"creator_id\": 1}",
- "connect_method": "na"
+ "connect_method": "na",
+ "wan_container_ip": "10.0.1.24"
},
{
"humanReadableName": "ceilometer-tenant-8",
@@ -182,5 +183,28 @@
"service_specific_id": null,
"service_specific_attribute": "{\"creator_id\": 1, \"dependencies\": \"org.onosproject.openflow-base, org.onosproject.olt, org.ciena.onos.ext_notifier, org.ciena.onos.volt_event_publisher\", \"name\": \"vOLT_ONOS_app\", \"install_dependencies\": \"onos-ext-notifier-1.0-SNAPSHOT.oar, onos-ext-volt-event-publisher-1.0-SNAPSHOT.oar\"}",
"connect_method": "na"
+ },
+ {
+ "humanReadableName": "vCPE-tenant-4",
+ "id": 14,
+ "created": "2016-02-17T19:36:04.650Z",
+ "updated": "2016-02-17T20:55:18.115Z",
+ "enacted": null,
+ "policed": null,
+ "backend_register": "{\"next_run\": 1455771318.072057, \"last_failure\": 1455742518.072061, \"last_success\": 1455737797.006782, \"exponent\": 871, \"failures\": 871}",
+ "backend_status": "2 - Exception('defer object vCPE-tenant-4 due to waiting on instance.instance_name',)",
+ "deleted": false,
+ "write_protect": false,
+ "lazy_blocked": false,
+ "no_sync": false,
+ "kind": "vCPE",
+ "provider_service": 2,
+ "subscriber_service": null,
+ "subscriber_tenant": "3",
+ "subscriber_user": null,
+ "subscriber_root": null,
+ "service_specific_id": null,
+ "service_specific_attribute": "{\"instance_id\": 11, \"creator_id\": 1}",
+ "connect_method": "na"
}
]
\ No newline at end of file
diff --git a/views/ngXosViews/diagnostic/mocks/data/users.json b/views/ngXosViews/diagnostic/mocks/data/users.json
new file mode 100644
index 0000000..c4fb9bf
--- /dev/null
+++ b/views/ngXosViews/diagnostic/mocks/data/users.json
@@ -0,0 +1,26 @@
+[
+ {
+ "mac": "01:02:03:04:05:06",
+ "level": "PG_13",
+ "id": 0,
+ "name": "Mom's PC"
+ },
+ {
+ "mac": "34:36:3B:C9:B6:A6",
+ "id": 1,
+ "name": "Jill's Laptop",
+ "level": "PG_13"
+ },
+ {
+ "mac": "68:5B:35:9D:91:D5",
+ "level": "PG_13",
+ "id": 2,
+ "name": "Jack's Laptop"
+ },
+ {
+ "id": 3,
+ "mac": "90:E2:BA:82:F9:75",
+ "name": "Dad's PC",
+ "level": "PG_13"
+ }
+]
\ No newline at end of file
diff --git a/views/ngXosViews/diagnostic/mocks/diagnostic.conf.json b/views/ngXosViews/diagnostic/mocks/diagnostic.conf.json
index 9f574fe..ba9dbb8 100644
--- a/views/ngXosViews/diagnostic/mocks/diagnostic.conf.json
+++ b/views/ngXosViews/diagnostic/mocks/diagnostic.conf.json
@@ -2,6 +2,12 @@
{
"url": "subscribers",
"base": "xos/",
+ "methods": ["GET"],
+ "param": "id"
+ },
+ {
+ "url": "users",
+ "base": "xoslib/rs/subscriber/1/",
"methods": ["GET"]
},
{
diff --git a/views/ngXosViews/diagnostic/spec/serviceChain.test.js b/views/ngXosViews/diagnostic/spec/serviceChain.test.js
index af9a701..14255e2 100644
--- a/views/ngXosViews/diagnostic/spec/serviceChain.test.js
+++ b/views/ngXosViews/diagnostic/spec/serviceChain.test.js
@@ -172,14 +172,17 @@
const services = [
{
id: 1,
+ name: 'vbng',
humanReadableName: 'vbng'
},
{
id: 2,
+ name: 'vsg',
humanReadableName: 'vsg'
},
{
id: 3,
+ name: 'volt',
humanReadableName: 'volt'
}
];
@@ -188,9 +191,10 @@
let tree = Service.buildServiceTree(services, coarseTenants);
expect(tree.type).toBe('subscriber');
- expect(tree.children[0].humanReadableName).toBe('volt');
- expect(tree.children[0].children[0].humanReadableName).toBe('vsg');
- expect(tree.children[0].children[0].children[0].humanReadableName).toBe('vbng');
+ expect(tree.children[0].name).toBe('volt');
+ expect(tree.children[0].service).toBeDefined();
+ expect(tree.children[0].children[0].name).toBe('vsg');
+ expect(tree.children[0].children[0].children[0].name).toBe('vbng');
});
});
diff --git a/views/ngXosViews/diagnostic/src/index.html b/views/ngXosViews/diagnostic/src/index.html
index eacbfe1..34deef6 100644
--- a/views/ngXosViews/diagnostic/src/index.html
+++ b/views/ngXosViews/diagnostic/src/index.html
@@ -33,6 +33,7 @@
<script src="/api/ng-xos.js"></script>
<script src="/api/ng-hpcapi.js"></script>
<script src="/.tmp/main.js"></script>
+<script src="/.tmp/subscriber_service.js"></script>
<script src="/.tmp/subscriber-modal.js"></script>
<script src="/.tmp/serviceTopologyHelper.js"></script>
<script src="/.tmp/serviceTopology.js"></script>
diff --git a/views/ngXosViews/diagnostic/src/js/diagnostic.js b/views/ngXosViews/diagnostic/src/js/diagnostic.js
index c9787ba..d65194c 100644
--- a/views/ngXosViews/diagnostic/src/js/diagnostic.js
+++ b/views/ngXosViews/diagnostic/src/js/diagnostic.js
@@ -30,6 +30,10 @@
ServiceRelation.getBySubscriber(subscriber)
.then((serviceChain) => {
this.serviceChain = serviceChain;
+ return Subscribers.getWithDevices({id: subscriber.id}).$promise;
+ })
+ .then((subscriber) => {
+ this.selectedSubscriber = subscriber;
});
});
}
diff --git a/views/ngXosViews/diagnostic/src/js/logicTopology.js b/views/ngXosViews/diagnostic/src/js/logicTopology.js
index a3501dd..5ca0b30 100644
--- a/views/ngXosViews/diagnostic/src/js/logicTopology.js
+++ b/views/ngXosViews/diagnostic/src/js/logicTopology.js
@@ -11,7 +11,7 @@
bindToController: true,
controllerAs: 'vm',
templateUrl: 'templates/logicTopology.tpl.html',
- controller: function($element, $log, $scope, $rootScope, $timeout, d3, LogicTopologyHelper, Node, Tenant, Ceilometer){
+ controller: function($element, $log, $scope, $rootScope, $timeout, d3, LogicTopologyHelper, Node, Tenant, Ceilometer, serviceTopologyConfig){
$log.info('Logic Plane');
var svg;
@@ -29,8 +29,6 @@
$scope.$watch(() => this.subscribers, (subscribers) => {
if(subscribers){
- // LogicTopologyHelper.addSubscribers(angular.copy(subscribers));
-
Node.queryWithInstances().$promise
.then((computeNodes) => {
LogicTopologyHelper.addComputeNodes(computeNodes);
@@ -43,6 +41,17 @@
$scope.$watch(() => this.selected, (selected) => {
if(selected){
$log.info(`Update logic layer for subscriber ${selected.humanReadableName}`);
+
+ // append the device with to config settings
+ serviceTopologyConfig.elWidths.push(160);
+
+ LogicTopologyHelper.addSubscriber(angular.copy(selected));
+
+ Tenant.getSubscriberTag({subscriber_root: selected.id}).$promise
+ .then((tags) => {
+ LogicTopologyHelper.addSubscriberTag(tags);
+ LogicTopologyHelper.updateTree(svg);
+ })
}
});
@@ -57,6 +66,10 @@
$rootScope.$on('instance.detail', (evt, service) => {
+ // NOTE consider if subscriber is selected or not,
+ // if not select instances
+ // else select containers (and follow subscriber chain to find the correct instance)
+
let param = {
'service_vsg': {kind: 'vCPE'},
'service_vbng': {kind: 'vBNG'},
@@ -69,6 +82,7 @@
return Ceilometer.getInstancesStats(instances);
})
.then((instances) => {
+ console.log(instances);
this.hideInstanceStats = false;
// HACK if array is empty wait for animation
if(instances.length === 0){
@@ -97,7 +111,6 @@
$scope.$apply();
};
-
// listen for subscriber modal event
$rootScope.$on('subscriber.modal.open', () => {
this.openSubscriberModal();
diff --git a/views/ngXosViews/diagnostic/src/js/logicTopologyHelper.js b/views/ngXosViews/diagnostic/src/js/logicTopologyHelper.js
index f860d9e..f17b103 100644
--- a/views/ngXosViews/diagnostic/src/js/logicTopologyHelper.js
+++ b/views/ngXosViews/diagnostic/src/js/logicTopologyHelper.js
@@ -136,6 +136,7 @@
});
// TODO handle node remove
+ var nodeExit = node.exit().remove();
};
/**
@@ -164,6 +165,8 @@
link.transition()
.duration(serviceTopologyConfig.duration)
.attr('d', diagonal);
+
+ link.exit().remove();
};
/**
@@ -190,6 +193,7 @@
// Compute the new tree layout.
[nodes, links] = computeLayout(baseData);
+ // console.log(baseData);
drawNodes(svg, nodes);
drawLinks(svg, links);
}
@@ -197,19 +201,28 @@
/**
* Add Subscribers to the tree
*/
- this.addSubscribers = (subscribers) => {
+ this.addSubscriber = (subscriber) => {
- subscribers.map((subscriber) => {
- subscriber.children = subscriber.devices;
- });
+
+ subscriber.children = subscriber.devices;
// add subscriber to data tree
- baseData.children[0].children[0].children[0].children = subscribers;
-
+ baseData.children[0].children[0].children[0].children = [subscriber];
return baseData;
};
/**
+ * Add Subscriber tag to LAN Network
+ */
+
+ this.addSubscriberTag = (tags) => {
+ baseData.children[0].children[0].children[0].subscriberTag = {
+ cTag: tags.c_tag,
+ sTag: tags.s_tag
+ }
+ };
+
+ /**
* Add compute nodes to the rack element
*/
diff --git a/views/ngXosViews/diagnostic/src/js/nodeDrawer.js b/views/ngXosViews/diagnostic/src/js/nodeDrawer.js
index 62e2cdf..94ff406 100644
--- a/views/ngXosViews/diagnostic/src/js/nodeDrawer.js
+++ b/views/ngXosViews/diagnostic/src/js/nodeDrawer.js
@@ -26,6 +26,26 @@
'text-anchor': 'middle'
})
.text(d => d.name)
+
+ nodes.each(function(n){
+ let currentNode = d3.select(this);
+ // cicle trouch node to add Tags and Public IP
+ if(n.name === 'LAN' && angular.isDefined(n.subscriberTag)){
+ currentNode.append('text')
+ .attr({
+ 'text-anchor': 'middle',
+ y: 40
+ })
+ .text(() => `C-Tag: ${n.subscriberTag.cTag}`);
+
+ currentNode.append('text')
+ .attr({
+ 'text-anchor': 'middle',
+ y: 60
+ })
+ .text(() => `S-Tag: ${n.subscriberTag.sTag}`);
+ }
+ });
}
this.addRack = (nodes) => {
diff --git a/views/ngXosViews/diagnostic/src/js/rest_services.js b/views/ngXosViews/diagnostic/src/js/rest_services.js
index 885b3de..877b485 100644
--- a/views/ngXosViews/diagnostic/src/js/rest_services.js
+++ b/views/ngXosViews/diagnostic/src/js/rest_services.js
@@ -28,6 +28,16 @@
return instances;
}
}
+ },
+ getSubscriberTag: {
+ method: 'GET',
+ isArray: true,
+ interceptor: {
+ response: (res) => {
+ // NOTE we should receive only one vOLT tenant here
+ return JSON.parse(res.data[0].service_specific_attribute);
+ }
+ }
}
});
})
@@ -127,7 +137,7 @@
});
})
.service('Subscribers', function($resource, $q, SubscriberDevice){
- return $resource('/xos/subscribers', {id: '@id'}, {
+ return $resource('/xos/subscribers/:id', {id: '@id'}, {
queryWithDevices: {
method: 'GET',
isArray: true,
@@ -138,7 +148,7 @@
* For each subscriber retrieve devices and append them
*/
- const deferred = $q.defer();
+ let deferred = $q.defer();
let requests = [];
@@ -169,6 +179,29 @@
return deferred.promise;
}
}
+ },
+ getWithDevices: {
+ method: 'GET',
+ isArray: false,
+ interceptor: {
+ response: (res) => {
+ let d = $q.defer();
+
+ SubscriberDevice.query({id: res.data.id}).$promise
+ .then(devices => {
+ devices.map(d => d.type = 'device');
+ res.data.devices = devices;
+ res.data.type = 'subscriber';
+ console.log(res.data);
+ d.resolve(res.data);
+ })
+ .catch(err => {
+ d.reject(err);
+ });
+
+ return d.promise;
+ }
+ }
}
});
})
@@ -289,13 +322,20 @@
// TODO refactor
const buildChild = (services, tenants, currentService) => {
+
+ const response = {
+ type: 'service',
+ name: currentService.humanReadableName,
+ service: currentService
+ };
+
let tenant = lodash.find(tenants, {subscriber_service: currentService.id});
if(tenant){
let next = lodash.find(services, {id: tenant.provider_service});
- currentService.children = [buildChild(services, tenants, next)];
+ response.children = [buildChild(services, tenants, next)];
}
else {
- currentService.children = [
+ response.children = [
{
name: 'Router',
type: 'router',
@@ -303,9 +343,8 @@
}
]
}
- currentService.type = 'service';
delete currentService.id; // conflict with d3
- return currentService;
+ return response;
}
let baseService = lodash.find(services, {id: 3});
diff --git a/views/ngXosViews/diagnostic/src/js/serviceTopology.js b/views/ngXosViews/diagnostic/src/js/serviceTopology.js
index 3d602fe..b358abf 100644
--- a/views/ngXosViews/diagnostic/src/js/serviceTopology.js
+++ b/views/ngXosViews/diagnostic/src/js/serviceTopology.js
@@ -32,8 +32,6 @@
const width = el.clientWidth - (serviceTopologyConfig.widthMargin * 2);
const height = el.clientHeight - (serviceTopologyConfig.heightMargin * 2);
- console.log(el.clientWidth, el.clientHeight);
-
const treeLayout = d3.layout.tree()
.size([height, width]);
diff --git a/views/ngXosViews/diagnostic/src/js/serviceTopologyHelper.js b/views/ngXosViews/diagnostic/src/js/serviceTopologyHelper.js
index 817e79e..47fc5eb 100644
--- a/views/ngXosViews/diagnostic/src/js/serviceTopologyHelper.js
+++ b/views/ngXosViews/diagnostic/src/js/serviceTopologyHelper.js
@@ -225,8 +225,8 @@
$rootScope.$emit('instance.detail.hide', {});
return updateTree(_svg, _layout, _source);
}
-
- $rootScope.$emit('instance.detail', {name: d.humanReadableName});
+
+ $rootScope.$emit('instance.detail', {name: d.name});
// unselect all
_svg.selectAll('circle')