16 package org.openkilda.pce.model;
22 import org.neo4j.driver.v1.AccessMode;
23 import org.neo4j.driver.v1.Driver;
24 import org.neo4j.driver.v1.Session;
25 import org.neo4j.driver.v1.StatementResult;
26 import org.neo4j.driver.v1.Value;
27 import org.neo4j.driver.v1.Values;
28 import org.neo4j.driver.v1.types.Relationship;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
32 import java.util.Collections;
33 import java.util.Comparator;
34 import java.util.HashMap;
35 import java.util.List;
37 import java.util.Map.Entry;
39 import java.util.stream.Collectors;
49 private static final Logger logger = LoggerFactory.getLogger(
AvailableNetwork.class);
51 private HashMap<SwitchId, SimpleSwitch> switches =
new HashMap<>();
53 private final Driver driver;
58 public AvailableNetwork(Driver driver,
boolean ignoreBandwidth,
long requestedBandwidth) {
61 buildNetwork(ignoreBandwidth, requestedBandwidth);
81 switches.put(dpid,
result);
90 int cost,
int latency) {
95 logger.warn(
"Found ZERO COST ISL: {}", isl);
105 return switches.get(dpid);
113 Map<String, Integer>
result =
new HashMap<>();
115 result.put(
"SWITCHES", switches.size());
120 neighbors += sw.outbound.size();
121 for (Set<SimpleIsl> isls : sw.outbound.values()) {
122 islCount += isls.size();
125 result.put(
"NEIGHBORS", neighbors);
126 result.put(
"ISLS", islCount);
158 if (sw.outbound.size() < 1) {
159 logger.warn(
"AvailableNetwork: Switch {} has NO OUTBOUND isls", sw.dpid);
162 for (Entry<
SwitchId, Set<SimpleIsl>> linksEntry : sw.outbound.entrySet()) {
163 Set<SimpleIsl> links = linksEntry.getValue();
164 if (links.size() <= 1) {
169 .min(Comparator.comparingInt(SimpleIsl::getCost))
172 sw.outbound.put(linksEntry.getKey(), Collections.singleton(cheapestLink));
184 if (sw.outbound.containsKey(sw.dpid)) {
185 sw.outbound.remove(sw.dpid);
200 +
"MATCH (src:switch)-[fs:flow_segment{flowid: $flow_id}]->(dst:switch) " 201 +
"MATCH (src)-[link:isl]->(dst) " 202 +
"WHERE src.state = 'active' AND dst.state = 'active' AND link.status = 'active' " 203 +
"AND link.src_port = fs.src_port AND link.dst_port = fs.dst_port " 204 +
"AND ($ignore_bandwidth OR link.available_bandwidth + fs.bandwidth >= $requested_bandwidth) " 207 Value parameters = Values.parameters(
209 "ignore_bandwidth", ignoreBandwidth,
210 "requested_bandwidth", flowBandwidth);
212 List<Relationship> links = loadAvailableLinks(query, parameters);
213 addLinksFromRelationships(links);
222 private void buildNetwork(
boolean ignoreBandwidth,
long flowBandwidth) {
223 String q =
"MATCH (src:switch)-[link:isl]->(dst:switch) " 224 +
" WHERE src.state = 'active' AND dst.state = 'active' AND link.status = 'active' " 225 +
" AND src.name IS NOT NULL AND dst.name IS NOT NULL " 226 +
" AND ($ignore_bandwidth OR link.available_bandwidth >= $requested_bandwidth) " 229 Value parameters = Values.parameters(
230 "ignore_bandwidth", ignoreBandwidth,
231 "requested_bandwidth", flowBandwidth
234 List<Relationship> links = loadAvailableLinks(q, parameters);
235 addLinksFromRelationships(links);
243 private List<Relationship> loadAvailableLinks(String query, Value parameters) {
244 logger.debug(
"Executing query for getting links to fill AvailableNetwork: {}", query);
245 try (Session session = driver.session(AccessMode.READ)) {
246 StatementResult queryResults = session.run(query, parameters);
247 return queryResults.list()
249 .map(record -> record.get(
"link"))
250 .map(Value::asRelationship)
251 .collect(Collectors.toList());
255 private void addLinksFromRelationships(List<Relationship> links) {
257 addLink(
new SwitchId(isl.get(
"src_switch").asString()),
258 new SwitchId(isl.get(
"dst_switch").asString()),
259 safeAsInt(isl.get(
"src_port")),
260 safeAsInt(isl.get(
"dst_port")),
261 safeAsInt(isl.get(
"cost")),
262 safeAsInt(isl.get(
"latency"))
268 String
result =
"AvailableNetwork{";
269 StringBuilder sb =
new StringBuilder();
AvailableNetwork(Driver driver, boolean ignoreBandwidth, long requestedBandwidth)
Map< String, Integer > getCounts()
Map< SwitchId, SimpleSwitch > getSwitches()
AvailableNetwork(Driver driver)
AvailableNetwork addLink(SwitchId srcDpid, SwitchId dstDpid, int srcPort, int dstPort, int cost, int latency)
AvailableNetwork removeSelfLoops()
static int safeAsInt(Value val)
void addIslsOccupiedByFlow(String flowId, boolean ignoreBandwidth, long flowBandwidth)
SimpleSwitch getSimpleSwitch(SwitchId dpid)
SimpleSwitch addOutbound(SimpleIsl isl)