blob: bf5612c188376ce17846a12b4467e1c94d17d62b [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;
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -070018import net.onrc.onos.core.util.OnosInstanceId;
Jonathan Hartbd766972013-02-22 15:13:03 -080019
Jonathan Hart12a26aa2014-06-04 14:33:09 -070020import org.apache.commons.lang.NotImplementedException;
Jonathan Hartc78b8f62014-08-07 22:31:09 -070021import org.projectfloodlight.openflow.util.HexString;
Jonathan Hartbd766972013-02-22 15:13:03 -080022import org.slf4j.Logger;
23import org.slf4j.LoggerFactory;
24
Jonathan Hart7bf62172013-02-28 13:17:18 -080025/**
26 * Implementation of a registry that doesn't rely on any external registry
27 * service. This is designed to be used only in single-node setups (e.g. for
28 * development). All registry data is stored in local memory.
Jonathan Hart7bf62172013-02-28 13:17:18 -080029 */
Jonathan Hartbd766972013-02-22 15:13:03 -080030public class StandaloneRegistry implements IFloodlightModule,
Ray Milkey269ffb92014-04-03 14:43:30 -070031 IControllerRegistryService {
Ray Milkeyec838942014-04-09 11:28:43 -070032 private static final Logger log = LoggerFactory.getLogger(StandaloneRegistry.class);
Pavlin Radoslavov52163ed2014-03-19 11:39:34 -070033
Jonathan Hart12a26aa2014-06-04 14:33:09 -070034 private IRestApiService restApi;
Jonathan Hartbd766972013-02-22 15:13:03 -080035
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -070036 private OnosInstanceId onosInstanceId;
Jonathan Hart12a26aa2014-06-04 14:33:09 -070037 private Map<String, ControlChangeCallback> switchCallbacks;
Jonathan Hartbd766972013-02-22 15:13:03 -080038
Jonathan Hart1dbcce62014-06-04 15:21:45 -070039 private long blockTop;
40 private static final long BLOCK_SIZE = 0x1000000L;
41
Ray Milkey269ffb92014-04-03 14:43:30 -070042 //
43 // Unique ID generation state
44 //
45 private static AtomicLong nextUniqueId = new AtomicLong(0);
Jonathan Hartbd766972013-02-22 15:13:03 -080046
Ray Milkey269ffb92014-04-03 14:43:30 -070047 @Override
48 public void requestControl(long dpid, ControlChangeCallback cb)
49 throws RegistryException {
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -070050 if (onosInstanceId == null) {
Jonathan Hart12a26aa2014-06-04 14:33:09 -070051 throw new IllegalStateException(
Ray Milkey269ffb92014-04-03 14:43:30 -070052 "Must register a controller before calling requestControl");
53 }
Jonathan Hartbd766972013-02-22 15:13:03 -080054
Ray Milkey269ffb92014-04-03 14:43:30 -070055 switchCallbacks.put(HexString.toHexString(dpid), cb);
Pavlin Radoslavovf1377ce2014-02-05 17:37:24 -080056
Ray Milkey269ffb92014-04-03 14:43:30 -070057 log.debug("Control granted for {}", HexString.toHexString(dpid));
Jonathan Hartbd766972013-02-22 15:13:03 -080058
Jonathan Hart12a26aa2014-06-04 14:33:09 -070059 // Immediately grant request for control
Ray Milkey269ffb92014-04-03 14:43:30 -070060 if (cb != null) {
61 cb.controlChanged(dpid, true);
62 }
63 }
Jonathan Hartbd766972013-02-22 15:13:03 -080064
Ray Milkey269ffb92014-04-03 14:43:30 -070065 @Override
66 public void releaseControl(long dpid) {
67 ControlChangeCallback cb = switchCallbacks.remove(HexString.toHexString(dpid));
Jonathan Hartbd766972013-02-22 15:13:03 -080068
Ray Milkey269ffb92014-04-03 14:43:30 -070069 log.debug("Control released for {}", HexString.toHexString(dpid));
Jonathan Hartbd766972013-02-22 15:13:03 -080070
Ray Milkey269ffb92014-04-03 14:43:30 -070071 if (cb != null) {
72 cb.controlChanged(dpid, false);
73 }
74 }
Jonathan Hartbd766972013-02-22 15:13:03 -080075
Ray Milkey269ffb92014-04-03 14:43:30 -070076 @Override
77 public boolean hasControl(long dpid) {
78 return switchCallbacks.containsKey(HexString.toHexString(dpid));
79 }
Jonathan Hartbd766972013-02-22 15:13:03 -080080
Ray Milkey269ffb92014-04-03 14:43:30 -070081 @Override
82 public boolean isClusterLeader() {
83 return true;
84 }
Pavlin Radoslavov52163ed2014-03-19 11:39:34 -070085
Ray Milkey269ffb92014-04-03 14:43:30 -070086 @Override
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -070087 public OnosInstanceId getOnosInstanceId() {
88 return onosInstanceId;
Ray Milkey269ffb92014-04-03 14:43:30 -070089 }
Jonathan Hartbd766972013-02-22 15:13:03 -080090
Ray Milkey269ffb92014-04-03 14:43:30 -070091 @Override
92 public void registerController(String controllerId)
93 throws RegistryException {
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -070094 if (onosInstanceId != null) {
Ray Milkey269ffb92014-04-03 14:43:30 -070095 throw new RegistryException(
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -070096 "Controller already registered with id " + onosInstanceId);
Ray Milkey269ffb92014-04-03 14:43:30 -070097 }
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -070098 onosInstanceId = new OnosInstanceId(controllerId);
Ray Milkey269ffb92014-04-03 14:43:30 -070099 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800100
Ray Milkey269ffb92014-04-03 14:43:30 -0700101 @Override
102 public Collection<String> getAllControllers() throws RegistryException {
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -0700103 if (onosInstanceId == null) {
104 return new ArrayList<String>();
105 }
106 return Collections.singletonList(onosInstanceId.toString());
Ray Milkey269ffb92014-04-03 14:43:30 -0700107 }
108
109 @Override
110 public String getControllerForSwitch(long dpid) throws RegistryException {
Jonathan Hart1dbcce62014-06-04 15:21:45 -0700111 return (switchCallbacks.get(HexString.toHexString(dpid)) == null)
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -0700112 ? null : onosInstanceId.toString();
Ray Milkey269ffb92014-04-03 14:43:30 -0700113 }
114
115 @Override
116 public Map<String, List<ControllerRegistryEntry>> getAllSwitches() {
117 Map<String, List<ControllerRegistryEntry>> switches =
118 new HashMap<String, List<ControllerRegistryEntry>>();
119
120 for (String strSwitch : switchCallbacks.keySet()) {
121 log.debug("Switch _{}", strSwitch);
Jonathan Hart1dbcce62014-06-04 15:21:45 -0700122 List<ControllerRegistryEntry> list =
123 new ArrayList<ControllerRegistryEntry>();
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -0700124 list.add(new ControllerRegistryEntry(onosInstanceId.toString(), 0));
Ray Milkey269ffb92014-04-03 14:43:30 -0700125
126 switches.put(strSwitch, list);
127 }
128
129 return switches;
130 }
131
132 @Override
133 public Collection<Long> getSwitchesControlledByController(
134 String controllerId) {
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700135 throw new NotImplementedException("Not yet implemented");
Ray Milkey269ffb92014-04-03 14:43:30 -0700136 }
137
Ray Milkey269ffb92014-04-03 14:43:30 -0700138 /**
139 * Returns a block of IDs which are unique and unused.
Jonathan Hart1dbcce62014-06-04 15:21:45 -0700140 * Range of IDs is fixed size and is assigned incrementally as this method
141 * called.
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700142 *
143 * @return an IdBlock containing a set of unique IDs
Ray Milkey269ffb92014-04-03 14:43:30 -0700144 */
145 @Override
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700146 public IdBlock allocateUniqueIdBlock() {
147 synchronized (this) {
148 long blockHead = blockTop;
149 long blockTail = blockTop + BLOCK_SIZE;
Ray Milkey269ffb92014-04-03 14:43:30 -0700150
Sho SHIMIZU9257b0c2014-08-13 15:00:10 -0700151 IdBlock block = new IdBlock(blockHead, BLOCK_SIZE);
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700152 blockTop = blockTail;
Ray Milkey269ffb92014-04-03 14:43:30 -0700153
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700154 return block;
155 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700156 }
157
158 /**
159 * Get a globally unique ID.
160 *
161 * @return a globally unique ID.
162 */
163 @Override
164 public long getNextUniqueId() {
165 return nextUniqueId.incrementAndGet();
166 }
167
168 @Override
169 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
170 Collection<Class<? extends IFloodlightService>> l =
Jonathan Hartbd766972013-02-22 15:13:03 -0800171 new ArrayList<Class<? extends IFloodlightService>>();
Ray Milkey269ffb92014-04-03 14:43:30 -0700172 l.add(IControllerRegistryService.class);
173 return l;
174 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800175
Ray Milkey269ffb92014-04-03 14:43:30 -0700176 @Override
177 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
178 Map<Class<? extends IFloodlightService>, IFloodlightService> m =
179 new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
180 m.put(IControllerRegistryService.class, this);
181 return m;
182 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800183
Ray Milkey269ffb92014-04-03 14:43:30 -0700184 @Override
185 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
186 Collection<Class<? extends IFloodlightService>> l =
187 new ArrayList<Class<? extends IFloodlightService>>();
188 l.add(IFloodlightProviderService.class);
189 l.add(IRestApiService.class);
190 return l;
191 }
192
193 @Override
194 public void init(FloodlightModuleContext context)
195 throws FloodlightModuleException {
196 restApi = context.getServiceImpl(IRestApiService.class);
197
198 switchCallbacks = new HashMap<String, ControlChangeCallback>();
199 }
200
201 @Override
202 public void startUp(FloodlightModuleContext context) {
203 restApi.addRestletRoutable(new RegistryWebRoutable());
204 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800205
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800206 @Override
207 public IdBlock allocateUniqueIdBlock(long range) {
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700208 throw new UnsupportedOperationException("Not supported yet");
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800209 }
210
Jonathan Hartbd766972013-02-22 15:13:03 -0800211}