blob: 488915f30399a2c1181158bb7e709abfb70f4818 [file] [log] [blame]
Jonathan Hart472062d2014-04-03 10:56:48 -07001package net.onrc.onos.core.topology;
Jonathan Hart062a2e82014-02-03 09:41:57 -08002
TeruUd1c5b652014-03-24 13:58:46 -07003import java.net.InetAddress;
Jonathan Hart062a2e82014-02-03 09:41:57 -08004import java.util.ArrayList;
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08005import java.util.Collection;
Jonathan Harta99ec672014-04-03 11:30:34 -07006import java.util.List;
Jonathan Hart062a2e82014-02-03 09:41:57 -08007
Jonathan Hart6df90172014-04-03 10:13:11 -07008import net.onrc.onos.core.datastore.DataStoreClient;
9import net.onrc.onos.core.datastore.IKVClient;
10import net.onrc.onos.core.datastore.topology.KVDevice;
11import net.onrc.onos.core.datastore.topology.KVLink;
12import net.onrc.onos.core.datastore.topology.KVPort;
Jonathan Hart6df90172014-04-03 10:13:11 -070013import net.onrc.onos.core.datastore.topology.KVPort.STATUS;
Jonathan Harta99ec672014-04-03 11:30:34 -070014import net.onrc.onos.core.datastore.topology.KVSwitch;
Jonathan Hart6df90172014-04-03 10:13:11 -070015import net.onrc.onos.core.datastore.utils.KVObject;
16import net.onrc.onos.core.datastore.utils.KVObject.WriteOp;
Jonathan Hart472062d2014-04-03 10:56:48 -070017import net.onrc.onos.core.topology.PortEvent.SwitchPort;
Jonathan Hart062a2e82014-02-03 09:41:57 -080018
19import org.slf4j.Logger;
20import org.slf4j.LoggerFactory;
21
TeruUd1c5b652014-03-24 13:58:46 -070022import com.google.common.net.InetAddresses;
23
Jonathan Hart062a2e82014-02-03 09:41:57 -080024/**
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080025 * The southbound interface to the network graph which allows clients to
Jonathan Hart062a2e82014-02-03 09:41:57 -080026 * mutate the graph. This class will maintain the invariants of the network
27 * graph. The southbound discovery modules will use this interface to update
28 * the network graph as they learn about the state of the network.
Ray Milkey269ffb92014-04-03 14:43:30 -070029 * <p/>
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080030 * Modification to the Network Map by this module will:
31 * 1. Writes to Cluster-wide DataStore.
32 * 2. Update ONOS instance In-memory Network Map.
33 * 3. Send-out Notification. (TBD)
Ray Milkey269ffb92014-04-03 14:43:30 -070034 * (XXX: To update other instances In-memory Network Map,
35 * notification should be triggered here.
36 * But if we want to aggregate notification to minimize notification,
37 * It might be better for the caller to trigger notification.)
Jonathan Hart062a2e82014-02-03 09:41:57 -080038 */
Jonathan Hartfa01c242014-02-11 10:03:03 -080039public class NetworkGraphDatastore {
Ray Milkey269ffb92014-04-03 14:43:30 -070040 private static final Logger log = LoggerFactory.getLogger(NetworkGraphDatastore.class);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080041
Ray Milkey269ffb92014-04-03 14:43:30 -070042 /**
43 * Add a switch to the database.
44 *
45 * @param sw the switch to add.
46 * @param portEvents the corresponding switch ports to add.
47 * @return true on success, otherwise false.
48 */
49 public boolean addSwitch(SwitchEvent sw,
50 Collection<PortEvent> portEvents) {
51 log.debug("Adding switch {}", sw);
52 ArrayList<WriteOp> groupOp = new ArrayList<>();
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080053
Ray Milkey269ffb92014-04-03 14:43:30 -070054 KVSwitch rcSwitch = new KVSwitch(sw.getDpid());
55 rcSwitch.setStatus(KVSwitch.STATUS.ACTIVE);
Yuta HIGUCHI66ca1bf2014-03-12 18:34:09 -070056
Ray Milkey269ffb92014-04-03 14:43:30 -070057 IKVClient client = DataStoreClient.getClient();
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080058
Ray Milkey269ffb92014-04-03 14:43:30 -070059 // XXX Is ForceCreating Switch on DB OK here?
60 // If ForceCreating, who ever is calling this method needs
61 // to assure that DPID is unique cluster-wide, etc.
62 groupOp.add(rcSwitch.forceCreateOp(client));
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080063
Ray Milkey269ffb92014-04-03 14:43:30 -070064 for (PortEvent portEvent : portEvents) {
65 KVPort rcPort = new KVPort(sw.getDpid(), portEvent.getNumber());
66 rcPort.setStatus(KVPort.STATUS.ACTIVE);
Jonathan Hart69864df2014-02-13 10:44:12 -080067
Ray Milkey269ffb92014-04-03 14:43:30 -070068 groupOp.add(rcPort.forceCreateOp(client));
69 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080070
Ray Milkey269ffb92014-04-03 14:43:30 -070071 boolean failed = KVObject.multiWrite(groupOp);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080072
Ray Milkey269ffb92014-04-03 14:43:30 -070073 if (failed) {
74 log.error("Adding Switch {} and its ports failed.", sw.getDpid());
75 for (WriteOp op : groupOp) {
76 log.debug("Operation:{} for {} - Result:{}", op.getOp(), op.getObject(), op.getStatus());
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080077
Ray Milkey269ffb92014-04-03 14:43:30 -070078 // If we changed the operation from ForceCreate to
79 // Conditional operation (Create/Update) then we should retry here.
80 }
81 }
82 return !failed;
83 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080084
Ray Milkey269ffb92014-04-03 14:43:30 -070085 /**
86 * Update a switch as inactive in the database.
87 *
88 * @param sw the switch to update.
89 * @param portEvents the corresponding switch ports to update.
90 * @return true on success, otherwise false.
91 */
92 public boolean deactivateSwitch(SwitchEvent sw,
93 Collection<PortEvent> portEvents) {
94 log.debug("Deactivating switch {}", sw);
95 KVSwitch rcSwitch = new KVSwitch(sw.getDpid());
Yuta HIGUCHI66ca1bf2014-03-12 18:34:09 -070096
Ray Milkey269ffb92014-04-03 14:43:30 -070097 IKVClient client = DataStoreClient.getClient();
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -080098
Ray Milkey269ffb92014-04-03 14:43:30 -070099 List<WriteOp> groupOp = new ArrayList<>();
100 rcSwitch.setStatus(KVSwitch.STATUS.INACTIVE);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800101
Ray Milkey269ffb92014-04-03 14:43:30 -0700102 groupOp.add(rcSwitch.forceCreateOp(client));
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800103
Ray Milkey269ffb92014-04-03 14:43:30 -0700104 for (PortEvent portEvent : portEvents) {
105 KVPort rcPort = new KVPort(sw.getDpid(), portEvent.getNumber());
106 rcPort.setStatus(KVPort.STATUS.INACTIVE);
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800107
Ray Milkey269ffb92014-04-03 14:43:30 -0700108 groupOp.add(rcPort.forceCreateOp(client));
109 }
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800110
Ray Milkey269ffb92014-04-03 14:43:30 -0700111 boolean failed = KVObject.multiWrite(groupOp);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800112
Ray Milkey269ffb92014-04-03 14:43:30 -0700113 return !failed;
114 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800115
Ray Milkey269ffb92014-04-03 14:43:30 -0700116 /**
117 * Add a port to the database.
118 *
119 * @param port the port to add.
120 * @return true on success, otherwise false.
121 */
122 public boolean addPort(PortEvent port) {
123 log.debug("Adding port {}", port);
Jonathan Hart4c263272014-02-13 17:41:05 -0800124
Ray Milkey269ffb92014-04-03 14:43:30 -0700125 KVPort rcPort = new KVPort(port.getDpid(), port.getNumber());
126 rcPort.setStatus(KVPort.STATUS.ACTIVE);
127 rcPort.forceCreate();
128 // TODO add description into KVPort
129 //rcPort.setDescription(port.getDescription());
Jonathan Hart4c263272014-02-13 17:41:05 -0800130
Ray Milkey269ffb92014-04-03 14:43:30 -0700131 return true;
132 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800133
Ray Milkey269ffb92014-04-03 14:43:30 -0700134 /**
135 * Update a port as inactive in the database.
136 *
137 * @param port the port to update.
138 * @return true on success, otherwise false.
139 */
140 public boolean deactivatePort(PortEvent port) {
141 log.debug("Deactivating port {}", port);
Yuta HIGUCHI5d2d8d42014-02-20 22:22:53 -0800142
Ray Milkey269ffb92014-04-03 14:43:30 -0700143 KVPort rcPort = new KVPort(port.getDpid(), port.getNumber());
144 rcPort.setStatus(STATUS.INACTIVE);
Yuta HIGUCHI5d2d8d42014-02-20 22:22:53 -0800145
Ray Milkey269ffb92014-04-03 14:43:30 -0700146 rcPort.forceCreate();
Jonathan Hart4c263272014-02-13 17:41:05 -0800147
Ray Milkey269ffb92014-04-03 14:43:30 -0700148 return true;
149 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800150
Ray Milkey269ffb92014-04-03 14:43:30 -0700151 /**
152 * Add a link to the database.
153 *
154 * @param link the link to add.
155 * @return true on success, otherwise false.
156 */
157 public boolean addLink(LinkEvent link) {
158 log.debug("Adding link {}", link);
Yuta HIGUCHI0a4bd192014-02-17 13:52:34 -0800159
Ray Milkey269ffb92014-04-03 14:43:30 -0700160 KVLink rcLink = new KVLink(link.getSrc().getDpid(),
161 link.getSrc().getNumber(),
162 link.getDst().getDpid(),
163 link.getDst().getNumber());
Jonathan Hart369875b2014-02-13 10:00:31 -0800164
Ray Milkey269ffb92014-04-03 14:43:30 -0700165 // XXX This method is called only by discovery,
166 // which means what we are trying to write currently is the truth
167 // so we can force write here
168 //
169 // TODO: We need to check for errors
170 rcLink.setStatus(KVLink.STATUS.ACTIVE);
171 rcLink.forceCreate();
Pavlin Radoslavovca529072014-02-19 14:07:52 -0800172
Ray Milkey269ffb92014-04-03 14:43:30 -0700173 return true; // Success
174 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800175
Ray Milkey269ffb92014-04-03 14:43:30 -0700176 public boolean removeLink(LinkEvent linkEvent) {
177 log.debug("Removing link {}", linkEvent);
Yuta HIGUCHI5d2d8d42014-02-20 22:22:53 -0800178
Ray Milkey269ffb92014-04-03 14:43:30 -0700179 KVLink rcLink = new KVLink(linkEvent.getSrc().getDpid(), linkEvent.getSrc().getNumber(),
180 linkEvent.getDst().getDpid(), linkEvent.getDst().getNumber());
181 rcLink.forceDelete();
Jonathan Hart369875b2014-02-13 10:00:31 -0800182
Ray Milkey269ffb92014-04-03 14:43:30 -0700183 return true;
184 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800185
Ray Milkey269ffb92014-04-03 14:43:30 -0700186 /**
187 * Add a device to the database.
188 *
189 * @param device the device to add.
190 * @return true on success, otherwise false.
191 */
192 public boolean addDevice(DeviceEvent device) {
193 log.debug("Adding device into DB. mac {}", device.getMac());
TeruUd1c5b652014-03-24 13:58:46 -0700194
Ray Milkey269ffb92014-04-03 14:43:30 -0700195 KVDevice rcDevice = new KVDevice(device.getMac().toBytes());
196 rcDevice.setLastSeenTime(device.getLastSeenTime());
TeruUd1c5b652014-03-24 13:58:46 -0700197
Ray Milkey269ffb92014-04-03 14:43:30 -0700198 for (SwitchPort sp : device.getAttachmentPoints()) {
199 byte[] portId = KVPort.getPortID(sp.getDpid(), sp.getNumber());
200 rcDevice.addPortId(portId);
201 }
Yuta HIGUCHIb4335ad2014-02-05 09:56:07 -0800202
Ray Milkey269ffb92014-04-03 14:43:30 -0700203 for (InetAddress addr : device.getIpAddresses()) {
204 //It assume only one ip on a device now.
205 rcDevice.setIp(InetAddresses.coerceToInteger(addr));
206 }
207
208 rcDevice.forceCreate();
209
210 return true;
211 }
212
213 /**
214 * Remove a device from the database.
215 *
216 * @param device the device to remove.
217 * @return true on success, otherwise false.
218 */
219 public boolean removeDevice(DeviceEvent device) {
220 log.debug("Removing device into DB. mac {}", device.getMac());
221
222 KVDevice rcDevice = new KVDevice(device.getMac().toBytes());
223 rcDevice.forceDelete();
224
225 return true;
226 }
Jonathan Hart062a2e82014-02-03 09:41:57 -0800227}