blob: 61dde3abd56bc7b4627bba2519d564df5d50d172 [file] [log] [blame]
Jonathan Hart062a2e82014-02-03 09:41:57 -08001package net.onrc.onos.ofcontroller.networkgraph;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import net.onrc.onos.datastore.RCObject;
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -08007import net.onrc.onos.datastore.RCObject.WriteOp;
Jonathan Hart369875b2014-02-13 10:00:31 -08008import net.onrc.onos.datastore.topology.RCLink;
Jonathan Hart69864df2014-02-13 10:44:12 -08009import net.onrc.onos.datastore.topology.RCPort;
Jonathan Hartdaea86f2014-02-19 15:28:42 -080010import net.onrc.onos.datastore.topology.RCPort.STATUS;
Jonathan Hart062a2e82014-02-03 09:41:57 -080011import net.onrc.onos.datastore.topology.RCSwitch;
12
13import org.slf4j.Logger;
14import org.slf4j.LoggerFactory;
15
Jonathan Hart062a2e82014-02-03 09:41:57 -080016/**
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080017 * The southbound interface to the network graph which allows clients to
Jonathan Hart062a2e82014-02-03 09:41:57 -080018 * mutate the graph. This class will maintain the invariants of the network
19 * graph. The southbound discovery modules will use this interface to update
20 * the network graph as they learn about the state of the network.
21 *
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080022 * Modification to the Network Map by this module will:
23 * 1. Writes to Cluster-wide DataStore.
24 * 2. Update ONOS instance In-memory Network Map.
25 * 3. Send-out Notification. (TBD)
26 * (XXX: To update other instances In-memory Network Map,
27 * notification should be triggered here.
28 * But if we want to aggregate notification to minimize notification,
29 * It might be better for the caller to trigger notification.)
30 *
Jonathan Hart062a2e82014-02-03 09:41:57 -080031 */
Jonathan Hartfa01c242014-02-11 10:03:03 -080032public class NetworkGraphDatastore {
33 private static final Logger log = LoggerFactory.getLogger(NetworkGraphDatastore.class);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080034
Pavlin Radoslavovca529072014-02-19 14:07:52 -080035 /**
36 * Add a switch to the database.
37 *
38 * @param sw the switch to add.
39 * @return true on success, otherwise false.
40 */
41 public boolean addSwitch(SwitchEvent sw) {
Jonathan Hart4b5bbb52014-02-06 10:09:31 -080042 log.debug("Adding switch {}", sw);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080043 ArrayList<WriteOp> groupOp = new ArrayList<>();
44
Jonathan Hart062a2e82014-02-03 09:41:57 -080045 RCSwitch rcSwitch = new RCSwitch(sw.getDpid());
46 rcSwitch.setStatus(RCSwitch.STATUS.ACTIVE);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080047
48 // XXX Is ForceCreating Switch on DB OK here?
49 // If ForceCreating, who ever is calling this method needs
50 // to assure that DPID is unique cluster-wide, etc.
51 groupOp.add(WriteOp.ForceCreate(rcSwitch));
52
Jonathan Hart69864df2014-02-13 10:44:12 -080053 for (PortEvent portEvent : sw.getPorts()) {
54 RCPort rcPort = new RCPort(sw.getDpid(), portEvent.getNumber());
55 rcPort.setStatus(RCPort.STATUS.ACTIVE);
Jonathan Hart69864df2014-02-13 10:44:12 -080056
57 groupOp.add(WriteOp.ForceCreate(rcPort));
58 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080059
Jonathan Hart369875b2014-02-13 10:00:31 -080060 boolean failed = RCObject.multiWrite(groupOp);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080061
Jonathan Hart369875b2014-02-13 10:00:31 -080062 if (failed) {
Jonathan Hart4b5bbb52014-02-06 10:09:31 -080063 log.error("Adding Switch {} and its ports failed.", sw.getDpid());
Jonathan Hart369875b2014-02-13 10:00:31 -080064 for (WriteOp op : groupOp) {
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080065 log.debug("Operation:{} for {} - Result:{}", op.getOp(), op.getObject(), op.getStatus() );
66
67 // If we changed the operation from ForceCreate to
68 // Conditional operation (Create/Update) then we should retry here.
69 }
70 }
Jonathan Hartdaea86f2014-02-19 15:28:42 -080071 return !failed;
Jonathan Hart062a2e82014-02-03 09:41:57 -080072 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080073
Pavlin Radoslavovca529072014-02-19 14:07:52 -080074 /**
75 * Update a switch as inactive in the database.
76 *
77 * @param sw the switch to update.
78 * @return true on success, otherwise false.
79 */
80 public boolean deactivateSwitch(SwitchEvent sw) {
Jonathan Hart4b5bbb52014-02-06 10:09:31 -080081 log.debug("Deactivating switch {}", sw);
Jonathan Hart062a2e82014-02-03 09:41:57 -080082 RCSwitch rcSwitch = new RCSwitch(sw.getDpid());
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080083
Jonathan Hartdaea86f2014-02-19 15:28:42 -080084 List<WriteOp> groupOp = new ArrayList<>();
85 rcSwitch.setStatus(RCSwitch.STATUS.INACTIVE);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080086
Jonathan Hartdaea86f2014-02-19 15:28:42 -080087 groupOp.add(WriteOp.ForceCreate(rcSwitch));
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080088
Jonathan Hartdaea86f2014-02-19 15:28:42 -080089 for (PortEvent portEvent : sw.getPorts()) {
90 RCPort rcPort = new RCPort(sw.getDpid(), (long)portEvent.getNumber());
91 rcPort.setStatus(RCPort.STATUS.INACTIVE);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080092
Jonathan Hartdaea86f2014-02-19 15:28:42 -080093 groupOp.add(WriteOp.ForceCreate(rcPort));
Jonathan Hart062a2e82014-02-03 09:41:57 -080094 }
Pavlin Radoslavovca529072014-02-19 14:07:52 -080095
Jonathan Hartdaea86f2014-02-19 15:28:42 -080096 boolean failed = RCObject.multiWrite(groupOp);
97
98 return !failed;
Jonathan Hart062a2e82014-02-03 09:41:57 -080099 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800100
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800101 /**
102 * Add a port to the database.
103 *
104 * @param port the port to add.
105 * @return true on success, otherwise false.
106 */
107 public boolean addPort(PortEvent port) {
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800108 log.debug("Adding port {}", port);
Jonathan Hart4c263272014-02-13 17:41:05 -0800109
110 RCPort rcPort = new RCPort(port.getDpid(), port.getNumber());
111 rcPort.setStatus(RCPort.STATUS.ACTIVE);
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800112 rcPort.forceCreate();
Jonathan Hart4c263272014-02-13 17:41:05 -0800113 // TODO add description into RCPort
114 //rcPort.setDescription(port.getDescription());
Jonathan Hart4c263272014-02-13 17:41:05 -0800115
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800116 return true;
Jonathan Hart062a2e82014-02-03 09:41:57 -0800117 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800118
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800119 /**
120 * Update a port as inactive in the database.
121 *
122 * @param port the port to update.
123 * @return true on success, otherwise false.
124 */
125 public boolean deactivatePort(PortEvent port) {
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800126 log.debug("Deactivating port {}", port);
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800127
Jonathan Hart4c263272014-02-13 17:41:05 -0800128 RCPort rcPort = new RCPort(port.getDpid(), port.getNumber());
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800129 rcPort.setStatus(STATUS.INACTIVE);
130
131 rcPort.forceCreate();
Jonathan Hart4c263272014-02-13 17:41:05 -0800132
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800133 return true;
Jonathan Hart062a2e82014-02-03 09:41:57 -0800134 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800135
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800136 /**
137 * Add a link to the database.
138 *
139 * @param link the link to add.
140 * @return true on success, otherwise false.
141 */
142 public boolean addLink(LinkEvent link) {
143 log.debug("Adding link {}", link);
Yuta HIGUCHI0a4bd192014-02-17 13:52:34 -0800144
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800145 RCLink rcLink = new RCLink(link.getSrc().getDpid(),
146 link.getSrc().getNumber(),
147 link.getDst().getDpid(),
148 link.getDst().getNumber());
Jonathan Hart369875b2014-02-13 10:00:31 -0800149
Yuta HIGUCHIef479672014-02-19 09:14:39 -0800150 // XXX This method is called only by discovery,
151 // which means what we are trying to write currently is the truth
152 // so we can force write here
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800153 //
154 // TODO: We need to check for errors
Yuta HIGUCHIef479672014-02-19 09:14:39 -0800155 rcLink.setStatus(RCLink.STATUS.ACTIVE);
156 rcLink.forceCreate();
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800157
158 return true; // Success
Jonathan Hart062a2e82014-02-03 09:41:57 -0800159 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800160
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800161 public boolean removeLink(LinkEvent linkEvent) {
162 log.debug("Removing link {}", linkEvent);
163
164 RCLink rcLink = new RCLink(linkEvent.getSrc().getDpid(), linkEvent.getSrc().getNumber(),
165 linkEvent.getDst().getDpid(), linkEvent.getDst().getNumber());
166 rcLink.forceDelete();
Jonathan Hart369875b2014-02-13 10:00:31 -0800167
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800168 return true;
Jonathan Hart062a2e82014-02-03 09:41:57 -0800169 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800170
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800171 /**
172 * Add a device to the database.
173 *
174 * @param device the device to add.
175 * @return true on success, otherwise false.
176 */
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800177 public boolean addDevice(DeviceEvent device) {
Jonathan Hart062a2e82014-02-03 09:41:57 -0800178 // TODO implement
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800179 return false; // Failure: not implemented yet
Jonathan Hart062a2e82014-02-03 09:41:57 -0800180 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800181
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800182 /**
183 * Remove a device from the database.
184 *
185 * @param device the device to remove.
186 * @return true on success, otherwise false.
187 */
188 public boolean removeDevice(DeviceEvent device) {
Jonathan Hart062a2e82014-02-03 09:41:57 -0800189 // TODO implement
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800190 return false; // Failure: not implemented yet
Jonathan Hart062a2e82014-02-03 09:41:57 -0800191 }
Jonathan Hart062a2e82014-02-03 09:41:57 -0800192}