blob: 0b552f1127e5585da6b32bcbe850daad4a488dd6 [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;
Jonathan Hartbd766972013-02-22 15:13:03 -080018
Jonathan Hart12a26aa2014-06-04 14:33:09 -070019import org.apache.commons.lang.NotImplementedException;
Jonathan Hartbd766972013-02-22 15:13:03 -080020import org.openflow.util.HexString;
21import org.slf4j.Logger;
22import org.slf4j.LoggerFactory;
23
Jonathan Hart7bf62172013-02-28 13:17:18 -080024/**
25 * Implementation of a registry that doesn't rely on any external registry
26 * service. This is designed to be used only in single-node setups (e.g. for
27 * development). All registry data is stored in local memory.
Jonathan Hart7bf62172013-02-28 13:17:18 -080028 */
Jonathan Hartbd766972013-02-22 15:13:03 -080029public class StandaloneRegistry implements IFloodlightModule,
Ray Milkey269ffb92014-04-03 14:43:30 -070030 IControllerRegistryService {
Ray Milkeyec838942014-04-09 11:28:43 -070031 private static final Logger log = LoggerFactory.getLogger(StandaloneRegistry.class);
Pavlin Radoslavov52163ed2014-03-19 11:39:34 -070032
Jonathan Hart12a26aa2014-06-04 14:33:09 -070033 private IRestApiService restApi;
Jonathan Hartbd766972013-02-22 15:13:03 -080034
Jonathan Hart12a26aa2014-06-04 14:33:09 -070035 private String registeredControllerId;
36 private Map<String, ControlChangeCallback> switchCallbacks;
Jonathan Hartbd766972013-02-22 15:13:03 -080037
Jonathan Hart1dbcce62014-06-04 15:21:45 -070038 private long blockTop;
39 private static final long BLOCK_SIZE = 0x1000000L;
40
Ray Milkey269ffb92014-04-03 14:43:30 -070041 //
42 // Unique ID generation state
43 //
44 private static AtomicLong nextUniqueId = new AtomicLong(0);
Jonathan Hartbd766972013-02-22 15:13:03 -080045
Ray Milkey269ffb92014-04-03 14:43:30 -070046 @Override
47 public void requestControl(long dpid, ControlChangeCallback cb)
48 throws RegistryException {
Ray Milkey5df613b2014-04-15 10:50:56 -070049 if (registeredControllerId == null) {
Jonathan Hart12a26aa2014-06-04 14:33:09 -070050 throw new IllegalStateException(
Ray Milkey269ffb92014-04-03 14:43:30 -070051 "Must register a controller before calling requestControl");
52 }
Jonathan Hartbd766972013-02-22 15:13:03 -080053
Ray Milkey269ffb92014-04-03 14:43:30 -070054 switchCallbacks.put(HexString.toHexString(dpid), cb);
Pavlin Radoslavovf1377ce2014-02-05 17:37:24 -080055
Ray Milkey269ffb92014-04-03 14:43:30 -070056 log.debug("Control granted for {}", HexString.toHexString(dpid));
Jonathan Hartbd766972013-02-22 15:13:03 -080057
Jonathan Hart12a26aa2014-06-04 14:33:09 -070058 // Immediately grant request for control
Ray Milkey269ffb92014-04-03 14:43:30 -070059 if (cb != null) {
60 cb.controlChanged(dpid, true);
61 }
62 }
Jonathan Hartbd766972013-02-22 15:13:03 -080063
Ray Milkey269ffb92014-04-03 14:43:30 -070064 @Override
65 public void releaseControl(long dpid) {
66 ControlChangeCallback cb = switchCallbacks.remove(HexString.toHexString(dpid));
Jonathan Hartbd766972013-02-22 15:13:03 -080067
Ray Milkey269ffb92014-04-03 14:43:30 -070068 log.debug("Control released for {}", HexString.toHexString(dpid));
Jonathan Hartbd766972013-02-22 15:13:03 -080069
Ray Milkey269ffb92014-04-03 14:43:30 -070070 if (cb != null) {
71 cb.controlChanged(dpid, false);
72 }
73 }
Jonathan Hartbd766972013-02-22 15:13:03 -080074
Ray Milkey269ffb92014-04-03 14:43:30 -070075 @Override
76 public boolean hasControl(long dpid) {
77 return switchCallbacks.containsKey(HexString.toHexString(dpid));
78 }
Jonathan Hartbd766972013-02-22 15:13:03 -080079
Ray Milkey269ffb92014-04-03 14:43:30 -070080 @Override
81 public boolean isClusterLeader() {
82 return true;
83 }
Pavlin Radoslavov52163ed2014-03-19 11:39:34 -070084
Ray Milkey269ffb92014-04-03 14:43:30 -070085 @Override
86 public String getControllerId() {
Ray Milkey5df613b2014-04-15 10:50:56 -070087 return registeredControllerId;
Ray Milkey269ffb92014-04-03 14:43:30 -070088 }
Jonathan Hartbd766972013-02-22 15:13:03 -080089
Ray Milkey269ffb92014-04-03 14:43:30 -070090 @Override
91 public void registerController(String controllerId)
92 throws RegistryException {
Ray Milkey5df613b2014-04-15 10:50:56 -070093 if (registeredControllerId != null) {
Ray Milkey269ffb92014-04-03 14:43:30 -070094 throw new RegistryException(
Ray Milkey5df613b2014-04-15 10:50:56 -070095 "Controller already registered with id " + registeredControllerId);
Ray Milkey269ffb92014-04-03 14:43:30 -070096 }
Ray Milkey5df613b2014-04-15 10:50:56 -070097 registeredControllerId = controllerId;
Ray Milkey269ffb92014-04-03 14:43:30 -070098 }
Jonathan Hartbd766972013-02-22 15:13:03 -080099
Ray Milkey269ffb92014-04-03 14:43:30 -0700100 @Override
101 public Collection<String> getAllControllers() throws RegistryException {
Jonathan Hart1dbcce62014-06-04 15:21:45 -0700102 //List<String> l = new ArrayList<String>();
103 //l.add(registeredControllerId);
104 //return l;
105 return Collections.singletonList(registeredControllerId);
Ray Milkey269ffb92014-04-03 14:43:30 -0700106 }
107
108 @Override
109 public String getControllerForSwitch(long dpid) throws RegistryException {
Jonathan Hart1dbcce62014-06-04 15:21:45 -0700110 return (switchCallbacks.get(HexString.toHexString(dpid)) == null)
111 ? null : registeredControllerId;
Ray Milkey269ffb92014-04-03 14:43:30 -0700112 }
113
114 @Override
115 public Map<String, List<ControllerRegistryEntry>> getAllSwitches() {
116 Map<String, List<ControllerRegistryEntry>> switches =
117 new HashMap<String, List<ControllerRegistryEntry>>();
118
119 for (String strSwitch : switchCallbacks.keySet()) {
120 log.debug("Switch _{}", strSwitch);
Jonathan Hart1dbcce62014-06-04 15:21:45 -0700121 List<ControllerRegistryEntry> list =
122 new ArrayList<ControllerRegistryEntry>();
Ray Milkey5df613b2014-04-15 10:50:56 -0700123 list.add(new ControllerRegistryEntry(registeredControllerId, 0));
Ray Milkey269ffb92014-04-03 14:43:30 -0700124
125 switches.put(strSwitch, list);
126 }
127
128 return switches;
129 }
130
131 @Override
132 public Collection<Long> getSwitchesControlledByController(
133 String controllerId) {
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700134 throw new NotImplementedException("Not yet implemented");
Ray Milkey269ffb92014-04-03 14:43:30 -0700135 }
136
Ray Milkey269ffb92014-04-03 14:43:30 -0700137 /**
138 * Returns a block of IDs which are unique and unused.
Jonathan Hart1dbcce62014-06-04 15:21:45 -0700139 * Range of IDs is fixed size and is assigned incrementally as this method
140 * called.
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700141 *
142 * @return an IdBlock containing a set of unique IDs
Ray Milkey269ffb92014-04-03 14:43:30 -0700143 */
144 @Override
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700145 public IdBlock allocateUniqueIdBlock() {
146 synchronized (this) {
147 long blockHead = blockTop;
148 long blockTail = blockTop + BLOCK_SIZE;
Ray Milkey269ffb92014-04-03 14:43:30 -0700149
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700150 IdBlock block = new IdBlock(blockHead, blockTail - 1, BLOCK_SIZE);
151 blockTop = blockTail;
Ray Milkey269ffb92014-04-03 14:43:30 -0700152
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700153 return block;
154 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700155 }
156
157 /**
158 * Get a globally unique ID.
159 *
160 * @return a globally unique ID.
161 */
162 @Override
163 public long getNextUniqueId() {
164 return nextUniqueId.incrementAndGet();
165 }
166
167 @Override
168 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
169 Collection<Class<? extends IFloodlightService>> l =
Jonathan Hartbd766972013-02-22 15:13:03 -0800170 new ArrayList<Class<? extends IFloodlightService>>();
Ray Milkey269ffb92014-04-03 14:43:30 -0700171 l.add(IControllerRegistryService.class);
172 return l;
173 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800174
Ray Milkey269ffb92014-04-03 14:43:30 -0700175 @Override
176 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
177 Map<Class<? extends IFloodlightService>, IFloodlightService> m =
178 new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
179 m.put(IControllerRegistryService.class, this);
180 return m;
181 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800182
Ray Milkey269ffb92014-04-03 14:43:30 -0700183 @Override
184 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
185 Collection<Class<? extends IFloodlightService>> l =
186 new ArrayList<Class<? extends IFloodlightService>>();
187 l.add(IFloodlightProviderService.class);
188 l.add(IRestApiService.class);
189 return l;
190 }
191
192 @Override
193 public void init(FloodlightModuleContext context)
194 throws FloodlightModuleException {
195 restApi = context.getServiceImpl(IRestApiService.class);
196
197 switchCallbacks = new HashMap<String, ControlChangeCallback>();
198 }
199
200 @Override
201 public void startUp(FloodlightModuleContext context) {
202 restApi.addRestletRoutable(new RegistryWebRoutable());
203 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800204
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800205 @Override
206 public IdBlock allocateUniqueIdBlock(long range) {
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700207 throw new UnsupportedOperationException("Not supported yet");
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800208 }
209
Jonathan Hartbd766972013-02-22 15:13:03 -0800210}