blob: d2a9d31c1d3181f8c0b8c2d490fc4950d50e0be3 [file] [log] [blame]
Jonathan Hartdeda0ba2014-04-03 11:14:12 -07001package net.onrc.onos.core.registry;
Jonathan Hartbd766972013-02-22 15:13:03 -08002
3import java.util.ArrayList;
4import java.util.Collection;
Jonathan Hart1dbcce62014-06-04 15:21:45 -07005import java.util.Collections;
Jonathan Hartbd766972013-02-22 15:13:03 -08006import java.util.HashMap;
7import java.util.List;
8import java.util.Map;
Pavlin Radoslavov52163ed2014-03-19 11:39:34 -07009import java.util.concurrent.atomic.AtomicLong;
Jonathan Hartbd766972013-02-22 15:13:03 -080010
Pavlin Radoslavovc35229e2014-02-06 16:19:37 -080011import net.floodlightcontroller.core.IFloodlightProviderService;
Jonathan Hartbd766972013-02-22 15:13:03 -080012import net.floodlightcontroller.core.module.FloodlightModuleContext;
13import net.floodlightcontroller.core.module.FloodlightModuleException;
14import net.floodlightcontroller.core.module.IFloodlightModule;
15import net.floodlightcontroller.core.module.IFloodlightService;
16import net.floodlightcontroller.restserver.IRestApiService;
Jonathan Hartdeda0ba2014-04-03 11:14:12 -070017import net.onrc.onos.core.registry.web.RegistryWebRoutable;
Sho SHIMIZUfc932d52014-08-15 11:22:37 -070018import net.onrc.onos.core.util.IdBlock;
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -070019import net.onrc.onos.core.util.OnosInstanceId;
Jonathan Hartbd766972013-02-22 15:13:03 -080020
Yuta HIGUCHI498e1532014-08-20 21:30:28 -070021import org.apache.commons.lang3.NotImplementedException;
Jonathan Hartc78b8f62014-08-07 22:31:09 -070022import org.projectfloodlight.openflow.util.HexString;
Jonathan Hartbd766972013-02-22 15:13:03 -080023import org.slf4j.Logger;
24import org.slf4j.LoggerFactory;
25
Jonathan Hart7bf62172013-02-28 13:17:18 -080026/**
27 * Implementation of a registry that doesn't rely on any external registry
28 * service. This is designed to be used only in single-node setups (e.g. for
29 * development). All registry data is stored in local memory.
Jonathan Hart7bf62172013-02-28 13:17:18 -080030 */
Jonathan Hartbd766972013-02-22 15:13:03 -080031public class StandaloneRegistry implements IFloodlightModule,
Ray Milkey269ffb92014-04-03 14:43:30 -070032 IControllerRegistryService {
Ray Milkeyec838942014-04-09 11:28:43 -070033 private static final Logger log = LoggerFactory.getLogger(StandaloneRegistry.class);
Pavlin Radoslavov52163ed2014-03-19 11:39:34 -070034
Jonathan Hart12a26aa2014-06-04 14:33:09 -070035 private IRestApiService restApi;
Jonathan Hartbd766972013-02-22 15:13:03 -080036
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -070037 private OnosInstanceId onosInstanceId;
Jonathan Hart12a26aa2014-06-04 14:33:09 -070038 private Map<String, ControlChangeCallback> switchCallbacks;
Jonathan Hartbd766972013-02-22 15:13:03 -080039
Jonathan Hart1dbcce62014-06-04 15:21:45 -070040 private long blockTop;
41 private static final long BLOCK_SIZE = 0x1000000L;
42
Ray Milkey269ffb92014-04-03 14:43:30 -070043 //
44 // Unique ID generation state
45 //
46 private static AtomicLong nextUniqueId = new AtomicLong(0);
Jonathan Hartbd766972013-02-22 15:13:03 -080047
Ray Milkey269ffb92014-04-03 14:43:30 -070048 @Override
49 public void requestControl(long dpid, ControlChangeCallback cb)
50 throws RegistryException {
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -070051 if (onosInstanceId == null) {
Jonathan Hart12a26aa2014-06-04 14:33:09 -070052 throw new IllegalStateException(
Ray Milkey269ffb92014-04-03 14:43:30 -070053 "Must register a controller before calling requestControl");
54 }
Jonathan Hartbd766972013-02-22 15:13:03 -080055
Ray Milkey269ffb92014-04-03 14:43:30 -070056 switchCallbacks.put(HexString.toHexString(dpid), cb);
Pavlin Radoslavovf1377ce2014-02-05 17:37:24 -080057
Ray Milkey269ffb92014-04-03 14:43:30 -070058 log.debug("Control granted for {}", HexString.toHexString(dpid));
Jonathan Hartbd766972013-02-22 15:13:03 -080059
Jonathan Hart12a26aa2014-06-04 14:33:09 -070060 // Immediately grant request for control
Ray Milkey269ffb92014-04-03 14:43:30 -070061 if (cb != null) {
62 cb.controlChanged(dpid, true);
63 }
64 }
Jonathan Hartbd766972013-02-22 15:13:03 -080065
Ray Milkey269ffb92014-04-03 14:43:30 -070066 @Override
67 public void releaseControl(long dpid) {
68 ControlChangeCallback cb = switchCallbacks.remove(HexString.toHexString(dpid));
Jonathan Hartbd766972013-02-22 15:13:03 -080069
Ray Milkey269ffb92014-04-03 14:43:30 -070070 log.debug("Control released for {}", HexString.toHexString(dpid));
Jonathan Hartbd766972013-02-22 15:13:03 -080071
Ray Milkey269ffb92014-04-03 14:43:30 -070072 if (cb != null) {
73 cb.controlChanged(dpid, false);
74 }
75 }
Jonathan Hartbd766972013-02-22 15:13:03 -080076
Ray Milkey269ffb92014-04-03 14:43:30 -070077 @Override
78 public boolean hasControl(long dpid) {
79 return switchCallbacks.containsKey(HexString.toHexString(dpid));
80 }
Jonathan Hartbd766972013-02-22 15:13:03 -080081
Ray Milkey269ffb92014-04-03 14:43:30 -070082 @Override
83 public boolean isClusterLeader() {
84 return true;
85 }
Pavlin Radoslavov52163ed2014-03-19 11:39:34 -070086
Ray Milkey269ffb92014-04-03 14:43:30 -070087 @Override
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -070088 public OnosInstanceId getOnosInstanceId() {
89 return onosInstanceId;
Ray Milkey269ffb92014-04-03 14:43:30 -070090 }
Jonathan Hartbd766972013-02-22 15:13:03 -080091
Ray Milkey269ffb92014-04-03 14:43:30 -070092 @Override
93 public void registerController(String controllerId)
94 throws RegistryException {
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -070095 if (onosInstanceId != null) {
Ray Milkey269ffb92014-04-03 14:43:30 -070096 throw new RegistryException(
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -070097 "Controller already registered with id " + onosInstanceId);
Ray Milkey269ffb92014-04-03 14:43:30 -070098 }
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -070099 onosInstanceId = new OnosInstanceId(controllerId);
Ray Milkey269ffb92014-04-03 14:43:30 -0700100 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800101
Ray Milkey269ffb92014-04-03 14:43:30 -0700102 @Override
103 public Collection<String> getAllControllers() throws RegistryException {
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -0700104 if (onosInstanceId == null) {
105 return new ArrayList<String>();
106 }
107 return Collections.singletonList(onosInstanceId.toString());
Ray Milkey269ffb92014-04-03 14:43:30 -0700108 }
109
110 @Override
111 public String getControllerForSwitch(long dpid) throws RegistryException {
Jonathan Hart1dbcce62014-06-04 15:21:45 -0700112 return (switchCallbacks.get(HexString.toHexString(dpid)) == null)
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -0700113 ? null : onosInstanceId.toString();
Ray Milkey269ffb92014-04-03 14:43:30 -0700114 }
115
116 @Override
117 public Map<String, List<ControllerRegistryEntry>> getAllSwitches() {
118 Map<String, List<ControllerRegistryEntry>> switches =
119 new HashMap<String, List<ControllerRegistryEntry>>();
120
121 for (String strSwitch : switchCallbacks.keySet()) {
122 log.debug("Switch _{}", strSwitch);
Jonathan Hart1dbcce62014-06-04 15:21:45 -0700123 List<ControllerRegistryEntry> list =
124 new ArrayList<ControllerRegistryEntry>();
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -0700125 list.add(new ControllerRegistryEntry(onosInstanceId.toString(), 0));
Ray Milkey269ffb92014-04-03 14:43:30 -0700126
127 switches.put(strSwitch, list);
128 }
129
130 return switches;
131 }
132
133 @Override
134 public Collection<Long> getSwitchesControlledByController(
135 String controllerId) {
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700136 throw new NotImplementedException("Not yet implemented");
Ray Milkey269ffb92014-04-03 14:43:30 -0700137 }
138
Ray Milkey269ffb92014-04-03 14:43:30 -0700139 /**
140 * Returns a block of IDs which are unique and unused.
Jonathan Hart1dbcce62014-06-04 15:21:45 -0700141 * Range of IDs is fixed size and is assigned incrementally as this method
142 * called.
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700143 *
144 * @return an IdBlock containing a set of unique IDs
Ray Milkey269ffb92014-04-03 14:43:30 -0700145 */
146 @Override
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700147 public IdBlock allocateUniqueIdBlock() {
148 synchronized (this) {
149 long blockHead = blockTop;
150 long blockTail = blockTop + BLOCK_SIZE;
Ray Milkey269ffb92014-04-03 14:43:30 -0700151
Sho SHIMIZU9257b0c2014-08-13 15:00:10 -0700152 IdBlock block = new IdBlock(blockHead, BLOCK_SIZE);
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700153 blockTop = blockTail;
Ray Milkey269ffb92014-04-03 14:43:30 -0700154
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700155 return block;
156 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700157 }
158
159 /**
160 * Get a globally unique ID.
161 *
162 * @return a globally unique ID.
163 */
164 @Override
165 public long getNextUniqueId() {
166 return nextUniqueId.incrementAndGet();
167 }
168
169 @Override
170 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
171 Collection<Class<? extends IFloodlightService>> l =
Jonathan Hartbd766972013-02-22 15:13:03 -0800172 new ArrayList<Class<? extends IFloodlightService>>();
Ray Milkey269ffb92014-04-03 14:43:30 -0700173 l.add(IControllerRegistryService.class);
174 return l;
175 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800176
Ray Milkey269ffb92014-04-03 14:43:30 -0700177 @Override
178 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
179 Map<Class<? extends IFloodlightService>, IFloodlightService> m =
180 new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
181 m.put(IControllerRegistryService.class, this);
182 return m;
183 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800184
Ray Milkey269ffb92014-04-03 14:43:30 -0700185 @Override
186 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
187 Collection<Class<? extends IFloodlightService>> l =
188 new ArrayList<Class<? extends IFloodlightService>>();
189 l.add(IFloodlightProviderService.class);
190 l.add(IRestApiService.class);
191 return l;
192 }
193
194 @Override
195 public void init(FloodlightModuleContext context)
196 throws FloodlightModuleException {
197 restApi = context.getServiceImpl(IRestApiService.class);
198
199 switchCallbacks = new HashMap<String, ControlChangeCallback>();
200 }
201
202 @Override
203 public void startUp(FloodlightModuleContext context) {
204 restApi.addRestletRoutable(new RegistryWebRoutable());
205 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800206
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800207 @Override
208 public IdBlock allocateUniqueIdBlock(long range) {
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700209 throw new UnsupportedOperationException("Not supported yet");
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800210 }
211
Jonathan Hartbd766972013-02-22 15:13:03 -0800212}