.vagrant
*.pyc
-get-nsps.py
-infrastructure_config.py
+/get-nsps.py
+/infrastructure_config.py
demo.lock
hostname="gbpsfc"$i
switchname="sw"$i
echo $hostname
- vagrant ssh $hostname -c "sudo ovs-vsctl del-br $switchname; sudo ovs-vsctl del-manager; sudo /vagrant/vmclean.sh"
+ vagrant ssh $hostname -c "sudo ovs-vsctl del-br $switchname; sudo ovs-vsctl del-manager; sudo /vagrant/vmclean.sh; sudo /vagrant/sflow/stop_sflow-rt.sh >/dev/null 2>&1"
done
-
+
./rest-clean.py
if [ -f "demo.lock" ] ; then
"order": 0,
"classifier-ref": [
{
- "name": "icmp",
- "instance-name": "icmp"
+ "name": "icmp-in",
+ "instance-name": "icmp",
+ "direction": "in"
+ },
+ {
+ "name": "icmp-out",
+ "instance-name": "icmp",
+ "direction": "out"
}
],
"action-ref": [
"order": 0,
"classifier-ref": [
{
- "name": "icmp",
- "instance-name": "icmp"
+ "name": "icmp-in",
+ "instance-name": "icmp",
+ "direction": "in"
+ },
+ {
+ "name": "icmp-out",
+ "instance-name": "icmp",
+ "direction": "out"
}
],
"action-ref": [
'type': 'gbp',
'dpid': '3'},
{'name': 'sw4',
- 'type': 'none',
+ 'type': 'sflow',
'dpid': '4'},
{'name': 'sw5',
'type': 'none',
if debug == True:
print r.text
r.raise_for_status()
-
+
def get_tenant_data():
return {
{
"classifier-ref": [
{
- "name": "icmp",
- "instance-name": "icmp"
+ "name": "icmp-in",
+ "instance-name": "icmp",
+ "direction": "in"
+ },
+ {
+ "name": "icmp-out",
+ "instance-name": "icmp",
+ "direction": "out"
}
],
"action-ref": [
}
# Main definition - constants
-
+
# =======================
# MENUS FUNCTIONS
# =======================
-
+
# Main menu
# =======================
# MAIN PROGRAM
# =======================
-
+
# Main Program
def get_tenant_uri():
}
]
},
-
+
]
}
}
-
+
def get_tunnel_uri():
return "/restconf/config/opendaylight-inventory:nodes"
return [{
"input": {
- "endpoint-group": "clients",
+ "endpoint-group": "clients",
"network-containment" : "subnet-10.0.35.0/24",
- "l2-context": "bridge-domain1",
- "mac-address": "00:00:00:00:35:02",
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:35:02",
"l3-address": [
{
- "ip-address": "10.0.35.2",
+ "ip-address": "10.0.35.2",
"l3-context": "l3-context-vrf-red"
}
- ],
- "port-name": "vethl-h35_2",
+ ],
+ "port-name": "vethl-h35_2",
"tenant": "tenant-red"
}
},
{
"input": {
- "endpoint-group": "clients",
+ "endpoint-group": "clients",
"network-containment" : "subnet-10.0.35.0/24",
- "l2-context": "bridge-domain1",
- "mac-address": "00:00:00:00:35:03",
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:35:03",
"l3-address": [
{
- "ip-address": "10.0.35.3",
+ "ip-address": "10.0.35.3",
"l3-context": "l3-context-vrf-red"
}
- ],
- "port-name": "vethl-h35_3",
+ ],
+ "port-name": "vethl-h35_3",
"tenant": "tenant-red"
}
},
{
"input": {
- "endpoint-group": "clients",
+ "endpoint-group": "clients",
"network-containment" : "subnet-10.0.35.0/24",
- "l2-context": "bridge-domain1",
- "mac-address": "00:00:00:00:35:04",
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:35:04",
"l3-address": [
{
- "ip-address": "10.0.35.4",
+ "ip-address": "10.0.35.4",
"l3-context": "l3-context-vrf-red"
}
- ],
- "port-name": "vethl-h35_4",
+ ],
+ "port-name": "vethl-h35_4",
"tenant": "tenant-red"
}
},
{
"input": {
- "endpoint-group": "clients",
+ "endpoint-group": "clients",
"network-containment" : "subnet-10.0.35.0/24",
- "l2-context": "bridge-domain1",
- "mac-address": "00:00:00:00:35:05",
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:35:05",
"l3-address": [
{
- "ip-address": "10.0.35.5",
+ "ip-address": "10.0.35.5",
"l3-context": "l3-context-vrf-red"
}
- ],
- "port-name": "vethl-h35_5",
+ ],
+ "port-name": "vethl-h35_5",
"tenant": "tenant-red"
}
},
{
"input": {
- "endpoint-group": "webservers",
+ "endpoint-group": "webservers",
"network-containment" : "subnet-10.0.36.0/24",
- "l2-context": "bridge-domain1",
- "mac-address": "00:00:00:00:36:02",
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:36:02",
"l3-address": [
{
- "ip-address": "10.0.36.2",
+ "ip-address": "10.0.36.2",
"l3-context": "l3-context-vrf-red"
}
- ],
- "port-name": "vethl-h36_2",
+ ],
+ "port-name": "vethl-h36_2",
"tenant": "tenant-red"
}
},
{
"input": {
- "endpoint-group": "webservers",
+ "endpoint-group": "webservers",
"network-containment" : "subnet-10.0.36.0/24",
- "l2-context": "bridge-domain1",
- "mac-address": "00:00:00:00:36:03",
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:36:03",
"l3-address": [
{
- "ip-address": "10.0.36.3",
+ "ip-address": "10.0.36.3",
"l3-context": "l3-context-vrf-red"
}
- ],
- "port-name": "vethl-h36_3",
+ ],
+ "port-name": "vethl-h36_3",
"tenant": "tenant-red"
}
},
{
"input": {
- "endpoint-group": "webservers",
+ "endpoint-group": "webservers",
"network-containment" : "subnet-10.0.36.0/24",
- "l2-context": "bridge-domain1",
- "mac-address": "00:00:00:00:36:04",
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:36:04",
"l3-address": [
{
- "ip-address": "10.0.36.4",
+ "ip-address": "10.0.36.4",
"l3-context": "l3-context-vrf-red"
}
- ],
- "port-name": "vethl-h36_4",
+ ],
+ "port-name": "vethl-h36_4",
"tenant": "tenant-red"
}
},{
"input": {
- "endpoint-group": "webservers",
+ "endpoint-group": "webservers",
"network-containment" : "subnet-10.0.36.0/24",
- "l2-context": "bridge-domain1",
- "mac-address": "00:00:00:00:36:05",
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:36:05",
"l3-address": [
{
- "ip-address": "10.0.36.5",
+ "ip-address": "10.0.36.5",
"l3-context": "l3-context-vrf-red"
}
- ],
- "port-name": "vethl-h36_5",
+ ],
+ "port-name": "vethl-h36_5",
"tenant": "tenant-red"
}
}]
controller=os.environ.get('ODL')
if controller == None:
sys.exit("No controller set.")
-
+
print "tenants"
tenants=get(controller,DEFAULT_PORT,CONF_TENANT)
print tenants
-
+
print "sending tenant"
put(controller, DEFAULT_PORT, get_tenant_uri(), get_tenant_data(),True)
print "sending tunnel"
print "registering endpoints"
for endpoint in get_endpoint_data():
post(controller, DEFAULT_PORT, get_endpoint_uri(),endpoint,True)
-
-
-
-
+
+
+
+
--- /dev/null
+#!/usr/bin/python
+
+if __name__ == "__main__":
+ # Launch main menu
+
+
+ # Some sensible defaults
+ print "Nothing"
--- /dev/null
+# Config for switches, tunnelIP is the local IP address.
+switches = [
+ {'name': 'sw1',
+ 'type': 'gbp',
+ 'dpid': '1'},
+ {'name': 'sw2',
+ 'type': 'gbp',
+ 'dpid': '2'},
+ {'name': 'sw3',
+ 'type': 'sflow',
+ 'dpid': '3'},
+ {'name': 'sw4',
+ 'type': 'none',
+ 'dpid': '4'},
+ {'name': 'sw5',
+ 'type': 'none',
+ 'dpid': '5'},
+ {'name': 'sw6',
+ 'type': 'none',
+ 'dpid': '6'},
+ {'name': 'sw7',
+ 'type': 'none',
+ 'dpid': '7'},
+ {'name': 'sw8',
+ 'type': 'none',
+ 'dpid': '8'}
+ ]
+
+defaultContainerImage='alagalah/odlpoc_ovs230'
+#defaultContainerImage='ubuntu:14.04'
+
+#Note that tenant name and endpointGroup name come from policy_config.py
+
+hosts = [{'name': 'h35_2',
+ 'mac': '00:00:00:00:35:02',
+ 'ip': '10.0.35.2/24',
+ 'switch': 'sw1'},
+ {'name': 'h35_3',
+ 'ip': '10.0.35.3/24',
+ 'mac': '00:00:00:00:35:03',
+ 'switch': 'sw1'},
+ {'name': 'h35_4',
+ 'ip': '10.0.35.4/24',
+ 'mac': '00:00:00:00:35:04',
+ 'switch': 'sw1'},
+ {'name': 'h35_5',
+ 'ip': '10.0.35.5/24',
+ 'mac': '00:00:00:00:35:05',
+ 'switch': 'sw1'},
+ {'name': 'h36_2',
+ 'ip': '10.0.36.2/24',
+ 'mac': '00:00:00:00:36:02',
+ 'switch': 'sw2'},
+ {'name': 'h36_3',
+ 'ip': '10.0.36.3/24',
+ 'mac': '00:00:00:00:36:03',
+ 'switch': 'sw2'},
+ {'name': 'h36_4',
+ 'ip': '10.0.36.4/24',
+ 'mac': '00:00:00:00:36:04',
+ 'switch': 'sw2'},
+ {'name': 'h36_5',
+ 'ip': '10.0.36.5/24',
+ 'mac': '00:00:00:00:36:05',
+ 'switch': 'sw2'}
+ ]
+
--- /dev/null
+#!/usr/bin/python
+import argparse
+import requests,json
+from requests.auth import HTTPBasicAuth
+from subprocess import call
+import time
+import sys
+import os
+
+
+DEFAULT_PORT='8181'
+
+
+USERNAME='admin'
+PASSWORD='admin'
+
+
+OPER_NODES='/restconf/operational/opendaylight-inventory:nodes/'
+CONF_TENANT='/restconf/config/policy:tenants'
+
+def get(host, port, uri):
+ url='http://'+host+":"+port+uri
+ #print url
+ r = requests.get(url, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+ jsondata=json.loads(r.text)
+ return jsondata
+
+def put(host, port, uri, data, debug=False):
+ '''Perform a PUT rest operation, using the URL and data provided'''
+
+ url='http://'+host+":"+port+uri
+
+ headers = {'Content-type': 'application/yang.data+json',
+ 'Accept': 'application/yang.data+json'}
+ if debug == True:
+ print "PUT %s" % url
+ print json.dumps(data, indent=4, sort_keys=True)
+ r = requests.put(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+ if debug == True:
+ print r.text
+ r.raise_for_status()
+
+def post(host, port, uri, data, debug=False):
+ '''Perform a POST rest operation, using the URL and data provided'''
+
+ url='http://'+host+":"+port+uri
+ headers = {'Content-type': 'application/yang.data+json',
+ 'Accept': 'application/yang.data+json'}
+ if debug == True:
+ print "POST %s" % url
+ print json.dumps(data, indent=4, sort_keys=True)
+ r = requests.post(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+ if debug == True:
+ print r.text
+ r.raise_for_status()
+
+
+def get_tenant_data():
+ return {
+ "policy:tenant": {
+ "id": "tenant-red",
+ "name": "GBPPOC",
+ "forwarding-context": {
+ "l2-bridge-domain": [
+ {
+ "id": "bridge-domain1",
+ "parent": "l3-context-vrf-red"
+ }
+ ],
+ "l2-flood-domain": [
+ {
+ "id": "flood-domain-1",
+ "parent": "bridge-domain1"
+ },
+ {
+ "id": "flood-domain1",
+ "parent": "bridge-domain1"
+ }
+ ],
+ "l3-context": [
+ {
+ "id": "l3-context-vrf-red"
+ }
+ ],
+ "subnet": [
+ {
+ "id": "subnet-10.0.35.0/24",
+ "ip-prefix": "10.0.35.1/24",
+ "parent": "flood-domain-1",
+ "virtual-router-ip": "10.0.35.1"
+ },
+ {
+ "id": "subnet-10.0.36.0/24",
+ "ip-prefix": "10.0.36.1/24",
+ "parent": "flood-domain1",
+ "virtual-router-ip": "10.0.36.1"
+ }
+ ]
+ },
+ "policy": {
+ "contract": [
+ {
+ "clause": [
+ {
+ "name": "allow-http-clause",
+ "subject-refs": [
+ "allow-http-subject",
+ "allow-icmp-subject"
+ ]
+ }
+ ],
+ "id": "icmp-http-contract",
+ "subject": [
+ {
+ "name": "allow-http-subject",
+ "rule": [
+ {
+ "classifier-ref": [
+ {
+ "direction": "in",
+ "name": "http-dest",
+ "instance-name": "http-dest"
+ },
+ {
+ "direction": "out",
+ "name": "http-src",
+ "instance-name": "http-src"
+ }
+ ],
+ "action-ref": [
+ {
+ "name": "allow1",
+ "order": 0
+ }
+ ],
+ "name": "allow-http-rule"
+ }
+ ]
+ },
+ {
+ "name": "allow-icmp-subject",
+ "rule": [
+ {
+ "classifier-ref": [
+ {
+ "name": "icmp-in",
+ "instance-name": "icmp",
+ "direction": "in"
+ },
+ {
+ "name": "icmp-out",
+ "instance-name": "icmp",
+ "direction": "out"
+ }
+ ],
+ "action-ref": [
+ {
+ "name": "allow1",
+ "order": 0
+ }
+ ],
+ "name": "allow-icmp-rule"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "endpoint-group": [
+ {
+ "consumer-named-selector": [
+ {
+ "contract": [
+ "icmp-http-contract"
+ ],
+ "name": "webservers-clients-icmp-http-contract"
+ }
+ ],
+ "id": "clients",
+ "provider-named-selector": []
+ },
+ {
+ "consumer-named-selector": [],
+ "id": "webservers1",
+ "provider-named-selector": [
+ {
+ "contract": [
+ "icmp-http-contract"
+ ],
+ "name": "webservers-clients-icmp-http-contract"
+ }
+ ]
+ },
+ {
+ "consumer-named-selector": [],
+ "id": "webservers2",
+ "provider-named-selector": [
+ {
+ "contract": [
+ "icmp-http-contract"
+ ],
+ "name": "webservers-clients-icmp-http-contract"
+ }
+ ]
+ }
+ ],
+ "subject-feature-instances": {
+ "classifier-instance": [
+ {
+ "classifier-definition-id": "Classifier-L4",
+ "name": "http-dest",
+ "parameter-value": [
+ {
+ "int-value": "6",
+ "name": "proto"
+ },
+ {
+ "int-value": "80",
+ "name": "destport"
+ }
+ ]
+ },
+ {
+ "classifier-definition-id": "Classifier-L4",
+ "name": "http-src",
+ "parameter-value": [
+ {
+ "int-value": "6",
+ "name": "proto"
+ },
+ {
+ "int-value": "80",
+ "name": "sourceport"
+ }
+ ]
+ },
+ {
+ "classifier-definition-id": "Classifier-IP-Protocol",
+ "name": "icmp",
+ "parameter-value": [
+ {
+ "int-value": "1",
+ "name": "proto"
+ }
+ ]
+ }
+ ],
+ "action-instance": [
+ {
+ "name": "allow1",
+ "action-definition-id": "Action-Allow"
+ }
+ ]
+ }
+ }
+ }
+ }
+
+# Main definition - constants
+
+# =======================
+# MENUS FUNCTIONS
+# =======================
+
+# Main menu
+
+# =======================
+# MAIN PROGRAM
+# =======================
+
+# Main Program
+
+def get_tenant_uri():
+ return "/restconf/config/policy:tenants/policy:tenant/tenant-red"
+
+
+def get_tunnel_data():
+ return {
+ "opendaylight-inventory:nodes": {
+ "node": [
+ {
+ "id": "openflow:1",
+ "ofoverlay:tunnel": [
+ {
+ "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
+ "node-connector-id": "openflow:1:1",
+ "ip": "192.168.50.70",
+ "port": 6633
+ },
+ {
+ "tunnel-type": "overlay:tunnel-type-vxlan",
+ "node-connector-id": "openflow:1:2",
+ "ip": "192.168.50.70",
+ "port": 4789
+ }
+ ]
+ },
+ {
+ "id": "openflow:2",
+ "ofoverlay:tunnel": [
+ {
+ "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
+ "node-connector-id": "openflow:2:1",
+ "ip": "192.168.50.71",
+ "port": 6633
+ },
+ {
+ "tunnel-type": "overlay:tunnel-type-vxlan",
+ "node-connector-id": "openflow:2:2",
+ "ip": "192.168.50.71",
+ "port": 4789
+ }
+ ]
+ },
+ {
+ "id": "openflow:3",
+ "ofoverlay:tunnel": [
+ {
+ "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
+ "node-connector-id": "openflow:3:1",
+ "ip": "192.168.50.72",
+ "port": 6633
+ },
+ {
+ "tunnel-type": "overlay:tunnel-type-vxlan",
+ "node-connector-id": "openflow:3:2",
+ "ip": "192.168.50.72",
+ "port": 4789
+ }
+ ]
+ },
+
+ ]
+ }
+ }
+
+def get_tunnel_uri():
+ return "/restconf/config/opendaylight-inventory:nodes"
+
+def get_endpoint_data():
+ return [{
+ "input": {
+
+ "endpoint-group": "clients",
+
+ "network-containment" : "subnet-10.0.35.0/24",
+
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:35:02",
+
+ "l3-address": [
+ {
+ "ip-address": "10.0.35.2",
+ "l3-context": "l3-context-vrf-red"
+ }
+ ],
+ "port-name": "vethl-h35_2",
+ "tenant": "tenant-red"
+ }
+},
+ {
+ "input": {
+
+ "endpoint-group": "clients",
+
+ "network-containment" : "subnet-10.0.35.0/24",
+
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:35:03",
+
+ "l3-address": [
+ {
+ "ip-address": "10.0.35.3",
+ "l3-context": "l3-context-vrf-red"
+ }
+ ],
+ "port-name": "vethl-h35_3",
+ "tenant": "tenant-red"
+ }
+},
+ {
+ "input": {
+
+ "endpoint-group": "clients",
+
+ "network-containment" : "subnet-10.0.35.0/24",
+
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:35:04",
+
+ "l3-address": [
+ {
+ "ip-address": "10.0.35.4",
+ "l3-context": "l3-context-vrf-red"
+ }
+ ],
+ "port-name": "vethl-h35_4",
+ "tenant": "tenant-red"
+ }
+},
+ {
+ "input": {
+
+ "endpoint-group": "clients",
+
+ "network-containment" : "subnet-10.0.35.0/24",
+
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:35:05",
+
+ "l3-address": [
+ {
+ "ip-address": "10.0.35.5",
+ "l3-context": "l3-context-vrf-red"
+ }
+ ],
+ "port-name": "vethl-h35_5",
+ "tenant": "tenant-red"
+ }
+},
+ {
+ "input": {
+
+ "endpoint-group": "webservers1",
+
+ "network-containment" : "subnet-10.0.36.0/24",
+
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:36:02",
+
+ "l3-address": [
+ {
+ "ip-address": "10.0.36.2",
+ "l3-context": "l3-context-vrf-red"
+ }
+ ],
+ "port-name": "vethl-h36_2",
+ "tenant": "tenant-red"
+ }
+},
+ {
+ "input": {
+
+ "endpoint-group": "webservers2",
+
+ "network-containment" : "subnet-10.0.36.0/24",
+
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:36:03",
+
+ "l3-address": [
+ {
+ "ip-address": "10.0.36.3",
+ "l3-context": "l3-context-vrf-red"
+ }
+ ],
+ "port-name": "vethl-h36_3",
+ "tenant": "tenant-red"
+ }
+},
+ {
+ "input": {
+
+ "endpoint-group": "webservers1",
+
+ "network-containment" : "subnet-10.0.36.0/24",
+
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:36:04",
+
+ "l3-address": [
+ {
+ "ip-address": "10.0.36.4",
+ "l3-context": "l3-context-vrf-red"
+ }
+ ],
+ "port-name": "vethl-h36_4",
+ "tenant": "tenant-red"
+ }
+},{
+ "input": {
+
+ "endpoint-group": "webservers2",
+
+ "network-containment" : "subnet-10.0.36.0/24",
+
+ "l2-context": "bridge-domain1",
+ "mac-address": "00:00:00:00:36:05",
+
+ "l3-address": [
+ {
+ "ip-address": "10.0.36.5",
+ "l3-context": "l3-context-vrf-red"
+ }
+ ],
+ "port-name": "vethl-h36_5",
+ "tenant": "tenant-red"
+ }
+}]
+
+def get_endpoint_uri():
+ return "/restconf/operations/endpoint:register-endpoint"
+
+if __name__ == "__main__":
+ # Launch main menu
+
+
+ # Some sensible defaults
+ controller=os.environ.get('ODL')
+ if controller == None:
+ sys.exit("No controller set.")
+
+
+ print "tenants"
+ tenants=get(controller,DEFAULT_PORT,CONF_TENANT)
+ print tenants
+
+ print "sending tenant"
+ put(controller, DEFAULT_PORT, get_tenant_uri(), get_tenant_data(),True)
+ print "sending tunnel"
+ put(controller, DEFAULT_PORT, get_tunnel_uri(), get_tunnel_data(), True)
+ print "registering endpoints"
+ for endpoint in get_endpoint_data():
+ post(controller, DEFAULT_PORT, get_endpoint_uri(),endpoint,True)
+
+
+
+
"order": 0,
"classifier-ref": [
{
- "name": "icmp",
- "instance-name": "icmp"
+ "name": "icmp-in",
+ "instance-name": "icmp",
+ "direction": "in"
+ },
+ {
+ "name": "icmp-out",
+ "instance-name": "icmp",
+ "direction": "out"
}
],
"action-ref": [
"order": 0,
"classifier-ref": [
{
- "name": "icmp",
- "instance-name": "icmp"
+ "name": "icmp-in",
+ "instance-name": "icmp",
+ "direction": "in"
+ },
+ {
+ "name": "icmp-out",
+ "instance-name": "icmp",
+ "direction": "out"
}
],
"action-ref": [
print "*****************************"
doCmd('sudo /vagrant/sf-config.sh')
#addGpeTunnel(switches[sw_index]['name'])
+ elif sw_type == 'sflow':
+ print "*****************************"
+ print "Configuring %s as an sFlow-RT collector." % sw_name
+ print "*****************************"
+ doCmd('sudo /vagrant/install_java.sh')
+ doCmd('sudo /vagrant/sflow/install_sflow-rt.sh')
+ call('sudo /home/vagrant/sflow-rt/gbp_start.sh &'.split())
+ doCmd('sudo /vagrant/sflow/set_collector_ip.sh')
+ doCmd('sudo /vagrant/sflow/curl_put_collector.sh')
+ print "Configuring finished."
+
--- /dev/null
+#!/usr/bin/env bash
+
+if ! java -version 2>/dev/null; then
+ sudo apt-get update
+ sudo apt-get install openjdk-7-jre-headless -y
+fi
--- /dev/null
+/curl_put_collector.sh
start [<name>]
stop [<name>]
list [<name>]
-No parameters: machines' names are generated from settings file.
-One parameter: operation will take place on than machine only
+No parameters: machines' names are generated from settings.sh file (SFLOW_LIST should contain numbers used for vagrant's names of VMs).
+One parameter: operation will take place on than machine only (ex., `start gbpsfc2')
start
-Start sending sFlow data from OVS (all parameters are set in internal_settings)
+Start sending sFlow data from OVS (all parameters are set in internal_settings.sh)
stop
Stop sending sFlow data
list
Show actual state of sFlow, or will not show anything if sFlow is stopped.
-internal_settings
+internal_settings.sh
Settings used to start sFlow sending on a machine
-internal_start, internal_stop
+internal_start.sh, internal_stop.sh
Not to be run manually. Starting/stopping sFlow sending on individual machine
--- /dev/null
+#!/usr/bin/env bash
+
+if [ ! -d /home/vagrant/sflow-rt ]; then
+ echo "/home/vagrant/sflow-rt not found; installing sFlow-RT..."
+ wget http://www.inmon.com/products/sFlow-RT/sflow-rt.tar.gz
+ tar -xvzf sflow-rt.tar.gz
+ sudo chown -R vagrant:vagrant /home/vagrant/sflow-rt
+fi
+
+if [ ! -f /home/vagrant/sflow-rt/gbp_start.sh ]; then
+ sed '/exec java/c sudo nohup java ${JVM_OPTS} ${RT_OPTS} ${SCRIPTS} -jar ${JAR} 1>rt.out 2>&1 &' ~/sflow-rt/start.sh >/home/vagrant/sflow-rt/gbp_start.sh
+ sudo chmod +x /home/vagrant/sflow-rt/gbp_start.sh
+fi
#!/usr/bin/env bash
-export COLLECTOR_IP=192.168.53.2
+export COLLECTOR_IP=192.168.53.73
export COLLECTOR_PORT=6343
export AGENT_IP=eth2
export HEADER_BYTES=128
#!/usr/bin/env bash
-. /vagrant/sflow/internal_settings
+. /vagrant/sflow/internal_settings.sh
hostnum=${HOSTNAME#"gbpsfc"}
sw="sw$hostnum"
if [ -f ~/sflow_uuid ]; then
echo "sflow_uuid already present; cleaning..."
- sudo ovs-vsctl remove bridge $sw sflow `cat ~/sflow_uuid`
+ sudo ovs-vsctl remove bridge $sw sflow `cat ~/sflow_uuid`
rm ~/sflow_uuid
fi
#!/usr/bin/env bash
if [ ! -f ~/sflow_uuid ]; then
- echo "No sflow_uuid found!"
+ echo "No sflow_uuid found."
exit 1
fi
hostnum=${HOSTNAME#"gbpsfc"}
sw="sw$hostnum"
-sudo ovs-vsctl remove bridge $sw sflow `cat ~/sflow_uuid`
+sudo ovs-vsctl remove bridge $sw sflow `cat ~/sflow_uuid`
rm ~/sflow_uuid
--- /dev/null
+#!/usr/bin/env bash
+
+source /vagrant/env.sh
+source /vagrant/sflow/settings.sh
+export THIS_IP=$(ifconfig | grep -A 1 'eth2' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)
+
+echo "#!/usr/bin/env bash" >/vagrant/sflow/curl_put_collector.sh
+echo "curl -H \"Content-Type:application/yang.data+json\" -X PUT --data \"{'ofoverlay:of-overlay-config': {'sflow-client-settings': {'gbp-ofoverlay-sflow-retrieve-interval': $SFLOW_INTERVAL, 'gbp-ofoverlay-sflow-collector-uri': 'http://$THIS_IP:8008'}}}\" http://admin:admin@$ODL:8181/restconf/config/ofoverlay:of-overlay-config" >>/vagrant/sflow/curl_put_collector.sh
+
+sed -i "/export COLLECTOR_IP=/c export COLLECTOR_IP=$THIS_IP" /vagrant/sflow/internal_settings.sh
#!/usr/bin/env bash
export SFLOW_LIST="1 2 3"
+export SFLOW_INTERVAL=30
#!/usr/bin/env bash
if [ $1 ]; then
- vagrant ssh $1 -c "bash -E /vagrant/sflow/internal_start"
+ vagrant ssh $1 -c "bash -E /vagrant/sflow/internal_start.sh"
else
- . sflow/settings
+ . sflow/settings.sh
for i in $SFLOW_LIST
do
echo; echo "gbpsfc$i"
- vagrant ssh gbpsfc$i -c "bash -E /vagrant/sflow/internal_start"
+ vagrant ssh gbpsfc$i -c "bash -E /vagrant/sflow/internal_start.sh"
done
fi
#!/usr/bin/env bash
if [ $1 ]; then
- vagrant ssh $1 -c "bash -E /vagrant/sflow/internal_stop"
+ vagrant ssh $1 -c "bash -E /vagrant/sflow/internal_stop.sh"
else
- . sflow/settings
+ . sflow/settings.sh
for i in $SFLOW_LIST
do
echo; echo "gbpsfc$i"
- vagrant ssh gbpsfc$i -c "bash -E /vagrant/sflow/internal_stop"
+ vagrant ssh gbpsfc$i -c "bash -E /vagrant/sflow/internal_stop.sh"
done
fi
--- /dev/null
+#!/usr/bin/env bash
+
+sudo kill $(ps -fe | grep port=6343 | grep -v grep | awk 'NR==1 {print $2}')
+sudo rm /home/vagrant/sflow-rt/rt.out.old
+sudo mv /home/vagrant/sflow-rt/rt.out /home/vagrant/sflow-rt/rt.out.old
<feature version='${sfc.version}'>odl-sfc-ui</feature>
<bundle>mvn:commons-net/commons-net/{{VERSION}}</bundle>
<bundle>mvn:org.opendaylight.groupbasedpolicy/ofoverlay-renderer/{{VERSION}}</bundle>
+ <bundle>mvn:com.sun.jersey/jersey-core/{{VERSION}}</bundle>
+ <bundle>mvn:com.sun.jersey/jersey-client/{{VERSION}}</bundle>
+ <bundle>mvn:com.google.code.gson/gson/{{VERSION}}</bundle>
<configfile finalname="${config.configfile.directory}/15-groupbasedpolicy-ofoverlay.xml">mvn:org.opendaylight.groupbasedpolicy/ofoverlay-renderer/{{VERSION}}/xml/config</configfile>
</feature>
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Policy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.SubjectFeatureInstances;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstanceBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPolicies;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPoliciesBuilder;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
synchronized (subscribersPerTenant) {
if (subscribersPerTenant.contains(tenantAfter.getId())) {
updateTenant(tenantAfter.getId(), tenantAfter);
+ tenantAfter.getPolicy().getContract().get(0).getId();
+ tenantAfter.getPolicy().getContract().get(0).getSubject().get(0).getName();
+ tenantAfter.getPolicy().getContract().get(0).getSubject().get(0).getRule().get(0).getName();
+ List<ClassifierRef> cref = tenantAfter.getPolicy()
+ .getContract()
+ .get(0)
+ .getSubject()
+ .get(0)
+ .getRule()
+ .get(0)
+ .getClassifierRef();
+ cref.get(0).getInstanceName();
+ tenantAfter.getPolicy().getSubjectFeatureInstances().getClassifierInstance().get(0).getName();
+ tenantAfter.getPolicy().getSubjectFeatureInstances().getClassifierInstance().get(0).getParameterValue()
+ .get(0);
}
}
}
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.groupbasedpolicy.api.StatisticsManager;
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
import org.opendaylight.groupbasedpolicy.util.IidFactory;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
@Override
public boolean writeStat(StatRecords record) {
+ WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
for (EpToEpStatistic epStats : record.getEpToEpStatistic()) {
SrcEndpointBuilder srcBuilder = new SrcEndpointBuilder();
DstEndpointBuilder dstBuilder = new DstEndpointBuilder();
srcBuilder.setMacAddress(epStats.getSrcMacAddress())
- .setL2Context(epStats.getSrcL2c())
- .setTenant(epStats.getSrcTenant());
+ .setL2Context(epStats.getSrcL2c())
+ .setTenant(epStats.getSrcTenant());
dstBuilder.setMacAddress(epStats.getDstMacAddress())
- .setL2Context(epStats.getDstL2c())
- .setTenant(epStats.getDstTenant());
+ .setL2Context(epStats.getDstL2c())
+ .setTenant(epStats.getDstTenant());
for (EpEpgToEpEpgStatistic epgStats : epStats.getEpEpgToEpEpgStatistic()) {
StatisticRecordKey key = new StatisticRecordKey(new RecordId(recordKey++));
StatisticRecord statRecord;
List<Statistic> statisticList = new ArrayList<>();
for (MatchedRuleStatistic ruleStats : epgStats.getMatchedRuleStatistic()) {
Statistic statistic = new StatisticBuilder()
- .setKey(new StatisticKey(ruleStats.getContract(), ruleStats.getMatchedRule(),
- ruleStats.getSubject()))
- .setContract(ruleStats.getContract())
- .setSubject(ruleStats.getSubject())
- .setRule(ruleStats.getMatchedRule())
- .setAction(ruleStats.getAction())
- .setClassifier(ruleStats.getClassifier())
- .setByteCount(ruleStats.getByteCount())
- .setPacketCount(ruleStats.getPacketCount())
- .build();
+ .setKey(new StatisticKey(ruleStats.getContract(),
+ ruleStats.getMatchedRule(), ruleStats.getSubject()))
+ .setContract(ruleStats.getContract())
+ .setSubject(ruleStats.getSubject())
+ .setRule(ruleStats.getMatchedRule())
+ .setAction(ruleStats.getAction())
+ .setClassifier(ruleStats.getClassifier())
+ .setByteCount(ruleStats.getByteCount())
+ .setPacketCount(ruleStats.getPacketCount())
+ .build();
statisticList.add(statistic);
}
statRecord = new StatisticRecordBuilder().setKey(key)
- .setRecordId(new RecordId(recordKey))
- .setTimestamp(epStats.getTimestamp())
- .setSrcEndpoint(srcBuilder.build())
- .setDstEndpoint(dstBuilder.build())
- .setStatistic(statisticList)
- .build();
+ .setRecordId(new RecordId(recordKey))
+ .setTimestamp(epStats.getTimestamp())
+ .setSrcEndpoint(srcBuilder.build())
+ .setDstEndpoint(dstBuilder.build())
+ .setStatistic(statisticList)
+ .build();
InstanceIdentifier<StatisticRecord> statIID = IidFactory.statisticRecordIid(key);
- WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
- LOG.debug("Writing statistics to datastore");
- wtx.put(LogicalDatastoreType.OPERATIONAL, statIID, statRecord);
- wtx.submit();
+ LOG.debug("Writing statistics to datastore: {}", statRecord);
+ wtx.put(LogicalDatastoreType.OPERATIONAL, statIID, statRecord, true);
}
}
- return true;
+ return DataStoreHelper.submitToDs(wtx);
}
@Override
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.groupbasedpolicy.util.IidFactory;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
.setSrcEndpoint(srcBuilder.build())
.setDstEndpoint(dstBuilder.build());
+// manager.writeStat(recordsBuilder.build());
+// Mockito.verify(wtx).put(LogicalDatastoreType.OPERATIONAL,
+// IidFactory.statisticRecordIid(key),
+// statRecord.build());
+ CheckedFuture<Void,TransactionCommitFailedException> future = Mockito.mock(CheckedFuture.class);
+ Mockito.when(wtx.submit()).thenReturn(future);
+ Mockito.when(dataBroker.newWriteOnlyTransaction()).thenReturn(wtx);
+
manager.writeStat(recordsBuilder.build());
Mockito.verify(wtx).put(LogicalDatastoreType.OPERATIONAL,
IidFactory.statisticRecordIid(key),
- statRecord.build());
+ statRecord.build(), true);
}
@Test
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
</dependency>
+ <!-- REST client-->
+ <dependency>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-client</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ </dependency>
<!-- SFC -->
<dependency>
<groupId>org.opendaylight.sfc</groupId>
<name>policy-validator-registry</name>
</policy-validator-registry>
+ <statistics-manager>
+ <type xmlns:gbp="urn:opendaylight:params:xml:ns:yang:controller:config:groupbasedpolicy">gbp:statistics-manager</type>
+ <name>statistics-manager</name>
+ </statistics-manager>
+
<gbp-ofoverlay-table-offset>0</gbp-ofoverlay-table-offset>
+
+ <!--<gbp-ofoverlay-sflow-start>false</gbp-ofoverlay-sflow-start>-->
+ <!--<gbp-ofoverlay-sflow-collector-uri>http://192.168.53.2:8008</gbp-ofoverlay-sflow-collector-uri>-->
</module>
</modules>
</data>
getNotificationAdapterDependency(),
getEpRendererAugmentationRegistryDependency(),
getPolicyValidatorRegistryDependency(),
+ getStatisticsManagerDependency(),
getGbpOfoverlayTableOffset().shortValue());
}
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.groupbasedpolicy.api.EpRendererAugmentationRegistry;
import org.opendaylight.groupbasedpolicy.api.PolicyValidatorRegistry;
+import org.opendaylight.groupbasedpolicy.api.StatisticsManager;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.OfOverlayAug;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.OfOverlayL3NatAug;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ActionDefinitionListener;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ClassifierDefinitionListener;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.SubjectFeatures;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.SflowClientSettingsListener;
import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionDefinitionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayConfig;
* using Open vSwitch.
*/
public class OFOverlayRenderer implements AutoCloseable, DataChangeListener {
+
private static final Logger LOG =
LoggerFactory.getLogger(OFOverlayRenderer.class);
public static final RendererName RENDERER_NAME = new RendererName("OFOverlay");
private final EndpointManager endpointManager;
private final PolicyManager policyManager;
private final ClassifierDefinitionListener classifierDefinitionListener;
+ private final SflowClientSettingsListener sflowClientSettingsListener;
private ActionDefinitionListener actionDefinitionListener;
private final OfOverlayAug ofOverlayAug;
private final OfOverlayL3NatAug ofOverlayL3NatAug;
ListenerRegistration<DataChangeListener> configReg;
public OFOverlayRenderer(final DataBroker dataProvider,
- RpcProviderRegistry rpcRegistry,
- NotificationService notificationService,
- EpRendererAugmentationRegistry epRendererAugmentationRegistry,
- PolicyValidatorRegistry policyValidatorRegistry,
- final short tableOffset) {
+ RpcProviderRegistry rpcRegistry,
+ NotificationService notificationService,
+ EpRendererAugmentationRegistry epRendererAugmentationRegistry,
+ PolicyValidatorRegistry policyValidatorRegistry,
+ StatisticsManager statisticsManager,
+ final short tableOffset) {
super();
this.dataBroker = dataProvider;
int numCPU = Runtime.getRuntime().availableProcessors();
policyValidatorRegistry.register(entry.getKey(), entry.getValue());
}
+ sflowClientSettingsListener = new SflowClientSettingsListener(dataProvider, executor, statisticsManager);
+
policyManager = new PolicyManager(dataProvider,
switchManager,
endpointManager,
configBuilder.setGbpOfoverlayTableOffset(tableOffset).build();
writeTableOffset(configBuilder.build());
}
+
+ }
+
+ public ScheduledExecutorService getExecutor() {
+ return executor;
}
// *************
if (ofOverlayAug != null) ofOverlayAug.close();
if (ofOverlayL3NatAug != null) ofOverlayL3NatAug.close();
if (policyManager != null) policyManager.close();
+ if (sflowClientSettingsListener != null) sflowClientSettingsListener.close();
}
// ******************
import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchListener;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sfcutils.SfcIidFactory;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.OFStatisticsManager;
import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
import org.opendaylight.groupbasedpolicy.util.IidFactory;
import org.opendaylight.groupbasedpolicy.util.SingletonTask;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.interests.followed.tenants.followed.tenant.FollowedEndpointGroup;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.interests.followed.tenants.followed.tenant.FollowedEndpointGroupBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPolicies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.PolicyRuleGroupWithEndpointConstraints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroup;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.EndpointListener;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.arp.ArpTasker;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.OFStatisticsManager;
import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
import org.opendaylight.groupbasedpolicy.util.IidFactory;
import org.opendaylight.groupbasedpolicy.util.SetUtils;
// create L3 endpoint
if (oldL3Ep == null && newL3Ep != null) {
createL3Endpoint(newL3Ep);
+ OFStatisticsManager.addL3Endpoint(newL3Ep);
}
// update L3 endpoint
// remove L3 endpoint
if (oldL3Ep != null && newL3Ep == null) {
+ OFStatisticsManager.removeL3Endpoint(oldL3Ep);
removeL3Endpoint(oldL3Ep);
}
}
/**
* An endpoint is external if its endpoint-group is external implicit group.
- *
+ *
* @param ep an endpoint
* @param eigs external implicit groups
* @return {@code true} if the given endpoint has EPG representing external implicit group;
/**
* An endpoint is internal if none of its endpoint-groups is external implicit group.
- *
+ *
* @param ep an endpoint
* @param eigs external implicit groups
* @return {@code true} if the given endpoint does not have EPG representing external implicit
}
ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();
Optional<Endpoints> endpoints =
- DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, IidFactory.endpointsIidWildcard(), rTx);
+ DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+ IidFactory.endpointsIidWildcard(), rTx);
if (!endpoints.isPresent()) {
LOG.warn("No Endpoints present in data store.");
return null;
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+
+import com.google.common.base.Preconditions;
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientHandlerException;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JsonRestClient {
+
+ private static final Logger LOG = LoggerFactory.getLogger(JsonRestClient.class);
+
+ private String uri;
+ private ClientConfig clientConfig;
+ private Client client;
+ private WebResource webResource;
+
+ public JsonRestClient(String uri, Integer connectTimeout, Integer readTimeout) {
+ Preconditions.checkNotNull(uri);
+
+ this.uri = uri;
+ clientConfig = new DefaultClientConfig();
+ clientConfig.getProperties()
+ .put(ClientConfig.PROPERTY_CONNECT_TIMEOUT, connectTimeout);
+ clientConfig.getProperties().put(ClientConfig.PROPERTY_READ_TIMEOUT, readTimeout);
+
+ client = Client.create(clientConfig);
+ webResource = client.resource(this.uri);
+ }
+
+ public String getHost() {
+ return webResource.getURI().getHost();
+ }
+
+ public JsonRestClientResponse get(String path) throws ClientHandlerException {
+ return get(path, null);
+ }
+
+ public JsonRestClientResponse get(String path, MultivaluedMap<String, String> params)
+ throws ClientHandlerException {
+ ClientResponse response;
+ WebResource r = this.webResource.path(path);
+ if (params == null) {
+ response = r.accept(MediaType.APPLICATION_JSON_TYPE).get(ClientResponse.class);
+ } else {
+ response = r.queryParams(params)
+ .accept(MediaType.APPLICATION_JSON_TYPE)
+ .get(ClientResponse.class);
+ }
+ return new JsonRestClientResponse(response);
+ }
+
+ public JsonRestClientResponse post(String path, String someJson) throws ClientHandlerException {
+ ClientResponse response;
+ response = webResource.path(path)
+ .accept(MediaType.APPLICATION_JSON_TYPE)
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .post(ClientResponse.class, someJson);
+ return new JsonRestClientResponse(response);
+ }
+
+ public JsonRestClientResponse put(String path, String someJson) throws ClientHandlerException {
+ ClientResponse response;
+ response = webResource.path(path)
+ .accept(MediaType.APPLICATION_JSON_TYPE)
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .put(ClientResponse.class, someJson);
+ return new JsonRestClientResponse(response);
+ }
+
+ public JsonRestClientResponse delete(String path) throws ClientHandlerException {
+ ClientResponse response;
+ response = webResource.path(path)
+ .accept(MediaType.APPLICATION_JSON_TYPE)
+ .delete(ClientResponse.class);
+ return new JsonRestClientResponse(response);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics;
+
+import javax.annotation.Nullable;
+
+import com.sun.jersey.api.client.ClientHandlerException;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.UniformInterfaceException;
+
+public class JsonRestClientResponse {
+
+ private ClientResponse clientResponse;
+ private String entity;
+ private int statusCode;
+ private ClientHandlerException clientHandlerException;
+
+ public JsonRestClientResponse(ClientResponse clientResponse) {
+ this.clientResponse = clientResponse;
+ try {
+ entity = clientResponse.getEntity(String.class);
+ } catch (UniformInterfaceException e) {
+ // in case of 204 No Content
+ entity = null;
+ } catch (ClientHandlerException ex) {
+ clientHandlerException = ex;
+ // LOG.warn("Error getting response entity while status code is: {}",
+ // clientResponse.getClientResponseStatus(), ex);
+ entity = null;
+ }
+ this.statusCode = clientResponse.getStatus();
+ }
+
+ public ClientResponse getClientResponse() {
+ return clientResponse;
+ }
+
+ public int getStatusCode() {
+ return statusCode;
+ }
+
+ @Nullable
+ public String getJsonResponse() {
+ return entity;
+ }
+
+ @Nullable
+ public ClientHandlerException getClientHandlerException() {
+ return clientHandlerException;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nullable;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.groupbasedpolicy.api.StatisticsManager;
+import org.opendaylight.groupbasedpolicy.dto.ConsEpgKey;
+import org.opendaylight.groupbasedpolicy.dto.EpgKeyDto;
+import org.opendaylight.groupbasedpolicy.dto.ProvEpgKey;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache.FlowCache;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache.FlowCacheFactory;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.util.FlowCacheCons;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.util.IidSflowNameUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicyKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.SetMultimap;
+
+public class OFStatisticsManager implements AutoCloseable {
+
+ // key is String (not a full IpAddress) because
+ // we will get String from REST query to sFlow
+ private static ConcurrentMap<String, EndpointL3> endpointL3ByIpMap = new ConcurrentHashMap<>();
+
+ private static final Logger LOG = LoggerFactory.getLogger(OFStatisticsManager.class);
+
+ private final ScheduledExecutorService executor;
+ private final StatisticsManager statisticsManager;
+ private final Set<String> flowCacheNames = new HashSet<>();
+ private static final SetMultimap<ContractId, Pair<ConsEpgKey, ProvEpgKey>> epgsByContractId = HashMultimap.create();
+ private List<ScheduledFuture<?>> collectStatsTasks = new ArrayList<>();
+
+ private static int MAX_FLOWS = 100;
+ private static double MIN_VALUE_IN_FLOW = 0.1;
+ private static final String AGG_MODE = "sum";
+ private Long delay;
+ private String sflowCollectorUri;
+
+ public OFStatisticsManager(ScheduledExecutorService executor, StatisticsManager statisticsManager) {
+ this.executor = executor;
+ this.statisticsManager = statisticsManager;
+ }
+
+ public synchronized void pullStatsForClassifier(InstanceIdentifier<Classifier> classifierIid,
+ Classifier classifier) {
+ Preconditions.checkNotNull(sflowCollectorUri);
+ Preconditions.checkNotNull(delay);
+ FlowCache flowCache = FlowCacheFactory.createFlowCache(classifierIid, classifier, FlowCacheCons.Value.BYTES);
+ setStatsPulling(flowCache, classifierIid);
+ flowCache = FlowCacheFactory.createFlowCache(classifierIid, classifier, FlowCacheCons.Value.FRAMES);
+ setStatsPulling(flowCache, classifierIid);
+ }
+
+ private void setStatsPulling(FlowCache flowCache, InstanceIdentifier<Classifier> classifierIid) {
+ if (flowCache == null) {
+ LOG.trace("Flow cache is null for classifier {}", classifierIid);
+ return;
+ }
+ ResolvedPolicyKey resolvedPolicyKey = classifierIid.firstKeyOf(ResolvedPolicy.class);
+ ConsEpgKey consEpgKey =
+ new EpgKeyDto(resolvedPolicyKey.getConsumerEpgId(), resolvedPolicyKey.getConsumerTenantId());
+ ProvEpgKey provEpgKey =
+ new EpgKeyDto(resolvedPolicyKey.getProviderEpgId(), resolvedPolicyKey.getProviderTenantId());
+ String flowCacheName = flowCache.getName();
+ ContractId contractId = IidSflowNameUtil.resolveContractIdFromFlowCacheName(flowCacheName);
+ epgsByContractId.put(contractId, Pair.of(consEpgKey, provEpgKey));
+ boolean isFlowCacheNew = flowCacheNames.add(flowCacheName);
+ if (isFlowCacheNew) {
+ SFlowRTConnection sFlowRTConnection = new SFlowRTConnection(executor, sflowCollectorUri, flowCache);
+ ScheduledFuture<?> collectStatsTask = this.executor.scheduleWithFixedDelay(new ReadGbpFlowCacheTask(flowCacheName, sFlowRTConnection,
+ statisticsManager, MAX_FLOWS, MIN_VALUE_IN_FLOW, AGG_MODE), 0, delay, TimeUnit.SECONDS);
+ collectStatsTasks.add(collectStatsTask);
+ }
+ }
+
+ public synchronized static Set<Pair<ConsEpgKey, ProvEpgKey>> getEpgsForContract(ContractId contractId) {
+ return epgsByContractId.get(contractId);
+ }
+
+ public synchronized void setSflowCollectorUri(String sflowCollectorUri) {
+ this.sflowCollectorUri = sflowCollectorUri;
+ }
+
+ public synchronized void setDelay(Long delay) {
+ this.delay = delay;
+ }
+
+ public static EndpointL3 getEndpointL3ForIp(@Nullable String ipAddress) {
+ if (ipAddress == null) {
+ return null;
+ }
+ return endpointL3ByIpMap.get(ipAddress);
+ }
+
+ public static void addL3Endpoint(EndpointL3 endpointL3) {
+ endpointL3ByIpMap.put(getStringIpAddress(endpointL3.getIpAddress()), endpointL3);
+ }
+
+ public static void removeL3Endpoint(EndpointL3 endpointL3) {
+ endpointL3ByIpMap.remove(getStringIpAddress(endpointL3.getIpAddress()));
+ }
+
+ private static String getStringIpAddress(IpAddress ipAddress) {
+ if (ipAddress.getIpv4Address() != null) {
+ return ipAddress.getIpv4Address().getValue();
+ }
+ return ipAddress.getIpv6Address().getValue();
+ }
+
+ @Override
+ public synchronized void close() throws Exception {
+ Iterator<ScheduledFuture<?>> tasksIterator = collectStatsTasks.iterator();
+ while (tasksIterator.hasNext()) {
+ ScheduledFuture<?> scheduledFuture = tasksIterator.next();
+ scheduledFuture.cancel(false);
+ tasksIterator.remove();
+ }
+ epgsByContractId.clear();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics;
+
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.groupbasedpolicy.api.StatisticsManager;
+import org.opendaylight.groupbasedpolicy.dto.ConsEpgKey;
+import org.opendaylight.groupbasedpolicy.dto.EpgKey;
+import org.opendaylight.groupbasedpolicy.dto.EpgKeyDto;
+import org.opendaylight.groupbasedpolicy.dto.ProvEpgKey;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache.FlowCache;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache.FlowCacheData;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.util.FlowCacheCons;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.util.IidSflowNameUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.StatRecords;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.StatRecordsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.EpToEpStatistic;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.EpToEpStatisticBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.EpEpgToEpEpgStatistic;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.EpEpgToEpEpgStatisticBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.ep.epg.to.ep.epg.statistic.MatchedRuleStatisticBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+
+public class ProcessDataTask implements Runnable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ProcessDataTask.class);
+
+ private FlowCache flowCache;
+ private BigInteger timestamp;
+ private StatisticsManager statisticsManager;
+ List<FlowCacheData> dataList;
+
+ public ProcessDataTask(FlowCache flowCache, List<FlowCacheData> dataList, BigInteger timestamp,
+ StatisticsManager statisticsManager) {
+ this.flowCache = flowCache;
+ this.dataList = dataList;
+ this.timestamp = timestamp;
+ this.statisticsManager = statisticsManager;
+ }
+
+ @Override
+ public void run() {
+ for (FlowCacheData flowCacheData : dataList) {
+ Map<String, String> flowCacheDataMap = createFlowCacheDataMap(flowCacheData);
+ if (flowCacheDataMap == null) {
+ LOG.info("Stats are skipped for {}", flowCacheData);
+ continue;
+ }
+ String srcIp = flowCacheDataMap.get(FlowCacheCons.Key.IP_SOURCE.get());
+ String dstIp = flowCacheDataMap.get(FlowCacheCons.Key.IP_DESTINATION.get());
+ EndpointL3 srcEpL3 = OFStatisticsManager.getEndpointL3ForIp(srcIp);
+ EndpointL3 dstEpL3 = OFStatisticsManager.getEndpointL3ForIp(dstIp);
+ if (srcEpL3 != null && dstEpL3 != null) {
+ ContractId contractId = IidSflowNameUtil.resolveContractIdFromFlowCacheName(flowCache.getName());
+ MatchedRuleStatisticBuilder matchedRuleStatisticBuilder = new MatchedRuleStatisticBuilder()
+ .setContract(contractId)
+ .setSubject(IidSflowNameUtil.resolveSubjectNameFromFlowCacheName(flowCache.getName()))
+ .setMatchedRule(IidSflowNameUtil.resolveRuleNameFromFlowCacheName(flowCache.getName()))
+ .setClassifier(ImmutableList
+ .of(IidSflowNameUtil.resolveClassifierNameFromFlowCacheName(flowCache.getName())));
+ if (FlowCacheCons.Value.BYTES.get().equals(IidSflowNameUtil.resolveFlowCacheValue(flowCache.getName()))) {
+ matchedRuleStatisticBuilder.setByteCount(Math.round(flowCacheData.getValue()));
+ } else if (FlowCacheCons.Value.FRAMES.get().equals(IidSflowNameUtil.resolveFlowCacheValue(flowCache.getName()))) {
+ matchedRuleStatisticBuilder.setPacketCount(Math.round(flowCacheData.getValue()));
+ }
+
+ Set<Pair<ConsEpgKey, ProvEpgKey>> epgsForContract = OFStatisticsManager.getEpgsForContract(contractId);
+ Set<EpgKey> epgsFromSrcEp = getEpgsFromEndpoint(srcEpL3);
+ Set<EpgKey> epgsFromDstEp = getEpgsFromEndpoint(dstEpL3);
+ Pair<? extends EpgKey, ? extends EpgKey> leftSrcEpgRightDstEpg = getMatchingEpgs(epgsForContract, epgsFromSrcEp, epgsFromDstEp, flowCache.getDirection());
+ if (leftSrcEpgRightDstEpg == null) {
+ LOG.info("Stats are skipped for {}", flowCacheData);
+ continue;
+ }
+
+ EpEpgToEpEpgStatistic epEpgToEpEpgStats = new EpEpgToEpEpgStatisticBuilder()
+ .setSrcEpg(leftSrcEpgRightDstEpg.getLeft().getEpgId())
+ .setDstEpg(leftSrcEpgRightDstEpg.getRight().getEpgId())
+ .setMatchedRuleStatistic(ImmutableList.of(matchedRuleStatisticBuilder.build()))
+ .build();
+
+ EpToEpStatistic e2e = new EpToEpStatisticBuilder().setSrcL2c(srcEpL3.getL2Context())
+ .setSrcMacAddress(srcEpL3.getMacAddress())
+ .setSrcTenant(srcEpL3.getTenant())
+ .setDstL2c(dstEpL3.getL2Context())
+ .setDstMacAddress(dstEpL3.getMacAddress())
+ .setDstTenant(dstEpL3.getTenant())
+ .setEpEpgToEpEpgStatistic(ImmutableList.of(epEpgToEpEpgStats))
+ .setTimestamp(timestamp)
+ .build();
+
+ StatRecords statRecords = new StatRecordsBuilder().setEpToEpStatistic(ImmutableList.of(e2e)).build();
+
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("[sflow] writing StatRecords: {}", statRecords);
+ }
+ statisticsManager.writeStat(statRecords);
+ }
+ }
+ }
+
+ private Set<EpgKey> getEpgsFromEndpoint(EndpointL3 epL3) {
+ Set<EpgKey> result = new HashSet<>();
+ TenantId tenantId = epL3.getTenant();
+ if (epL3.getEndpointGroup() != null) {
+ result.add(new EpgKeyDto(epL3.getEndpointGroup(), tenantId));
+ }
+ List<EndpointGroupId> epgs = epL3.getEndpointGroups();
+ if (epgs != null) {
+ for (EndpointGroupId epg : epgs) {
+ result.add(new EpgKeyDto(epg, tenantId));
+ }
+ }
+ return result;
+ }
+
+ private Pair<? extends EpgKey, ? extends EpgKey> getMatchingEpgs(Set<Pair<ConsEpgKey, ProvEpgKey>> epgsForContract,
+ Set<EpgKey> epgsFromSrcEp, Set<EpgKey> epgsFromDstEp, Direction direction) {
+ if (direction == null || Direction.Bidirectional == direction) {
+ LOG.info("The bidirectional direction is not supported.");
+ return null;
+ }
+ for (Pair<ConsEpgKey, ProvEpgKey> epgForContract : epgsForContract) {
+ ConsEpgKey consEpg = epgForContract.getLeft();
+ ProvEpgKey provEpg = epgForContract.getRight();
+ if (epgsFromSrcEp.contains(consEpg) && epgsFromDstEp.contains(provEpg)) {
+ if (Direction.In.equals(direction)) {
+ return Pair.of(consEpg, provEpg);
+ } else if (Direction.Out.equals(direction)) {
+ return Pair.of(provEpg, consEpg);
+ }
+ }
+ if (epgsFromSrcEp.contains(provEpg) && epgsFromDstEp.contains(consEpg)) {
+ if (Direction.In.equals(direction)) {
+ return Pair.of(consEpg, provEpg);
+ } else if (Direction.Out.equals(direction)) {
+ return Pair.of(provEpg, consEpg);
+ }
+ }
+ }
+ LOG.info(
+ "EPGs of srcEP and dstEp does not match against EPGs for contract:"
+ + "\nsrcEP EPGs: {}\ndstEP EPGs: {}\nEPGs for contract: {}",
+ epgsFromSrcEp, epgsFromDstEp, epgsForContract);
+ return null;
+ }
+
+ private Map<String, String> createFlowCacheDataMap(FlowCacheData flowCacheData) {
+ String[] splitValues = flowCacheData.getKey().split(",");
+ if (splitValues.length != flowCache.getKeyNum()) {
+ LOG.error(
+ "Key names and key values lists length do not match: {} != {}. Not processing.",
+ flowCache.getKeyNum(), splitValues.length);
+ return null;
+ }
+ Map<String, String> flowCacheDataMap = new HashMap<>();
+ for (int i = 0; i < flowCache.getKeyNum(); i++) {
+ flowCacheDataMap.put(flowCache.getKeyNames()[i], splitValues[i]);
+ }
+ return flowCacheDataMap;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.lang.reflect.Type;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.List;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.opendaylight.groupbasedpolicy.api.StatisticsManager;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache.FlowCacheData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.sun.jersey.core.util.MultivaluedMapImpl;
+
+public class ReadGbpFlowCacheTask implements Runnable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ReadGbpFlowCacheTask.class);
+
+ private static final Type LIST_OF_FLOW_CACHE_DATA = new TypeToken<List<FlowCacheData>>() {}.getType();
+ private static final Gson GSON = new Gson();
+ private static final String MAX_FLOWS_PARAM = "maxFlows";
+ private static final String MIN_VALUE_PARAM = "minValue";
+ private static final String AGG_MODE_PARAM = "aggMode";
+
+ private final SFlowRTConnection sFlowRTConnection;
+ private final StatisticsManager statisticsManager;
+ private final String maxFlows;
+ private final String minValue;
+ private final String aggMode;
+ private final String path;
+
+ public ReadGbpFlowCacheTask(String flowCacheName, SFlowRTConnection sFlowRTConnection,
+ StatisticsManager statisticsManager, Integer maxFlows, Double minValue, String aggMode) {
+ this.path = "/activeflows/ALL/" + checkNotNull(flowCacheName) + "/json";
+ this.sFlowRTConnection = checkNotNull(sFlowRTConnection);
+ this.statisticsManager = checkNotNull(statisticsManager);
+ this.maxFlows = String.valueOf(checkNotNull(maxFlows));
+ this.minValue = String.valueOf(checkNotNull(minValue));
+ this.aggMode = checkNotNull(aggMode);
+ }
+
+ @Override
+ public void run() {
+ MultivaluedMap<String, String> params = new MultivaluedMapImpl();
+ params.add(MAX_FLOWS_PARAM, maxFlows);
+ params.add(MIN_VALUE_PARAM, minValue);
+ params.add(AGG_MODE_PARAM, aggMode);
+ JsonRestClientResponse result = sFlowRTConnection.get(path, params);
+
+ if (result != null && result.getJsonResponse() != null) {
+ List<FlowCacheData> dataList = GSON.fromJson(result.getJsonResponse(), LIST_OF_FLOW_CACHE_DATA);
+ if (dataList == null) {
+ LOG.trace("Empty reply, not processing");
+ return;
+ }
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Got sFlow reply: {}", result.getJsonResponse());
+ }
+
+ if (result.getStatusCode() < 300) {
+ sFlowRTConnection.getExecutor().execute((new ProcessDataTask(sFlowRTConnection.getFlowCache(), dataList,
+ BigInteger.valueOf(new Date().getTime()), statisticsManager)));
+ } else if (result.getStatusCode() < 400) {
+ LOG.warn("Status code {}, not processing data. Response: {}", result.getStatusCode(),
+ result.getClientResponse().toString());
+ } else {
+ LOG.error("Status code {}, not processing data. Response: {}", result.getStatusCode(),
+ result.getClientResponse().toString());
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPolicies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.PolicyRuleGroupWithEndpointConstraints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroup;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.MapDifference;
+import com.google.common.collect.Maps;
+
+public class ResolvedPolicyClassifierListener extends DataTreeChangeHandler<ResolvedPolicy> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ResolvedPolicyClassifierListener.class);
+ private final OFStatisticsManager ofStatsManager;
+
+ public ResolvedPolicyClassifierListener(DataBroker dataProvider, OFStatisticsManager ofStatsManager) {
+ super(dataProvider, new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+ InstanceIdentifier.builder(ResolvedPolicies.class).child(ResolvedPolicy.class).build()));
+ this.ofStatsManager = checkNotNull(ofStatsManager);
+ }
+
+ @Override
+ protected void onWrite(DataObjectModification<ResolvedPolicy> rootNode,
+ InstanceIdentifier<ResolvedPolicy> rootIdentifier) {
+ ResolvedPolicy resolvedPolicy = rootNode.getDataAfter();
+ Map<InstanceIdentifier<Classifier>, Classifier> classifierByIid =
+ resolveClassifiers(resolvedPolicy, rootIdentifier);
+ for (Entry<InstanceIdentifier<Classifier>, Classifier> classfierEntry : classifierByIid.entrySet()) {
+ LOG.trace("New classifier created: {}\n{}", classfierEntry.getKey(), classfierEntry.getValue());
+ ofStatsManager.pullStatsForClassifier(classfierEntry.getKey(), classfierEntry.getValue());
+ }
+ }
+
+ @Override
+ protected void onDelete(DataObjectModification<ResolvedPolicy> rootNode,
+ InstanceIdentifier<ResolvedPolicy> rootIdentifier) {
+ LOG.debug("Delete is not supported yet.");
+ }
+
+ @Override
+ protected void onSubtreeModified(DataObjectModification<ResolvedPolicy> rootNode,
+ InstanceIdentifier<ResolvedPolicy> rootIdentifier) {
+ ResolvedPolicy resolvedPolicyAfter = rootNode.getDataAfter();
+ ResolvedPolicy resolvedPolicyBefore = rootNode.getDataBefore();
+ Map<InstanceIdentifier<Classifier>, Classifier> classifierByIidAfter =
+ resolveClassifiers(resolvedPolicyAfter, rootIdentifier);
+ Map<InstanceIdentifier<Classifier>, Classifier> classifierByIidBefore =
+ resolveClassifiers(resolvedPolicyBefore, rootIdentifier);
+ MapDifference<InstanceIdentifier<Classifier>, Classifier> difference =
+ Maps.difference(classifierByIidBefore, classifierByIidAfter);
+ Map<InstanceIdentifier<Classifier>, Classifier> createdClassifierByIid = difference.entriesOnlyOnRight();
+ for (Entry<InstanceIdentifier<Classifier>, Classifier> createdClassfierEntry : createdClassifierByIid
+ .entrySet()) {
+ LOG.trace("New classifier created: {}\n{}", createdClassfierEntry.getKey(),
+ createdClassfierEntry.getValue());
+ ofStatsManager.pullStatsForClassifier(createdClassfierEntry.getKey(), createdClassfierEntry.getValue());
+ }
+ // TODO missing impl for case when classifier is changed or removed
+ }
+
+ private Map<InstanceIdentifier<Classifier>, Classifier> resolveClassifiers(ResolvedPolicy resolvedPolicy,
+ InstanceIdentifier<ResolvedPolicy> resolvedPolicyIid) {
+ List<PolicyRuleGroupWithEndpointConstraints> policyRgWithEcs =
+ resolvedPolicy.getPolicyRuleGroupWithEndpointConstraints();
+ if (policyRgWithEcs == null) {
+ return Collections.emptyMap();
+ }
+ Map<InstanceIdentifier<Classifier>, Classifier> result = new HashMap<>();
+ for (PolicyRuleGroupWithEndpointConstraints policyRgWithEc : policyRgWithEcs) {
+ List<PolicyRuleGroup> policyRuleGroups = policyRgWithEc.getPolicyRuleGroup();
+ if (policyRuleGroups == null) {
+ continue;
+ }
+ for (PolicyRuleGroup policyRuleGroup : policyRuleGroups) {
+ List<ResolvedRule> resolvedRules = policyRuleGroup.getResolvedRule();
+ if (resolvedRules == null) {
+ continue;
+ }
+ for (ResolvedRule resolvedRule : resolvedRules) {
+ List<Classifier> classifiers = resolvedRule.getClassifier();
+ if (classifiers == null) {
+ continue;
+ }
+ for (Classifier classifier : classifiers) {
+ InstanceIdentifier<Classifier> classifierIid = resolvedPolicyIid.builder()
+ .child(PolicyRuleGroupWithEndpointConstraints.class)
+ .child(PolicyRuleGroup.class, policyRuleGroup.getKey())
+ .child(ResolvedRule.class, resolvedRule.getKey())
+ .child(Classifier.class, classifier.getKey())
+ .build();
+ result.put(classifierIid, classifier);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics;
+
+import javax.annotation.Nullable;
+import javax.ws.rs.core.MultivaluedMap;
+import java.util.concurrent.ScheduledExecutorService;
+
+import com.google.common.base.Preconditions;
+import com.sun.jersey.api.client.ClientHandlerException;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache.FlowCache;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SFlowRTConnection {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SFlowRTConnection.class);
+
+ private static final int CONNECT_TIMEOUT_MILLISEC = 20000;
+ private static final int READ_TIMEOUT_MILLISEC = 30000;
+ private static final String GET = "GET";
+ private static final String PUT = "PUT";
+ private static final String DELETE = "DELETE";
+
+ private final FlowCache flowCache;
+ private JsonRestClient client;
+ private boolean isInitialized = false;
+ private final ScheduledExecutorService executor;
+ private final String collectorUri;
+
+ public SFlowRTConnection(ScheduledExecutorService executor, String collectorUri, FlowCache flowCache) {
+ this.executor = Preconditions.checkNotNull(executor);
+ this.collectorUri = Preconditions.checkNotNull(collectorUri);
+ this.flowCache = Preconditions.checkNotNull(flowCache);
+
+ this.client = new JsonRestClient(collectorUri, CONNECT_TIMEOUT_MILLISEC,
+ READ_TIMEOUT_MILLISEC);
+ initialize();
+ }
+
+ @Nullable
+ public String getJsonResponse(String path, MultivaluedMap<String, String> params) {
+ try {
+ JsonRestClientResponse responce = client.get(path, params);
+ Preconditions.checkNotNull(responce);
+ logStatusCode(GET, responce.getStatusCode(), path, params);
+ return responce.getJsonResponse();
+ } catch (ClientHandlerException e) {
+ processClientHandlerException(e);
+ }
+ return null;
+ }
+
+ @Nullable
+ public JsonRestClientResponse get(String path,
+ MultivaluedMap<String, String> params) {
+ if (!isInitialized()) {
+ throw new IllegalStateException("SFlowRTConnection is not initialized.");
+ }
+ try {
+ JsonRestClientResponse responce = client.get(path, params);
+ Preconditions.checkNotNull(responce);
+ return responce;
+ } catch (ClientHandlerException e) {
+ processClientHandlerException(e);
+ }
+ return null;
+ }
+
+ @Nullable
+ public JsonRestClientResponse put(String path, String someJson) {
+ if (!isInitialized()) {
+ throw new IllegalStateException("SFlowRTConnection is not initialized.");
+ }
+ return putWithoutInitCheck(path, someJson);
+ }
+
+ private JsonRestClientResponse putWithoutInitCheck(String path,
+ String someJson) {
+ try {
+ JsonRestClientResponse responce = client.put(path, someJson);
+ Preconditions.checkNotNull(responce);
+ logStatusCode(PUT, responce.getStatusCode(), path, null);
+ return responce;
+ } catch (ClientHandlerException e) {
+ processClientHandlerException(e);
+ }
+ return null;
+ }
+
+ public JsonRestClientResponse delete(String path) {
+ if (!isInitialized()) {
+ throw new IllegalStateException("SFlowRTConnection is not initialized.");
+ }
+ try {
+ JsonRestClientResponse responce = client.delete(path);
+ Preconditions.checkNotNull(responce);
+ logStatusCode(DELETE, responce.getStatusCode(), path, null);
+ return responce;
+ } catch (ClientHandlerException e) {
+ processClientHandlerException(e);
+ }
+ return null;
+ }
+
+ public boolean isInitialized() {
+ return isInitialized;
+ }
+
+ public FlowCache getFlowCache() {
+ return flowCache;
+ }
+
+ public ScheduledExecutorService getExecutor() {
+ return executor;
+ }
+
+ public String getCollectorUri() {
+ return collectorUri;
+ }
+
+ public void initialize() {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Initializing flow {}", flowCache);
+ }
+ JsonRestClientResponse initResp =
+ putWithoutInitCheck(flowCache.getPath(), flowCache.getJsonDefinition());
+ Preconditions.checkNotNull(initResp);
+ if (initResp.getStatusCode() < 300) {
+ LOG.info("sFlow connection {} initialization status code {}", getCollectorUri(), initResp.getStatusCode());
+ } else if (initResp.getStatusCode() < 400) {
+ LOG.warn("sFlow connection {} initialization status code {}", getCollectorUri(), initResp.getStatusCode());
+ } else {
+ LOG.error("sFlow connection {} initialization status code {}", getCollectorUri(), initResp.getStatusCode());
+ }
+ this.isInitialized = true;
+ }
+
+ private void processClientHandlerException(ClientHandlerException e) {
+ if (e.getCause() instanceof java.net.SocketTimeoutException || e.getCause() instanceof java.net.ConnectException) {
+ LOG.error("Connection to {} failed: {}", client.getHost(), e.getMessage());
+ this.isInitialized = false;
+ throw e;
+ } else {
+ throw e;
+ }
+ }
+
+ private void logStatusCode(String verb, int status, String path,
+ MultivaluedMap<String, String> params) {
+ if (params != null) {
+ if (status <= 204) {
+ LOG.trace("Query {} {} with params {} returned status {}", verb, path, params,
+ status);
+ } else if (status < 400) {
+ LOG.warn("Query {} {} with params {} returned status {}", verb, path, params,
+ status);
+ } else {
+ LOG.error("Query {} {} with params {} returned status {}", verb, path, params,
+ status);
+ }
+ } else {
+ if (status <= 204) {
+ LOG.trace("Query {} {} returned status {}", verb, path, status);
+ } else if (status < 400) {
+ LOG.warn("Query {} {} returned status {}", verb, path, status);
+ } else {
+ LOG.error("Query {} {} returned status {}", verb, path, status);
+ }
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics;
+
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.api.StatisticsManager;
+import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.sflow.values.SflowClientSettings;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+
+public class SflowClientSettingsListener extends DataTreeChangeHandler<SflowClientSettings> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SflowClientSettingsListener.class);
+ private static InstanceIdentifier<SflowClientSettings> IID =
+ InstanceIdentifier.builder(OfOverlayConfig.class)
+ .child(SflowClientSettings.class)
+ .build();
+ private OFStatisticsManager ofStatisticsManager;
+ private final ScheduledExecutorService executor;
+ private final StatisticsManager statisticsManager;
+ private ResolvedPolicyClassifierListener classifierListener;
+
+ public SflowClientSettingsListener(DataBroker dataprovider, ScheduledExecutorService executor, StatisticsManager statisticsManager) {
+ super(dataprovider, new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, IID));
+ this.statisticsManager = Preconditions.checkNotNull(statisticsManager);
+ this.executor = Preconditions.checkNotNull(executor);
+ }
+
+ @Override
+ protected void onWrite(DataObjectModification<SflowClientSettings> rootNode,
+ InstanceIdentifier<SflowClientSettings> rootIdentifier) {
+ onSubtreeModified(rootNode, rootIdentifier);
+ }
+
+ @Override
+ protected void onDelete(DataObjectModification<SflowClientSettings> rootNode,
+ InstanceIdentifier<SflowClientSettings> rootIdentifier) {
+ try {
+ classifierListener.close();
+ ofStatisticsManager.close();
+ } catch (Exception e) {
+ LOG.error(
+ "Error during closing OFStatisticsManager and ResolvedPolicyClassifierListener. "
+ + "Statistics do not have to be correct because of illegal state.", e);
+ }
+ }
+
+ @Override
+ protected void onSubtreeModified(DataObjectModification<SflowClientSettings> rootNode,
+ InstanceIdentifier<SflowClientSettings> rootIdentifier) {
+ SflowClientSettings sflowClientSettings =
+ Preconditions.checkNotNull(rootNode.getDataAfter());
+ if (classifierListener != null && ofStatisticsManager != null) {
+ try {
+ classifierListener.close();
+ ofStatisticsManager.close();
+ } catch (Exception e) {
+ LOG.error(
+ "Error during closing OFStatisticsManager and ResolvedPolicyClassifierListener. "
+ + "Statistics do not have to be correct because of illegal state.", e);
+ }
+ }
+ ofStatisticsManager = new OFStatisticsManager(executor, statisticsManager);
+ ofStatisticsManager.setSflowCollectorUri(sflowClientSettings.getGbpOfoverlaySflowCollectorUri());
+ ofStatisticsManager.setDelay(sflowClientSettings.getGbpOfoverlaySflowRetrieveInterval());
+ classifierListener = new ResolvedPolicyClassifierListener(dataProvider, ofStatisticsManager);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache;
+
+import java.util.Arrays;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
+
+import com.google.common.base.Preconditions;
+import com.google.gson.Gson;
+
+public class FlowCache {
+
+ static final String API_FLOW = "/flow/";
+ static final String SUFFIX_JSON = "/json";
+
+ private transient Direction direction;
+ private String name;
+ private FlowCacheDefinition definition;
+
+ /** Array containing key names from FlowCacheDefinition */
+ private String[] keyNames;
+ private int keyNum;
+
+ private FlowCache() {
+ }
+
+ private FlowCache(FlowCacheBuilder builder) {
+ this.name = builder.getName();
+ this.definition = builder.getDefinition();
+ this.direction = builder.getDirection();
+
+ this.keyNames = this.definition.getKeys().split(",");
+ this.keyNum = this.keyNames.length;
+ for (int i = 0; i < this.keyNum; i++) {
+ keyNames[i] = parseNullableKeyName(keyNames[i]);
+ }
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public FlowCacheDefinition getDefinition() {
+ return definition;
+ }
+
+ public Direction getDirection() {
+ return direction;
+ }
+
+ public String[] getKeyNames() {
+ return keyNames;
+ }
+
+ public int getKeyNum() {
+ return keyNum;
+ }
+
+ public String getPath() {
+ return API_FLOW + name + SUFFIX_JSON;
+ }
+
+ public String getJsonDefinition() {
+ Gson gson = new Gson();
+ return gson.toJson(definition);
+ }
+
+ public static FlowCacheBuilder builder() {
+ return new FlowCacheBuilder();
+ }
+
+ private String parseNullableKeyName(String nullableKeyName) {
+ String res = nullableKeyName.replaceAll("^\\w+:(\\w+):.*", "$1");
+ return "".equals(res) ? nullableKeyName : res;
+ }
+
+ @Override
+ public String toString() {
+ return "FlowCache [name=" + name + ", definition=" + definition + ", keyNames=" + Arrays.toString(keyNames)
+ + ", keyNum=" + keyNum + "]";
+ }
+
+ public static class FlowCacheBuilder {
+
+ private String name;
+ private FlowCacheDefinition definition;
+ private Direction direction;
+
+ public String getName() {
+ return name;
+ }
+
+ public FlowCacheBuilder setName(String name) {
+ Preconditions.checkNotNull(name);
+ this.name = name;
+ return this;
+ }
+
+ public FlowCacheDefinition getDefinition() {
+ return definition;
+ }
+
+ public FlowCacheBuilder setDefinition(FlowCacheDefinition definition) {
+ Preconditions.checkNotNull(definition);
+ this.definition = definition;
+ return this;
+ }
+
+ public Direction getDirection() {
+ return direction;
+ }
+
+ public FlowCacheBuilder setDirection(Direction direction) {
+ this.direction = direction;
+ return this;
+ }
+
+ public FlowCache build() {
+ return new FlowCache(this);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache;
+
+public class FlowCacheData {
+
+ private String key;
+ private double value;
+
+ private FlowCacheData() {
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public double getValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return "FlowCacheData [key=" + key + ", value=" + value + "]";
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache;
+
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache.FlowCacheFilter.FlowCacheFilterBuilder;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache.FlowCacheKeys.FlowCacheKeysBuilder;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * An object to handle flow-cache parameters for JSON conversion
+ */
+public final class FlowCacheDefinition {
+
+ private String keys;
+ private String value;
+ private String filter;
+ private boolean log;
+
+ private FlowCacheDefinition() {
+ }
+
+ private FlowCacheDefinition(FlowCacheDefinitionBuilder builder) {
+ this.keys = builder.getKeysBuilder().build().getValue();
+ this.value = builder.getValue();
+ this.filter = builder.getFilterBuilder().build().getValue();
+ this.log = builder.isLog();
+ }
+
+ public String getKeys() {
+ return keys;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public String getFilter() {
+ return filter;
+ }
+
+ public boolean getLog() {
+ return log;
+ }
+
+ public static FlowCacheDefinitionBuilder builder(){
+ return new FlowCacheDefinitionBuilder();
+ }
+
+ @Override
+ public String toString() {
+ return "FlowCacheDefinition [keys=" + keys + ", value=" + value + ", filter=" + filter + ", log=" + log + "]";
+ }
+
+ public static class FlowCacheDefinitionBuilder {
+
+ private String value;
+ private boolean log = false;
+ private final FlowCacheKeysBuilder keysBuilder = new FlowCacheKeysBuilder();
+ private final FlowCacheFilterBuilder filterBuilder = new FlowCacheFilterBuilder();
+
+ public FlowCacheKeysBuilder getKeysBuilder() {
+ return keysBuilder;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public FlowCacheDefinitionBuilder setValue(String value) {
+ Preconditions.checkNotNull(value);
+ this.value = value;
+ return this;
+ }
+
+ public FlowCacheFilterBuilder getFilterBuilder() {
+ return filterBuilder;
+ }
+
+ public boolean isLog() {
+ return log;
+ }
+
+ public FlowCacheDefinitionBuilder setLog(boolean log) {
+ this.log = log;
+ return this;
+ }
+
+ public FlowCacheDefinition build() {
+ return new FlowCacheDefinition(this);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache;
+
+import java.util.List;
+
+import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache.FlowCache.FlowCacheBuilder;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache.FlowCacheDefinition.FlowCacheDefinitionBuilder;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.util.FlowCacheCons;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.util.IidSflowNameUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FlowCacheFactory {
+
+ private static final Logger LOG = LoggerFactory.getLogger(FlowCacheFactory.class);
+
+ public static FlowCache createFlowCache(InstanceIdentifier<Classifier> classifierIid, Classifier classifier,
+ FlowCacheCons.Value value) {
+ FlowCacheDefinition flowCacheDefinition = creteFlowCacheDefinition(classifier, value);
+ if (flowCacheDefinition == null) {
+ LOG.info("Cannot create flow cache for statistics of classifier {}\n{}", classifierIid, classifier);
+ return null;
+ }
+ return new FlowCacheBuilder().setDefinition(flowCacheDefinition)
+ .setName(IidSflowNameUtil.createFlowCacheName(classifierIid, value))
+ .setDirection(classifier.getDirection())
+ .build();
+ }
+
+ public static FlowCacheDefinition creteFlowCacheDefinition(Classifier classifier, FlowCacheCons.Value value) {
+ FlowCacheDefinitionBuilder fcdBuilder = new FlowCacheDefinitionBuilder();
+ if (L4ClassifierDefinition.ID.equals(classifier.getClassifierDefinitionId())) {
+ addEthTypeInfoToFlowCache(classifier, fcdBuilder);
+ if (!addIpProtoInfoToFlowCache(classifier, fcdBuilder)) {
+ return null;
+ }
+ if (!addL4InfoToFlowCache(classifier, fcdBuilder)) {
+ return null;
+ }
+ } else if (IpProtoClassifierDefinition.ID.equals(classifier.getClassifierDefinitionId())) {
+ addEthTypeInfoToFlowCache(classifier, fcdBuilder);
+ if (!addIpProtoInfoToFlowCache(classifier, fcdBuilder)) {
+ return null;
+ }
+ } else if (EtherTypeClassifierDefinition.ID.equals(classifier.getClassifierDefinitionId())) {
+ addEthTypeInfoToFlowCache(classifier, fcdBuilder);
+ } else {
+ LOG.warn("Sflow stats will not be pulled because of unknown classifier: {}", classifier);
+ return null;
+ }
+ fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.IP_SOURCE.get()).addValue(FlowCacheCons.Key.IP_DESTINATION.get());
+ fcdBuilder.setValue(value.get());
+ return fcdBuilder.build();
+ }
+
+ private static void addEthTypeInfoToFlowCache(Classifier classifier, FlowCacheDefinitionBuilder fcdBuilder) {
+ List<ParameterValue> parametersAndValues = classifier.getParameterValue();
+ ParameterValue ethTypeParam = getParamVal(parametersAndValues, EtherTypeClassifierDefinition.ETHERTYPE_PARAM);
+ if (ethTypeParam != null) {
+ fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.ETH_PROTOCOL.get());
+ fcdBuilder.getFilterBuilder()
+ .addValue(FlowCacheCons.Key.ETH_PROTOCOL.get() + FlowCacheCons.EQ + ethTypeParam.getIntValue());
+ } else {
+ fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.ETH_PROTOCOL.get());
+ fcdBuilder.getFilterBuilder()
+ .addValue(FlowCacheCons.Key.ETH_PROTOCOL.get() + FlowCacheCons.EQ + FlowUtils.IPv4 + FlowCacheCons.OR
+ + FlowCacheCons.Key.ETH_PROTOCOL.get() + FlowCacheCons.EQ + FlowUtils.IPv6);
+ }
+ }
+
+ private static boolean addIpProtoInfoToFlowCache(Classifier classifier, FlowCacheDefinitionBuilder fcdBuilder) {
+ List<ParameterValue> parametersAndValues = classifier.getParameterValue();
+ ParameterValue ipProtoParam = getParamVal(parametersAndValues, IpProtoClassifierDefinition.PROTO_PARAM);
+ if (ipProtoParam != null) {
+ fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.IP_PROTOCOL.get());
+ fcdBuilder.getFilterBuilder()
+ .addValue(FlowCacheCons.Key.IP_PROTOCOL.get() + FlowCacheCons.EQ + ipProtoParam.getIntValue());
+ return true;
+ } else {
+ LOG.trace("Cannot add ip-proto information to flow cache for Sflow-RT.");
+ return false;
+ }
+ }
+
+ private static boolean addL4InfoToFlowCache(Classifier classifier, FlowCacheDefinitionBuilder fcdBuilder) {
+ List<ParameterValue> parametersAndValues = classifier.getParameterValue();
+ ParameterValue ipProtoParam = getParamVal(parametersAndValues, IpProtoClassifierDefinition.PROTO_PARAM);
+ ParameterValue dstPortParam = getParamVal(parametersAndValues, L4ClassifierDefinition.DST_PORT_PARAM);
+ ParameterValue srcPortParam = getParamVal(parametersAndValues, L4ClassifierDefinition.SRC_PORT_PARAM);
+ if (ipProtoParam == null || (dstPortParam == null && srcPortParam == null)) {
+ LOG.trace(
+ "Cannot add L4 information to flow cache for Sflow-RT."
+ + "\nipProtoParam:{} dstPortParam:{} srcPortParam:{}",
+ ipProtoParam, dstPortParam, srcPortParam);
+ return false;
+ }
+ if (dstPortParam != null) {
+ if (!addTcpUdpPortKeys(ipProtoParam.getIntValue(), dstPortParam.getIntValue(), true, fcdBuilder)) {
+ return false;
+ }
+ }
+ if (srcPortParam != null) {
+ if (!addTcpUdpPortKeys(ipProtoParam.getIntValue(), srcPortParam.getIntValue(), false, fcdBuilder)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static ParameterValue getParamVal(List<ParameterValue> parametersAndValues, String paramName) {
+ for (ParameterValue paramVal : parametersAndValues) {
+ if (paramName.equals(paramVal.getName().getValue())) {
+ return paramVal;
+ }
+ }
+ return null;
+ }
+
+ private static boolean addTcpUdpPortKeys(Long ipProto, Long port, boolean isDstPort,
+ FlowCacheDefinitionBuilder fcdBuilder) {
+ if (isDstPort) {
+ if (ipProto == IpProtoClassifierDefinition.TCP_VALUE) {
+ fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.TCP_DST_PORT.get());
+ fcdBuilder.getFilterBuilder().addValue(FlowCacheCons.Key.TCP_DST_PORT.get() + FlowCacheCons.EQ + port);
+ } else if (ipProto == IpProtoClassifierDefinition.UDP_VALUE) {
+ fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.UDP_DST_PORT.get());
+ fcdBuilder.getFilterBuilder().addValue(FlowCacheCons.Key.UDP_DST_PORT.get() + FlowCacheCons.EQ + port);
+ } else {
+ LOG.info("Statistics cannot be collected for ip-proto {} and port {}", ipProto, port);
+ return false;
+ }
+ } else {
+ if (ipProto == IpProtoClassifierDefinition.TCP_VALUE) {
+ fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.TCP_SRC_PORT.get());
+ fcdBuilder.getFilterBuilder().addValue(FlowCacheCons.Key.TCP_SRC_PORT.get() + FlowCacheCons.EQ + port);
+ } else if (ipProto == IpProtoClassifierDefinition.UDP_VALUE) {
+ fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.UDP_SRC_PORT.get());
+ fcdBuilder.getFilterBuilder().addValue(FlowCacheCons.Key.UDP_SRC_PORT.get() + FlowCacheCons.EQ + port);
+ } else {
+ LOG.info("Statistics cannot be collected for ip-proto {} and port {}", ipProto, port);
+ return false;
+ }
+ }
+ return true;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+
+public final class FlowCacheFilter {
+
+ private static final String AND = "&";
+ private static final String LB = "(";
+ private static final String RB = ")";
+
+ private String value;
+
+ private FlowCacheFilter(FlowCacheFilterBuilder builder) {
+ this.value = Joiner.on(AND).join(builder.getValues());
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public static FlowCacheFilterBuilder builder(){
+ return new FlowCacheFilterBuilder();
+ }
+
+ public static class FlowCacheFilterBuilder {
+
+ private List<String> values = new ArrayList<>();
+
+ public List<String> getValues() {
+ return values;
+ }
+
+ public FlowCacheFilterBuilder setValues(List<String> values) {
+ this.values = Preconditions.checkNotNull(values);
+ return this;
+ }
+
+ public FlowCacheFilterBuilder addValue(String value) {
+ values.add(LB + Preconditions.checkNotNull(value) + RB);
+ return this;
+ }
+
+ public FlowCacheFilter build() {
+ return new FlowCacheFilter(this);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+
+public final class FlowCacheKeys {
+
+ private static final String SEPARATOR = ",";
+
+ private String value;
+
+ private FlowCacheKeys(FlowCacheKeysBuilder builder) {
+ this.value = Joiner.on(SEPARATOR).join(builder.getValues());
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public static FlowCacheKeysBuilder builder(){
+ return new FlowCacheKeysBuilder();
+ }
+
+ public static class FlowCacheKeysBuilder {
+
+ private List<String> values = new ArrayList<>();
+
+ public List<String> getValues() {
+ return values;
+ }
+
+ public FlowCacheKeysBuilder setValues(List<String> values) {
+ this.values = Preconditions.checkNotNull(values);
+ return this;
+ }
+
+ public FlowCacheKeysBuilder addValue(String value) {
+ values.add(Preconditions.checkNotNull(value));
+ return this;
+ }
+
+ public FlowCacheKeys build() {
+ return new FlowCacheKeys(this);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.util;
+
+public class FlowCacheCons {
+
+ public static final String EQ = "=";
+ public static final String OR = "|";
+
+ public static enum Key {
+ TCP_DST_PORT("tcpdestinationport"),
+ TCP_SRC_PORT("tcpsourceport"),
+ UDP_DST_PORT("udpdestinationport"),
+ UDP_SRC_PORT("udpsourceport"),
+ IP_PROTOCOL("ipprotocol"),
+ ETH_PROTOCOL("ethernetprotocol"),
+ IP_SOURCE("ipsource"),
+ IP_DESTINATION("ipdestination");
+
+ private String val;
+
+ private Key(String val) {
+ this.val = val;
+ }
+
+ public String get() {
+ return val;
+ }
+ }
+
+ public static enum Value {
+ BYTES("bytes"),
+ FRAMES("frames");
+
+ private String val;
+
+ private Value(String val) {
+ this.val = val;
+ }
+
+ public String get() {
+ return val;
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.util;
+
+import java.util.List;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.ClassifierKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRuleKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroupKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+
+public class IidSflowNameUtil {
+
+ public static final String DELIMETER = "_-_";
+ public static final String KEY_DELIMETER = "-_-";
+
+ public static String createFlowCacheName(InstanceIdentifier<Classifier> classifierIid, FlowCacheCons.Value value) {
+ PolicyRuleGroupKey policyRuleGroup = classifierIid.firstKeyOf(PolicyRuleGroup.class);
+ ResolvedRuleKey resolvedRule = classifierIid.firstKeyOf(ResolvedRule.class);
+ ClassifierKey classifier = classifierIid.firstKeyOf(Classifier.class);
+ StringBuilder sb = new StringBuilder();
+ sb.append(createStringFromCompositeKey(policyRuleGroup.getTenantId().getValue(),
+ policyRuleGroup.getContractId().getValue(), policyRuleGroup.getSubjectName().getValue()))
+ .append(DELIMETER)
+ .append(resolvedRule.getName().getValue())
+ .append(DELIMETER)
+ .append(classifier.getName().getValue())
+ .append(DELIMETER)
+ .append(value.get());
+ return sb.toString();
+ }
+
+ private static String createStringFromCompositeKey(String... keys) {
+ return Joiner.on(KEY_DELIMETER).join(keys);
+ }
+
+ public static ContractId resolveContractIdFromFlowCacheName(String flowCacheName) {
+ List<String> keys = Splitter.on(DELIMETER).splitToList(flowCacheName);
+ String policyRuleGroupKey = keys.get(0);
+ String contractId = Splitter.on(KEY_DELIMETER).splitToList(policyRuleGroupKey).get(1);
+ return new ContractId(contractId);
+ }
+
+ public static SubjectName resolveSubjectNameFromFlowCacheName(String flowCacheName) {
+ List<String> keys = Splitter.on(DELIMETER).splitToList(flowCacheName);
+ String policyRuleGroupKey = keys.get(0);
+ String subjectName = Splitter.on(KEY_DELIMETER).splitToList(policyRuleGroupKey).get(2);
+ return new SubjectName(subjectName);
+ }
+
+ public static RuleName resolveRuleNameFromFlowCacheName(String flowCacheName) {
+ List<String> keys = Splitter.on(DELIMETER).splitToList(flowCacheName);
+ String ruleName = keys.get(1);
+ return new RuleName(ruleName);
+ }
+
+ public static ClassifierName resolveClassifierNameFromFlowCacheName(String flowCacheName) {
+ List<String> keys = Splitter.on(DELIMETER).splitToList(flowCacheName);
+ String classifierName = keys.get(2);
+ return new ClassifierName(classifierName);
+ }
+
+ public static String resolveFlowCacheValue(String flowCacheName) {
+ List<String> keys = Splitter.on(DELIMETER).splitToList(flowCacheName);
+ return keys.get(3);
+ }
+}
config:java-name-prefix OFOverlayProvider;
}
- // Augments the 'configuration' choice node under modules/module.
+ // Augments the 'configuration' choice node under modules/module.
augment "/config:modules/config:module/config:configuration" {
case ofoverlay-provider-impl {
when "/config:modules/config:module/config:type = 'ofoverlay-provider-impl'";
}
}
}
+ // StatisticsManager service
+ container statistics-manager {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity gbpcfg:statistics-manager;
+ }
+ }
+ }
uses ofoverlay:initial-values;
+ //uses ofoverlay:sflow-values;
}
}
}
}
uses initial-values;
+ uses sflow-values;
}
grouping initial-values {
}
}
+ grouping sflow-values {
+ description
+ "Values for sFlow-RT collector setup";
+ container sflow-client-settings {
+ leaf gbp-ofoverlay-sflow-retrieve-interval {
+ description
+ "Interval (seconds) for periodical flowcache data retrieve.";
+ type uint32;
+ default 20;
+ }
+ leaf gbp-ofoverlay-sflow-collector-uri {
+ description
+ "URI of sFlow-RT collector, including schema, IP/domain, port. No trailing slash.";
+ mandatory true;
+ type string;
+ }
+ }
+ }
+
grouping endpoint-location {
description
"The location for this endpoint in the overlay network";
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.groupbasedpolicy.api.PolicyValidatorRegistry;
+import org.opendaylight.groupbasedpolicy.api.StatisticsManager;
import org.opendaylight.groupbasedpolicy.endpoint.EndpointRpcRegistry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayConfig;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
private EndpointRpcRegistry endpointRpcRegistry;
private NotificationService notificationService;
private PolicyValidatorRegistry policyValidatorRegistry;
+ private StatisticsManager statisticsManager;
private short tableOffset;
private CheckedFuture<Optional<OfOverlayConfig>, ReadFailedException> future;
private ListenerRegistration<DataChangeListener> configReg;
endpointRpcRegistry = mock(EndpointRpcRegistry.class);
notificationService = mock(NotificationService.class);
policyValidatorRegistry = mock(PolicyValidatorRegistry.class);
+ statisticsManager = mock(StatisticsManager.class);
tableOffset = 5;
configReg = mock(ListenerRegistration.class);
when(dataProvider.registerDataChangeListener(any(LogicalDatastoreType.class), any(InstanceIdentifier.class),
future = Futures.immediateCheckedFuture(Optional.<OfOverlayConfig> absent());
when(readTransaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(future);
renderer = new OFOverlayRenderer(dataProvider, rpcRegistry, notificationService, endpointRpcRegistry,
- policyValidatorRegistry, tableOffset);
+ policyValidatorRegistry, statisticsManager, tableOffset);
}
@Test
public void constructorTest() throws Exception {
renderer.close();
- verify(configReg, times(10)).close();
+ verify(configReg, times(11)).close();
}
@Test
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.EndpointListener;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
tenantId = mock(TenantId.class);
endpointGroupId = mock(EndpointGroupId.class);
l2BridgeDomainId = mock(L2BridgeDomainId.class);
- MacAddress macAddress = mock(MacAddress.class);
+ MacAddress macAddress = new MacAddress("12:34:56:78:9a:bc");
when(endpoint1.getTenant()).thenReturn(tenantId);
when(endpoint1.getEndpointGroup()).thenReturn(endpointGroupId);
when(endpoint1.getL2Context()).thenReturn(l2BridgeDomainId);
when(newL3Ep.getKey()).thenReturn(endpointL3Key);
IpAddress ipAddress = mock(IpAddress.class);
when(endpointL3Key.getIpAddress()).thenReturn(ipAddress);
-
+ when(newL3Ep.getIpAddress()).thenReturn(new IpAddress(new Ipv4Address("1.1.1.1")));
manager.processL3Endpoint(null, newL3Ep);
verify(endpointListener,never()).endpointUpdated(any(EpKey.class));
}
when(newL3Ep.getKey()).thenReturn(endpointL3Key);
IpAddress ipAddress = mock(IpAddress.class);
when(endpointL3Key.getIpAddress()).thenReturn(ipAddress);
-
+ when(newL3Ep.getIpAddress()).thenReturn(new IpAddress(new Ipv4Address("1.1.1.1")));
manager.processL3Endpoint(null, newL3Ep);
verify(endpointListener,never()).endpointUpdated(any(EpKey.class));
}
when(newL3Ep.getL2Context()).thenReturn(mock(L2BridgeDomainId.class));
when(newL3Ep.getMacAddress()).thenReturn(mock(MacAddress.class));
-
+ when(newL3Ep.getIpAddress()).thenReturn(new IpAddress(new Ipv4Address("1.1.1.1")));
manager.processL3Endpoint(null, newL3Ep);
verify(endpointListener).endpointUpdated(any(EpKey.class));
}
when(newL3Ep.getEndpointGroup()).thenReturn(mock(EndpointGroupId.class));
when(newL3Ep.getL3Context()).thenReturn(mock(L3ContextId.class));
when(newL3Ep.getIpAddress()).thenReturn(null);
-
+ when(newL3Ep.getIpAddress()).thenReturn(new IpAddress(new Ipv4Address("1.1.1.1")));
manager.processL3Endpoint(null, newL3Ep);
verify(endpointListener,never()).endpointUpdated(any(EpKey.class));
}
@Test
public void updateEndpointL3TestDelete() throws Exception {
+ when(oldL3Ep.getIpAddress()).thenReturn(new IpAddress(new Ipv4Address("1.1.1.1")));
manager.processL3Endpoint(oldL3Ep, null);
verify(endpointListener).endpointUpdated(any(EpKey.class));
}