blob: 989d2c1c1b2cd5f1ad2d26cf83e4db3815891a07 [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
18import org.openflow.util.HexString;
19import org.slf4j.Logger;
20import org.slf4j.LoggerFactory;
21
Jonathan Hart7bf62172013-02-28 13:17:18 -080022/**
23 * Implementation of a registry that doesn't rely on any external registry
24 * service. This is designed to be used only in single-node setups (e.g. for
25 * development). All registry data is stored in local memory.
Jonathan Hart7bf62172013-02-28 13:17:18 -080026 *
Ray Milkey269ffb92014-04-03 14:43:30 -070027 * @author jono
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
Ray Milkey269ffb92014-04-03 14:43:30 -070033 protected IRestApiService restApi;
Jonathan Hartbd766972013-02-22 15:13:03 -080034
Ray Milkey5df613b2014-04-15 10:50:56 -070035 protected String registeredControllerId = null;
Ray Milkey269ffb92014-04-03 14:43:30 -070036 protected Map<String, ControlChangeCallback> switchCallbacks;
Jonathan Hartbd766972013-02-22 15:13:03 -080037
Ray Milkey269ffb92014-04-03 14:43:30 -070038 //
39 // Unique ID generation state
40 //
41 private static AtomicLong nextUniqueId = new AtomicLong(0);
Jonathan Hartbd766972013-02-22 15:13:03 -080042
Ray Milkey269ffb92014-04-03 14:43:30 -070043 @Override
44 public void requestControl(long dpid, ControlChangeCallback cb)
45 throws RegistryException {
Ray Milkey5df613b2014-04-15 10:50:56 -070046 if (registeredControllerId == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -070047 throw new RuntimeException(
48 "Must register a controller before calling requestControl");
49 }
Jonathan Hartbd766972013-02-22 15:13:03 -080050
Ray Milkey269ffb92014-04-03 14:43:30 -070051 switchCallbacks.put(HexString.toHexString(dpid), cb);
Pavlin Radoslavovf1377ce2014-02-05 17:37:24 -080052
Ray Milkey269ffb92014-04-03 14:43:30 -070053 log.debug("Control granted for {}", HexString.toHexString(dpid));
Jonathan Hartbd766972013-02-22 15:13:03 -080054
Ray Milkey269ffb92014-04-03 14:43:30 -070055 //Immediately grant request for control
56 if (cb != null) {
57 cb.controlChanged(dpid, true);
58 }
59 }
Jonathan Hartbd766972013-02-22 15:13:03 -080060
Ray Milkey269ffb92014-04-03 14:43:30 -070061 @Override
62 public void releaseControl(long dpid) {
63 ControlChangeCallback cb = switchCallbacks.remove(HexString.toHexString(dpid));
Jonathan Hartbd766972013-02-22 15:13:03 -080064
Ray Milkey269ffb92014-04-03 14:43:30 -070065 log.debug("Control released for {}", HexString.toHexString(dpid));
Jonathan Hartbd766972013-02-22 15:13:03 -080066
Ray Milkey269ffb92014-04-03 14:43:30 -070067 if (cb != null) {
68 cb.controlChanged(dpid, false);
69 }
70 }
Jonathan Hartbd766972013-02-22 15:13:03 -080071
Ray Milkey269ffb92014-04-03 14:43:30 -070072 @Override
73 public boolean hasControl(long dpid) {
74 return switchCallbacks.containsKey(HexString.toHexString(dpid));
75 }
Jonathan Hartbd766972013-02-22 15:13:03 -080076
Ray Milkey269ffb92014-04-03 14:43:30 -070077 @Override
78 public boolean isClusterLeader() {
79 return true;
80 }
Pavlin Radoslavov52163ed2014-03-19 11:39:34 -070081
Ray Milkey269ffb92014-04-03 14:43:30 -070082 @Override
83 public String getControllerId() {
Ray Milkey5df613b2014-04-15 10:50:56 -070084 return registeredControllerId;
Ray Milkey269ffb92014-04-03 14:43:30 -070085 }
Jonathan Hartbd766972013-02-22 15:13:03 -080086
Ray Milkey269ffb92014-04-03 14:43:30 -070087 @Override
88 public void registerController(String controllerId)
89 throws RegistryException {
Ray Milkey5df613b2014-04-15 10:50:56 -070090 if (registeredControllerId != null) {
Ray Milkey269ffb92014-04-03 14:43:30 -070091 throw new RegistryException(
Ray Milkey5df613b2014-04-15 10:50:56 -070092 "Controller already registered with id " + registeredControllerId);
Ray Milkey269ffb92014-04-03 14:43:30 -070093 }
Ray Milkey5df613b2014-04-15 10:50:56 -070094 registeredControllerId = controllerId;
Ray Milkey269ffb92014-04-03 14:43:30 -070095 }
Jonathan Hartbd766972013-02-22 15:13:03 -080096
Ray Milkey269ffb92014-04-03 14:43:30 -070097 @Override
98 public Collection<String> getAllControllers() throws RegistryException {
99 List<String> l = new ArrayList<String>();
Ray Milkey5df613b2014-04-15 10:50:56 -0700100 l.add(registeredControllerId);
Ray Milkey269ffb92014-04-03 14:43:30 -0700101 return l;
102 }
103
104 @Override
105 public String getControllerForSwitch(long dpid) throws RegistryException {
Ray Milkey5df613b2014-04-15 10:50:56 -0700106 return (switchCallbacks.get(HexString.toHexString(dpid)) != null) ? registeredControllerId : null;
Ray Milkey269ffb92014-04-03 14:43:30 -0700107 }
108
109 @Override
110 public Map<String, List<ControllerRegistryEntry>> getAllSwitches() {
111 Map<String, List<ControllerRegistryEntry>> switches =
112 new HashMap<String, List<ControllerRegistryEntry>>();
113
114 for (String strSwitch : switchCallbacks.keySet()) {
115 log.debug("Switch _{}", strSwitch);
116 List<ControllerRegistryEntry> list = new ArrayList<ControllerRegistryEntry>();
Ray Milkey5df613b2014-04-15 10:50:56 -0700117 list.add(new ControllerRegistryEntry(registeredControllerId, 0));
Ray Milkey269ffb92014-04-03 14:43:30 -0700118
119 switches.put(strSwitch, list);
120 }
121
122 return switches;
123 }
124
125 @Override
126 public Collection<Long> getSwitchesControlledByController(
127 String controllerId) {
128 throw new RuntimeException("Not yet implemented");
129 }
130
131 private long blockTop = 0L;
132 private static final long BLOCK_SIZE = 0x1000000L;
133
134 /**
135 * Returns a block of IDs which are unique and unused.
136 * Range of IDs is fixed size and is assigned incrementally as this method called.
137 */
138 @Override
139 public synchronized IdBlock allocateUniqueIdBlock() {
140 long blockHead = blockTop;
141 long blockTail = blockTop + BLOCK_SIZE;
142
143 IdBlock block = new IdBlock(blockHead, blockTail - 1, BLOCK_SIZE);
144 blockTop = blockTail;
145
146 return block;
147 }
148
149 /**
150 * Get a globally unique ID.
151 *
152 * @return a globally unique ID.
153 */
154 @Override
155 public long getNextUniqueId() {
156 return nextUniqueId.incrementAndGet();
157 }
158
159 @Override
160 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
161 Collection<Class<? extends IFloodlightService>> l =
Jonathan Hartbd766972013-02-22 15:13:03 -0800162 new ArrayList<Class<? extends IFloodlightService>>();
Ray Milkey269ffb92014-04-03 14:43:30 -0700163 l.add(IControllerRegistryService.class);
164 return l;
165 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800166
Ray Milkey269ffb92014-04-03 14:43:30 -0700167 @Override
168 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
169 Map<Class<? extends IFloodlightService>, IFloodlightService> m =
170 new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
171 m.put(IControllerRegistryService.class, this);
172 return m;
173 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800174
Ray Milkey269ffb92014-04-03 14:43:30 -0700175 @Override
176 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
177 Collection<Class<? extends IFloodlightService>> l =
178 new ArrayList<Class<? extends IFloodlightService>>();
179 l.add(IFloodlightProviderService.class);
180 l.add(IRestApiService.class);
181 return l;
182 }
183
184 @Override
185 public void init(FloodlightModuleContext context)
186 throws FloodlightModuleException {
187 restApi = context.getServiceImpl(IRestApiService.class);
188
189 switchCallbacks = new HashMap<String, ControlChangeCallback>();
190 }
191
192 @Override
193 public void startUp(FloodlightModuleContext context) {
194 restApi.addRestletRoutable(new RegistryWebRoutable());
195 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800196
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800197 @Override
198 public IdBlock allocateUniqueIdBlock(long range) {
199 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
200 }
201
Jonathan Hartbd766972013-02-22 15:13:03 -0800202}