blob: dca4eb014b6b3d2ff15da92f5a96e1a6a492fc6e [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;
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08005import java.util.Collection;
Jonathan Hart062a2e82014-02-03 09:41:57 -08006
7import net.onrc.onos.datastore.RCObject;
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -08008import net.onrc.onos.datastore.RCObject.WriteOp;
Jonathan Hart369875b2014-02-13 10:00:31 -08009import net.onrc.onos.datastore.topology.RCLink;
Jonathan Hart69864df2014-02-13 10:44:12 -080010import net.onrc.onos.datastore.topology.RCPort;
Jonathan Hartdaea86f2014-02-19 15:28:42 -080011import net.onrc.onos.datastore.topology.RCPort.STATUS;
Jonathan Hart062a2e82014-02-03 09:41:57 -080012import net.onrc.onos.datastore.topology.RCSwitch;
13
14import org.slf4j.Logger;
15import org.slf4j.LoggerFactory;
16
Jonathan Hart062a2e82014-02-03 09:41:57 -080017/**
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080018 * The southbound interface to the network graph which allows clients to
Jonathan Hart062a2e82014-02-03 09:41:57 -080019 * mutate the graph. This class will maintain the invariants of the network
20 * graph. The southbound discovery modules will use this interface to update
21 * the network graph as they learn about the state of the network.
22 *
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080023 * Modification to the Network Map by this module will:
24 * 1. Writes to Cluster-wide DataStore.
25 * 2. Update ONOS instance In-memory Network Map.
26 * 3. Send-out Notification. (TBD)
27 * (XXX: To update other instances In-memory Network Map,
28 * notification should be triggered here.
29 * But if we want to aggregate notification to minimize notification,
30 * It might be better for the caller to trigger notification.)
31 *
Jonathan Hart062a2e82014-02-03 09:41:57 -080032 */
Jonathan Hartfa01c242014-02-11 10:03:03 -080033public class NetworkGraphDatastore {
34 private static final Logger log = LoggerFactory.getLogger(NetworkGraphDatastore.class);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080035
Pavlin Radoslavovca529072014-02-19 14:07:52 -080036 /**
37 * Add a switch to the database.
38 *
39 * @param sw the switch to add.
Pavlin Radoslavov018d5332014-02-19 23:08:35 -080040 * @param portEvents the corresponding switch ports to add.
Pavlin Radoslavovca529072014-02-19 14:07:52 -080041 * @return true on success, otherwise false.
42 */
Pavlin Radoslavov018d5332014-02-19 23:08:35 -080043 public boolean addSwitch(SwitchEvent sw,
44 Collection<PortEvent> portEvents) {
Jonathan Hart4b5bbb52014-02-06 10:09:31 -080045 log.debug("Adding switch {}", sw);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080046 ArrayList<WriteOp> groupOp = new ArrayList<>();
47
Jonathan Hart062a2e82014-02-03 09:41:57 -080048 RCSwitch rcSwitch = new RCSwitch(sw.getDpid());
49 rcSwitch.setStatus(RCSwitch.STATUS.ACTIVE);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080050
51 // XXX Is ForceCreating Switch on DB OK here?
52 // If ForceCreating, who ever is calling this method needs
53 // to assure that DPID is unique cluster-wide, etc.
54 groupOp.add(WriteOp.ForceCreate(rcSwitch));
55
Pavlin Radoslavov018d5332014-02-19 23:08:35 -080056 for (PortEvent portEvent : portEvents) {
Jonathan Hart69864df2014-02-13 10:44:12 -080057 RCPort rcPort = new RCPort(sw.getDpid(), portEvent.getNumber());
58 rcPort.setStatus(RCPort.STATUS.ACTIVE);
Jonathan Hart69864df2014-02-13 10:44:12 -080059
60 groupOp.add(WriteOp.ForceCreate(rcPort));
61 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080062
Jonathan Hart369875b2014-02-13 10:00:31 -080063 boolean failed = RCObject.multiWrite(groupOp);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080064
Jonathan Hart369875b2014-02-13 10:00:31 -080065 if (failed) {
Jonathan Hart4b5bbb52014-02-06 10:09:31 -080066 log.error("Adding Switch {} and its ports failed.", sw.getDpid());
Jonathan Hart369875b2014-02-13 10:00:31 -080067 for (WriteOp op : groupOp) {
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080068 log.debug("Operation:{} for {} - Result:{}", op.getOp(), op.getObject(), op.getStatus() );
69
70 // If we changed the operation from ForceCreate to
71 // Conditional operation (Create/Update) then we should retry here.
72 }
73 }
Jonathan Hartdaea86f2014-02-19 15:28:42 -080074 return !failed;
Jonathan Hart062a2e82014-02-03 09:41:57 -080075 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080076
Pavlin Radoslavovca529072014-02-19 14:07:52 -080077 /**
78 * Update a switch as inactive in the database.
79 *
80 * @param sw the switch to update.
Pavlin Radoslavov018d5332014-02-19 23:08:35 -080081 * @param portEvents the corresponding switch ports to update.
Pavlin Radoslavovca529072014-02-19 14:07:52 -080082 * @return true on success, otherwise false.
83 */
Pavlin Radoslavov018d5332014-02-19 23:08:35 -080084 public boolean deactivateSwitch(SwitchEvent sw,
85 Collection<PortEvent> portEvents) {
Jonathan Hart4b5bbb52014-02-06 10:09:31 -080086 log.debug("Deactivating switch {}", sw);
Jonathan Hart062a2e82014-02-03 09:41:57 -080087 RCSwitch rcSwitch = new RCSwitch(sw.getDpid());
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080088
Jonathan Hartdaea86f2014-02-19 15:28:42 -080089 List<WriteOp> groupOp = new ArrayList<>();
90 rcSwitch.setStatus(RCSwitch.STATUS.INACTIVE);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080091
Jonathan Hartdaea86f2014-02-19 15:28:42 -080092 groupOp.add(WriteOp.ForceCreate(rcSwitch));
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080093
Pavlin Radoslavov018d5332014-02-19 23:08:35 -080094 for (PortEvent portEvent : portEvents) {
Jonathan Hartdaea86f2014-02-19 15:28:42 -080095 RCPort rcPort = new RCPort(sw.getDpid(), (long)portEvent.getNumber());
96 rcPort.setStatus(RCPort.STATUS.INACTIVE);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080097
Jonathan Hartdaea86f2014-02-19 15:28:42 -080098 groupOp.add(WriteOp.ForceCreate(rcPort));
Jonathan Hart062a2e82014-02-03 09:41:57 -080099 }
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800100
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800101 boolean failed = RCObject.multiWrite(groupOp);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800102
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800103 return !failed;
Jonathan Hart062a2e82014-02-03 09:41:57 -0800104 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800105
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800106 /**
107 * Add a port to the database.
108 *
109 * @param port the port to add.
110 * @return true on success, otherwise false.
111 */
112 public boolean addPort(PortEvent port) {
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800113 log.debug("Adding port {}", port);
Jonathan Hart4c263272014-02-13 17:41:05 -0800114
115 RCPort rcPort = new RCPort(port.getDpid(), port.getNumber());
116 rcPort.setStatus(RCPort.STATUS.ACTIVE);
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800117 rcPort.forceCreate();
Jonathan Hart4c263272014-02-13 17:41:05 -0800118 // TODO add description into RCPort
119 //rcPort.setDescription(port.getDescription());
Jonathan Hart4c263272014-02-13 17:41:05 -0800120
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800121 return true;
Jonathan Hart062a2e82014-02-03 09:41:57 -0800122 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800123
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800124 /**
125 * Update a port as inactive in the database.
126 *
127 * @param port the port to update.
128 * @return true on success, otherwise false.
129 */
130 public boolean deactivatePort(PortEvent port) {
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800131 log.debug("Deactivating port {}", port);
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800132
Jonathan Hart4c263272014-02-13 17:41:05 -0800133 RCPort rcPort = new RCPort(port.getDpid(), port.getNumber());
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800134 rcPort.setStatus(STATUS.INACTIVE);
135
136 rcPort.forceCreate();
Jonathan Hart4c263272014-02-13 17:41:05 -0800137
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800138 return true;
Jonathan Hart062a2e82014-02-03 09:41:57 -0800139 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800140
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800141 /**
142 * Add a link to the database.
143 *
144 * @param link the link to add.
145 * @return true on success, otherwise false.
146 */
147 public boolean addLink(LinkEvent link) {
148 log.debug("Adding link {}", link);
Yuta HIGUCHI0a4bd192014-02-17 13:52:34 -0800149
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800150 RCLink rcLink = new RCLink(link.getSrc().getDpid(),
151 link.getSrc().getNumber(),
152 link.getDst().getDpid(),
153 link.getDst().getNumber());
Jonathan Hart369875b2014-02-13 10:00:31 -0800154
Yuta HIGUCHIef479672014-02-19 09:14:39 -0800155 // XXX This method is called only by discovery,
156 // which means what we are trying to write currently is the truth
157 // so we can force write here
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800158 //
159 // TODO: We need to check for errors
Yuta HIGUCHIef479672014-02-19 09:14:39 -0800160 rcLink.setStatus(RCLink.STATUS.ACTIVE);
161 rcLink.forceCreate();
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800162
163 return true; // Success
Jonathan Hart062a2e82014-02-03 09:41:57 -0800164 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800165
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800166 public boolean removeLink(LinkEvent linkEvent) {
167 log.debug("Removing link {}", linkEvent);
168
169 RCLink rcLink = new RCLink(linkEvent.getSrc().getDpid(), linkEvent.getSrc().getNumber(),
170 linkEvent.getDst().getDpid(), linkEvent.getDst().getNumber());
171 rcLink.forceDelete();
Jonathan Hart369875b2014-02-13 10:00:31 -0800172
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800173 return true;
Jonathan Hart062a2e82014-02-03 09:41:57 -0800174 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800175
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800176 /**
177 * Add a device to the database.
178 *
179 * @param device the device to add.
180 * @return true on success, otherwise false.
181 */
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800182 public boolean addDevice(DeviceEvent device) {
Jonathan Hart062a2e82014-02-03 09:41:57 -0800183 // TODO implement
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800184 return false; // Failure: not implemented yet
Jonathan Hart062a2e82014-02-03 09:41:57 -0800185 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800186
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800187 /**
188 * Remove a device from the database.
189 *
190 * @param device the device to remove.
191 * @return true on success, otherwise false.
192 */
193 public boolean removeDevice(DeviceEvent device) {
Jonathan Hart062a2e82014-02-03 09:41:57 -0800194 // TODO implement
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800195 return false; // Failure: not implemented yet
Jonathan Hart062a2e82014-02-03 09:41:57 -0800196 }
Jonathan Hart062a2e82014-02-03 09:41:57 -0800197}