EMMA Coverage Report (generated Mon Aug 23 17:21:34 CEST 2010)
[all classes][dmg.cells.services]

COVERAGE SUMMARY FOR SOURCE FILE [RoutingManager.java]

nameclass, %method, %block, %line, %
RoutingManager.java100% (1/1)33%  (6/18)20%  (147/730)23%  (32.6/145)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class RoutingManager100% (1/1)33%  (6/18)20%  (147/730)23%  (32.6/145)
ac_ls_$_0 (Args): Object 0%   (0/1)0%   (0/45)0%   (0/13)
ac_update (Args): String 0%   (0/1)0%   (0/4)0%   (0/2)
addRoutingInfo (String []): void 0%   (0/1)0%   (0/132)0%   (0/21)
addWellknown (String, String): void 0%   (0/1)0%   (0/35)0%   (0/7)
getInfo (PrintWriter): void 0%   (0/1)0%   (0/35)0%   (0/5)
isDefaultInstalled (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
messageArrived (CellMessage): void 0%   (0/1)0%   (0/45)0%   (0/11)
removeRoutingInfo (String): void 0%   (0/1)0%   (0/45)0%   (0/8)
removeWellknown (String, String): void 0%   (0/1)0%   (0/35)0%   (0/7)
routeAdded (CellEvent): void 0%   (0/1)0%   (0/93)0%   (0/17)
routeDeleted (CellEvent): void 0%   (0/1)0%   (0/56)0%   (0/11)
setDefaultInstalled (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
updateUpstream (): void 100% (1/1)45%  (39/86)52%  (7.7/15)
RoutingManager (String, String): void 100% (1/1)92%  (45/49)99%  (10.9/11)
<static initializer> 100% (1/1)100% (4/4)100% (1/1)
cellCreated (CellEvent): void 100% (1/1)100% (15/15)100% (3/3)
cellDied (CellEvent): void 100% (1/1)100% (22/22)100% (5/5)
cellExported (CellEvent): void 100% (1/1)100% (22/22)100% (5/5)

1package dmg.cells.services;
2 
3import java.util.*;
4import java.io.*;
5import dmg.cells.nucleus.*;
6import dmg.util.*;
7 
8import org.slf4j.Logger;
9import org.slf4j.LoggerFactory;
10 
11/**
12  *
13  * The dmg.cells.services.RoutingManager is a ready to use
14  * service Cell, performing the following services :
15  * <ul>
16  * <li>Watching a specified tunnel cell and setting the
17  *     default route to this cell as soon as this tunnel
18  *     cell establishes its domain route.
19  * <li>Assembling downstream routing informations and
20  *     the exportCell EventListener Event and maitaining
21  *     a wellknown Cell list.
22  * <li>Sending its wellknown cell list upstream as soon
23  *     as a default route is available and whenever
24  *     the wellknown cell list changes.
25  * </ul>
26  * @author Patrick Fuhrmann
27  * @version 0.1, 15 Feb 1998
28  */
29public class RoutingManager
30    extends CellAdapter
31    implements CellEventListener
32{
33    private final static Logger _log =
34        LoggerFactory.getLogger(RoutingManager.class);
35 
36    private final CellNucleus _nucleus;
37    private final Args _args;
38    private final Set<String> _localExports = new HashSet();
39    private final Map<String,Set<String>> _domainHash = new HashMap();
40    private final String _watchCell;
41    private boolean _defaultInstalled = false;
42 
43    public RoutingManager(String name, String args)
44    {
45        super(name,"System", args, false);
46        _nucleus = getNucleus();
47        _args = getArgs();
48 
49        _nucleus.addCellEventListener(this);
50        _watchCell = _args.argc() == 0 ? null : _args.argv(0);
51 
52        start();
53    }
54 
55    public synchronized void getInfo(PrintWriter pw)
56    {
57        pw.println(" Our routing knowledge :");
58        pw.append(" Local : ").println(_localExports);
59 
60        for (Map.Entry<String,Set<String>> e : _domainHash.entrySet()) {
61            pw.append(" ").append(e.getKey()).append(" : ").println(e.getValue());
62        }
63    }
64 
65    private synchronized void setDefaultInstalled(boolean value)
66    {
67        _defaultInstalled = value;
68    }
69 
70    private synchronized boolean isDefaultInstalled()
71    {
72        return _defaultInstalled;
73    }
74 
75    private void addWellknown(String cell, String domain)
76    {
77        if (cell.startsWith("@"))
78            return;
79        try {
80            _nucleus.routeAdd(new CellRoute(cell,
81                                             "*@"+domain,
82                                             CellRoute.WELLKNOWN));
83        } catch (IllegalArgumentException e) {
84            _log.warn("Couldn't add wellknown route : " + e.getMessage());
85        }
86    }
87 
88    private void removeWellknown(String cell, String domain)
89    {
90        if (cell.startsWith("@"))
91            return;
92        try {
93            _nucleus.routeDelete(new CellRoute(cell,
94                                                "*@"+domain,
95                                                CellRoute.WELLKNOWN));
96        } catch (IllegalArgumentException e) {
97            _log.warn("Couldn't delete wellknown route : " + e.getMessage());
98        }
99    }
100 
101    private synchronized void updateUpstream()
102    {
103        List<String> all = new ArrayList();
104        _log.info("update requested to upstream Domains");
105        //
106        // the protocol requires the local DomainName
107        // first
108        //
109        all.add(_nucleus.getCellDomainName());
110        //
111        // here we add our own exportables
112        //
113        all.addAll(_localExports);
114 
115        //
116        // and now all the others
117        //
118 
119        for (Set<String> cells : _domainHash.values()) {
120            all.addAll(cells);
121        }
122 
123        String destinationManager = _nucleus.getCellName();
124        _log.info("Resending to " + destinationManager + " : " + all);
125        try {
126            CellPath path = new CellPath(destinationManager);
127            String[] arr = all.toArray(new String[0]);
128            _nucleus.resendMessage(new CellMessage(path, arr));
129        } catch (NoRouteToCellException e) {
130            /* This normally happens when there is no default route.
131             */
132            _log.info("Cannot send routing information to RoutingMgr: " + e.getMessage());
133        }
134    }
135 
136    private synchronized void addRoutingInfo(String[] info)
137    {
138        String domain = info[0];
139        Set<String> oldCells = _domainHash.get(domain);
140        Set<String> newCells = new HashSet<String>();
141        for (int i = 1; i < info.length; i++){
142            newCells.add(info[i]);
143        }
144 
145        if (oldCells == null) {
146            _log.info("Adding new domain : " + domain);
147            for (String cell : newCells) {
148                addWellknown(cell, domain);
149            }
150        } else {
151            _log.info("Updating domain : " + domain);
152            for (String cell : newCells) {
153                _log.info("Adding : " + cell);
154                if (!oldCells.remove(cell)) {
155                    // entry not found, so make it
156                    addWellknown(cell, domain);
157                }
158            }
159            // all additional route added now, need to remove the rest
160            for (String cell : oldCells) {
161                _log.info("Removing : " + cell);
162                removeWellknown(cell, domain);
163            }
164        }
165        _domainHash.put(domain, newCells);
166        if (isDefaultInstalled())
167            updateUpstream();
168    }
169 
170    private synchronized void removeRoutingInfo(String domain)
171    {
172        _log.info("Removing all routes to domain : " + domain);
173        Set<String> cells = _domainHash.remove(domain);
174        if (cells == null){
175            _log.info("No entry found for domain : " + domain);
176            return;
177        }
178        for (String cell : cells)
179            removeWellknown(cell, domain);
180    }
181 
182    public void messageArrived(CellMessage msg)
183    {
184        Object obj = msg.getMessageObject();
185        if (obj instanceof String[]){
186            String[] info = (String[])obj;
187            if (info.length < 1){
188                _log.warn("Protocol error 1 in routing info");
189                return;
190            }
191            _log.info("Routing info arrived for Domain : " + info[0]);
192            addRoutingInfo(info);
193        } else {
194            _log.warn("Unidentified message ignored : " + obj);
195        }
196    }
197 
198    public void cellCreated(CellEvent ce)
199    {
200        String name = (String)ce.getSource();
201        _log.info("cellCreated : " + name);
202    }
203 
204    public synchronized void cellDied(CellEvent ce)
205    {
206        String name = (String) ce.getSource();
207        _log.info("cellDied : "+name);
208        _localExports.remove(name);
209        updateUpstream();
210    }
211 
212    public synchronized void cellExported(CellEvent ce)
213    {
214        String name = (String)ce.getSource();
215        _log.info("cellExported : " + name);
216        _localExports.add(name);
217        updateUpstream();
218    }
219 
220    public void routeAdded(CellEvent ce)
221    {
222        CellRoute       cr   = (CellRoute)ce.getSource();
223        CellAddressCore gate = new CellAddressCore(cr.getTargetName());
224        _log.info("Got 'route added' event : " + cr);
225        if (cr.getRouteType() == CellRoute.DOMAIN){
226            if ((_watchCell != null) && gate.getCellName().equals(_watchCell)) {
227                //
228                // the upstream route (we only support one)
229                //
230                try {
231                    CellRoute defRoute =
232                        new CellRoute("",
233                                       "*@"+cr.getDomainName(),
234                                       CellRoute.DEFAULT);
235                    _nucleus.routeAdd(defRoute);
236                } catch (IllegalArgumentException e) {
237                    _log.warn("Couldn't add default route : " + e.getMessage());
238                }
239            } else {
240                //
241                // possible downstream routes
242                //
243                // _log.info("Downstream route added : "+ cr);
244                _log.info("Downstream route added to Domain : " + cr.getDomainName());
245                //
246                // If the locationManager takes over control
247                // the default route may be installed before
248                // the actual domainRouted is added. Therefore
249                // we have to 'updateUpstream' for each route.
250                updateUpstream();
251            }
252        } else if (cr.getRouteType() == CellRoute.DEFAULT) {
253            _log.info("Default route was added");
254            setDefaultInstalled(true);
255            updateUpstream();
256        }
257    }
258 
259    public void routeDeleted(CellEvent ce)
260    {
261        CellRoute cr = (CellRoute)ce.getSource();
262        CellAddressCore gate = new CellAddressCore(cr.getTargetName());
263        if (cr.getRouteType() == CellRoute.DOMAIN) {
264            if ((_watchCell != null) && gate.getCellName().equals(_watchCell)) {
265                CellRoute defRoute =
266                    new CellRoute("",
267                                   "*@"+cr.getDomainName(),
268                                   CellRoute.DEFAULT);
269                _nucleus.routeDelete(defRoute);
270            } else {
271                removeRoutingInfo(cr.getDomainName());
272            }
273        } else if (cr.getRouteType() == CellRoute.DEFAULT) {
274            setDefaultInstalled(false);
275        }
276    }
277 
278    public String ac_update(Args args)
279    {
280        updateUpstream();
281        return "Done";
282    }
283 
284    /**
285     * This method returns the current state of the RoutingMgr cell as a (binary) Object.
286     * <p>
287     * NB. <b>This is a hack</b>.  The correct method of receiving information from a
288     * Cell is via a Vehicle.  However, as the RoutingMgr is within the cells module (which
289     * does not have the concept of Vehicles) this cannot be (easily) done.  Instead, we
290     * use the existing mechanism of obtaining a binary object via the admin interface and
291     * flag this functionality as something that should be improved later.
292     *
293     * @return a representation of the RoutingManager's little brain.
294     */
295    @Deprecated
296    public Object ac_ls_$_0( Args args) {
297 
298            Object info;
299 
300            if (args.getOpt("x") == null) {
301                    // Throw together some meaningful output.
302                    ByteArrayOutputStream os = new ByteArrayOutputStream();
303                    PrintWriter pw = new PrintWriter( os);
304                getInfo( pw);
305                pw.flush();
306                info = os.toString();
307        } else {
308                Object infoArray[] = new Object[3];
309 
310                infoArray[0] = _nucleus.getCellDomainName();
311                infoArray[1] = _localExports;
312                infoArray[2] = _domainHash;
313 
314                info = infoArray;
315        }
316 
317            return info;
318    }
319 
320    public String hh_ls = "[-x]";
321 
322}

[all classes][dmg.cells.services]
EMMA 2.0.5312 (C) Vladimir Roubtsov