blob: d5815902f01148ec757efa39ccd3fd4b0c4f6b19 [file] [log] [blame]
Jonathan Hartbd766972013-02-22 15:13:03 -08001package net.onrc.onos.registry.controller;
2
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;
Naoki Shiotab32edf52013-12-12 14:09:36 -080016import net.onrc.onos.registry.controller.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.
26 * @author jono
27 *
28 */
Jonathan Hartbd766972013-02-22 15:13:03 -080029public class StandaloneRegistry implements IFloodlightModule,
30 IControllerRegistryService {
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070031 protected final static Logger log = LoggerFactory.getLogger(StandaloneRegistry.class);
Jonathan Hartbd766972013-02-22 15:13:03 -080032
33 protected IRestApiService restApi;
34
Jonathan Hartbd766972013-02-22 15:13:03 -080035 protected String controllerId = null;
36 protected Map<String, ControlChangeCallback> switchCallbacks;
Pavlin Radoslavov52163ed2014-03-19 11:39:34 -070037
38 //
39 // Unique ID generation state
40 //
41 private static AtomicLong nextUniqueId = new AtomicLong(0);
Jonathan Hartbd766972013-02-22 15:13:03 -080042
43 @Override
44 public void requestControl(long dpid, ControlChangeCallback cb)
45 throws RegistryException {
46 if (controllerId == null) {
Jonathan Hartd10008d2013-02-23 17:04:08 -080047 throw new RuntimeException(
48 "Must register a controller before calling requestControl");
Jonathan Hartbd766972013-02-22 15:13:03 -080049 }
50
51 switchCallbacks.put(HexString.toHexString(dpid), cb);
52
53 log.debug("Control granted for {}", HexString.toHexString(dpid));
54
55 //Immediately grant request for control
56 if (cb != null) {
57 cb.controlChanged(dpid, true);
58 }
59 }
60
61 @Override
62 public void releaseControl(long dpid) {
63 ControlChangeCallback cb = switchCallbacks.remove(HexString.toHexString(dpid));
64
65 log.debug("Control released for {}", HexString.toHexString(dpid));
66
67 if (cb != null){
68 cb.controlChanged(dpid, false);
69 }
70 }
71
72 @Override
73 public boolean hasControl(long dpid) {
74 return switchCallbacks.containsKey(HexString.toHexString(dpid));
75 }
76
77 @Override
Pavlin Radoslavovf1377ce2014-02-05 17:37:24 -080078 public boolean isClusterLeader() {
79 return true;
80 }
81
82 @Override
Jonathan Hart7bf62172013-02-28 13:17:18 -080083 public String getControllerId() {
Jonathan Hartbd766972013-02-22 15:13:03 -080084 return controllerId;
85 }
86
87 @Override
88 public void registerController(String controllerId)
89 throws RegistryException {
Jonathan Hartd10008d2013-02-23 17:04:08 -080090 if (this.controllerId != null) {
91 throw new RegistryException(
92 "Controller already registered with id " + this.controllerId);
93 }
Jonathan Hartbd766972013-02-22 15:13:03 -080094 this.controllerId = controllerId;
95 }
96
97 @Override
98 public Collection<String> getAllControllers() throws RegistryException {
99 List<String> l = new ArrayList<String>();
100 l.add(controllerId);
101 return l;
102 }
103
104 @Override
105 public String getControllerForSwitch(long dpid) throws RegistryException {
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700106 return (switchCallbacks.get(HexString.toHexString(dpid)) != null)? controllerId: null;
Jonathan Hartbd766972013-02-22 15:13:03 -0800107 }
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()){
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800115 log.debug("Switch _{}", strSwitch);
Jonathan Hartbd766972013-02-22 15:13:03 -0800116 List<ControllerRegistryEntry> list = new ArrayList<ControllerRegistryEntry>();
117 list.add(new ControllerRegistryEntry(controllerId, 0));
118
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 }
Jonathan Hart1530ccc2013-04-03 19:36:02 -0700130
Naoki Shiotad00accf2013-06-25 14:40:37 -0700131 private long blockTop = 0L;
132 private static final long BLOCK_SIZE = 0x1000000L;
Naoki Shiotaa3b2dfa2013-06-27 13:52:24 -0700133
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 */
Jonathan Hart1530ccc2013-04-03 19:36:02 -0700138 @Override
Naoki Shiotaa3b2dfa2013-06-27 13:52:24 -0700139 public synchronized IdBlock allocateUniqueIdBlock(){
Naoki Shiotad00accf2013-06-25 14:40:37 -0700140 long blockHead = blockTop;
141 long blockTail = blockTop + BLOCK_SIZE;
142
Naoki Shiotaa3b2dfa2013-06-27 13:52:24 -0700143 IdBlock block = new IdBlock(blockHead, blockTail - 1, BLOCK_SIZE);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700144 blockTop = blockTail;
145
146 return block;
Jonathan Hart1530ccc2013-04-03 19:36:02 -0700147 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800148
Pavlin Radoslavov52163ed2014-03-19 11:39:34 -0700149 /**
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
Jonathan Hartbd766972013-02-22 15:13:03 -0800159 @Override
160 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
161 Collection<Class<? extends IFloodlightService>> l =
162 new ArrayList<Class<? extends IFloodlightService>>();
163 l.add(IControllerRegistryService.class);
164 return l;
165 }
166
167 @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 }
174
175 @Override
176 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
177 Collection<Class<? extends IFloodlightService>> l =
178 new ArrayList<Class<? extends IFloodlightService>>();
Pavlin Radoslavovc35229e2014-02-06 16:19:37 -0800179 l.add(IFloodlightProviderService.class);
180 l.add(IRestApiService.class);
Jonathan Hartbd766972013-02-22 15:13:03 -0800181 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>();
Jonathan Hartbd766972013-02-22 15:13:03 -0800190 }
191
192 @Override
193 public void startUp(FloodlightModuleContext context) {
194 restApi.addRestletRoutable(new RegistryWebRoutable());
195 }
196
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}