blob: de07adf97284862c1cdf334daee4f9435afd028e [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;
5import java.util.HashMap;
6import java.util.List;
7import java.util.Map;
Pavlin Radoslavov52163ed2014-03-19 11:39:34 -07008import java.util.concurrent.atomic.AtomicLong;
Jonathan Hartbd766972013-02-22 15:13:03 -08009
Pavlin Radoslavovc35229e2014-02-06 16:19:37 -080010import net.floodlightcontroller.core.IFloodlightProviderService;
Jonathan Hartbd766972013-02-22 15:13:03 -080011import net.floodlightcontroller.core.module.FloodlightModuleContext;
12import net.floodlightcontroller.core.module.FloodlightModuleException;
13import net.floodlightcontroller.core.module.IFloodlightModule;
14import net.floodlightcontroller.core.module.IFloodlightService;
15import net.floodlightcontroller.restserver.IRestApiService;
Jonathan Hartdeda0ba2014-04-03 11:14:12 -070016import net.onrc.onos.core.registry.web.RegistryWebRoutable;
Jonathan Hartbd766972013-02-22 15:13:03 -080017
Jonathan Hart12a26aa2014-06-04 14:33:09 -070018import org.apache.commons.lang.NotImplementedException;
Jonathan Hartbd766972013-02-22 15:13:03 -080019import org.openflow.util.HexString;
20import org.slf4j.Logger;
21import org.slf4j.LoggerFactory;
22
Jonathan Hart7bf62172013-02-28 13:17:18 -080023/**
24 * Implementation of a registry that doesn't rely on any external registry
25 * service. This is designed to be used only in single-node setups (e.g. for
26 * development). All registry data is stored in local memory.
Jonathan Hart7bf62172013-02-28 13:17:18 -080027 */
Jonathan Hartbd766972013-02-22 15:13:03 -080028public class StandaloneRegistry implements IFloodlightModule,
Ray Milkey269ffb92014-04-03 14:43:30 -070029 IControllerRegistryService {
Ray Milkeyec838942014-04-09 11:28:43 -070030 private static final Logger log = LoggerFactory.getLogger(StandaloneRegistry.class);
Pavlin Radoslavov52163ed2014-03-19 11:39:34 -070031
Jonathan Hart12a26aa2014-06-04 14:33:09 -070032 private IRestApiService restApi;
Jonathan Hartbd766972013-02-22 15:13:03 -080033
Jonathan Hart12a26aa2014-06-04 14:33:09 -070034 private String registeredControllerId;
35 private Map<String, ControlChangeCallback> switchCallbacks;
Jonathan Hartbd766972013-02-22 15:13:03 -080036
Ray Milkey269ffb92014-04-03 14:43:30 -070037 //
38 // Unique ID generation state
39 //
40 private static AtomicLong nextUniqueId = new AtomicLong(0);
Jonathan Hartbd766972013-02-22 15:13:03 -080041
Ray Milkey269ffb92014-04-03 14:43:30 -070042 @Override
43 public void requestControl(long dpid, ControlChangeCallback cb)
44 throws RegistryException {
Ray Milkey5df613b2014-04-15 10:50:56 -070045 if (registeredControllerId == null) {
Jonathan Hart12a26aa2014-06-04 14:33:09 -070046 throw new IllegalStateException(
Ray Milkey269ffb92014-04-03 14:43:30 -070047 "Must register a controller before calling requestControl");
48 }
Jonathan Hartbd766972013-02-22 15:13:03 -080049
Ray Milkey269ffb92014-04-03 14:43:30 -070050 switchCallbacks.put(HexString.toHexString(dpid), cb);
Pavlin Radoslavovf1377ce2014-02-05 17:37:24 -080051
Ray Milkey269ffb92014-04-03 14:43:30 -070052 log.debug("Control granted for {}", HexString.toHexString(dpid));
Jonathan Hartbd766972013-02-22 15:13:03 -080053
Jonathan Hart12a26aa2014-06-04 14:33:09 -070054 // Immediately grant request for control
Ray Milkey269ffb92014-04-03 14:43:30 -070055 if (cb != null) {
56 cb.controlChanged(dpid, true);
57 }
58 }
Jonathan Hartbd766972013-02-22 15:13:03 -080059
Ray Milkey269ffb92014-04-03 14:43:30 -070060 @Override
61 public void releaseControl(long dpid) {
62 ControlChangeCallback cb = switchCallbacks.remove(HexString.toHexString(dpid));
Jonathan Hartbd766972013-02-22 15:13:03 -080063
Ray Milkey269ffb92014-04-03 14:43:30 -070064 log.debug("Control released for {}", HexString.toHexString(dpid));
Jonathan Hartbd766972013-02-22 15:13:03 -080065
Ray Milkey269ffb92014-04-03 14:43:30 -070066 if (cb != null) {
67 cb.controlChanged(dpid, false);
68 }
69 }
Jonathan Hartbd766972013-02-22 15:13:03 -080070
Ray Milkey269ffb92014-04-03 14:43:30 -070071 @Override
72 public boolean hasControl(long dpid) {
73 return switchCallbacks.containsKey(HexString.toHexString(dpid));
74 }
Jonathan Hartbd766972013-02-22 15:13:03 -080075
Ray Milkey269ffb92014-04-03 14:43:30 -070076 @Override
77 public boolean isClusterLeader() {
78 return true;
79 }
Pavlin Radoslavov52163ed2014-03-19 11:39:34 -070080
Ray Milkey269ffb92014-04-03 14:43:30 -070081 @Override
82 public String getControllerId() {
Ray Milkey5df613b2014-04-15 10:50:56 -070083 return registeredControllerId;
Ray Milkey269ffb92014-04-03 14:43:30 -070084 }
Jonathan Hartbd766972013-02-22 15:13:03 -080085
Ray Milkey269ffb92014-04-03 14:43:30 -070086 @Override
87 public void registerController(String controllerId)
88 throws RegistryException {
Ray Milkey5df613b2014-04-15 10:50:56 -070089 if (registeredControllerId != null) {
Ray Milkey269ffb92014-04-03 14:43:30 -070090 throw new RegistryException(
Ray Milkey5df613b2014-04-15 10:50:56 -070091 "Controller already registered with id " + registeredControllerId);
Ray Milkey269ffb92014-04-03 14:43:30 -070092 }
Ray Milkey5df613b2014-04-15 10:50:56 -070093 registeredControllerId = controllerId;
Ray Milkey269ffb92014-04-03 14:43:30 -070094 }
Jonathan Hartbd766972013-02-22 15:13:03 -080095
Ray Milkey269ffb92014-04-03 14:43:30 -070096 @Override
97 public Collection<String> getAllControllers() throws RegistryException {
98 List<String> l = new ArrayList<String>();
Ray Milkey5df613b2014-04-15 10:50:56 -070099 l.add(registeredControllerId);
Ray Milkey269ffb92014-04-03 14:43:30 -0700100 return l;
101 }
102
103 @Override
104 public String getControllerForSwitch(long dpid) throws RegistryException {
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700105 return (switchCallbacks.get(HexString.toHexString(dpid)) == null) ? null : registeredControllerId;
Ray Milkey269ffb92014-04-03 14:43:30 -0700106 }
107
108 @Override
109 public Map<String, List<ControllerRegistryEntry>> getAllSwitches() {
110 Map<String, List<ControllerRegistryEntry>> switches =
111 new HashMap<String, List<ControllerRegistryEntry>>();
112
113 for (String strSwitch : switchCallbacks.keySet()) {
114 log.debug("Switch _{}", strSwitch);
115 List<ControllerRegistryEntry> list = new ArrayList<ControllerRegistryEntry>();
Ray Milkey5df613b2014-04-15 10:50:56 -0700116 list.add(new ControllerRegistryEntry(registeredControllerId, 0));
Ray Milkey269ffb92014-04-03 14:43:30 -0700117
118 switches.put(strSwitch, list);
119 }
120
121 return switches;
122 }
123
124 @Override
125 public Collection<Long> getSwitchesControlledByController(
126 String controllerId) {
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700127 throw new NotImplementedException("Not yet implemented");
Ray Milkey269ffb92014-04-03 14:43:30 -0700128 }
129
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700130 private long blockTop;
Ray Milkey269ffb92014-04-03 14:43:30 -0700131 private static final long BLOCK_SIZE = 0x1000000L;
132
133 /**
134 * Returns a block of IDs which are unique and unused.
135 * Range of IDs is fixed size and is assigned incrementally as this method called.
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700136 *
137 * @return an IdBlock containing a set of unique IDs
Ray Milkey269ffb92014-04-03 14:43:30 -0700138 */
139 @Override
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700140 public IdBlock allocateUniqueIdBlock() {
141 synchronized (this) {
142 long blockHead = blockTop;
143 long blockTail = blockTop + BLOCK_SIZE;
Ray Milkey269ffb92014-04-03 14:43:30 -0700144
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700145 IdBlock block = new IdBlock(blockHead, blockTail - 1, BLOCK_SIZE);
146 blockTop = blockTail;
Ray Milkey269ffb92014-04-03 14:43:30 -0700147
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700148 return block;
149 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700150 }
151
152 /**
153 * Get a globally unique ID.
154 *
155 * @return a globally unique ID.
156 */
157 @Override
158 public long getNextUniqueId() {
159 return nextUniqueId.incrementAndGet();
160 }
161
162 @Override
163 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
164 Collection<Class<? extends IFloodlightService>> l =
Jonathan Hartbd766972013-02-22 15:13:03 -0800165 new ArrayList<Class<? extends IFloodlightService>>();
Ray Milkey269ffb92014-04-03 14:43:30 -0700166 l.add(IControllerRegistryService.class);
167 return l;
168 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800169
Ray Milkey269ffb92014-04-03 14:43:30 -0700170 @Override
171 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
172 Map<Class<? extends IFloodlightService>, IFloodlightService> m =
173 new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
174 m.put(IControllerRegistryService.class, this);
175 return m;
176 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800177
Ray Milkey269ffb92014-04-03 14:43:30 -0700178 @Override
179 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
180 Collection<Class<? extends IFloodlightService>> l =
181 new ArrayList<Class<? extends IFloodlightService>>();
182 l.add(IFloodlightProviderService.class);
183 l.add(IRestApiService.class);
184 return l;
185 }
186
187 @Override
188 public void init(FloodlightModuleContext context)
189 throws FloodlightModuleException {
190 restApi = context.getServiceImpl(IRestApiService.class);
191
192 switchCallbacks = new HashMap<String, ControlChangeCallback>();
193 }
194
195 @Override
196 public void startUp(FloodlightModuleContext context) {
197 restApi.addRestletRoutable(new RegistryWebRoutable());
198 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800199
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800200 @Override
201 public IdBlock allocateUniqueIdBlock(long range) {
Jonathan Hart12a26aa2014-06-04 14:33:09 -0700202 throw new UnsupportedOperationException("Not supported yet");
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800203 }
204
Jonathan Hartbd766972013-02-22 15:13:03 -0800205}