NB API for packet count statistics. analytics.py demonstrates how to use it.
[affinity.git] / analytics / northbound / src / main / java / org / opendaylight / affinity / analytics / northbound / AnalyticsNorthbound.java
1 /*
2  * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.affinity.analytics.northbound;
10
11 import java.net.InetAddress;
12 import java.net.UnknownHostException;
13 import java.util.List;
14 import java.util.Set;
15 import java.util.Map;
16
17 import javax.ws.rs.GET;
18 import javax.ws.rs.Path;
19 import javax.ws.rs.PathParam;
20 import javax.ws.rs.Produces;
21 import javax.ws.rs.core.Context;
22 import javax.ws.rs.core.MediaType;
23 import javax.ws.rs.core.SecurityContext;
24
25 import org.codehaus.enunciate.jaxrs.ResponseCode;
26 import org.codehaus.enunciate.jaxrs.StatusCodes;
27 import org.codehaus.enunciate.jaxrs.TypeHint;
28
29 import org.opendaylight.affinity.affinity.AffinityLink;
30 import org.opendaylight.affinity.affinity.IAffinityManager;
31 import org.opendaylight.affinity.analytics.IAnalyticsManager;
32 import org.opendaylight.controller.containermanager.IContainerManager;
33 import org.opendaylight.controller.hosttracker.IfIptoHost;
34 import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
35 import org.opendaylight.controller.northbound.commons.RestMessages;
36 import org.opendaylight.controller.northbound.commons.exception.*;
37 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
38 import org.opendaylight.controller.sal.authorization.Privilege;
39 import org.opendaylight.controller.sal.core.Host;
40 import org.opendaylight.controller.sal.utils.GlobalConstants;
41 import org.opendaylight.controller.sal.utils.IPProtocols;
42 import org.opendaylight.controller.sal.utils.ServiceHelper;
43 import org.opendaylight.controller.switchmanager.ISwitchManager;
44
45 /**
46  * Northbound APIs that returns various Analytics exposed by the Southbound
47  * plugins such as Openflow.
48  *
49  * <br>
50  * <br>
51  * Authentication scheme : <b>HTTP Basic</b><br>
52  * Authentication realm : <b>opendaylight</b><br>
53  * Transport : <b>HTTP and HTTPS</b><br>
54  * <br>
55  * HTTPS Authentication is disabled by default. Administrator can enable it in
56  * tomcat-server.xml after adding a proper keystore / SSL certificate from a
57  * trusted authority.<br>
58  * More info :
59  * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
60  *
61  */
62 @Path("/")
63 public class AnalyticsNorthbound {
64
65     private String username;
66
67     @Context
68     public void setSecurityContext(SecurityContext context) {
69         username = context.getUserPrincipal().getName();
70     }
71
72     protected String getUserName() {
73         return username;
74     }
75
76     private IAnalyticsManager getAnalyticsService(String containerName) {
77         IContainerManager containerManager = (IContainerManager) ServiceHelper.getGlobalInstance(IContainerManager.class, this);
78         if (containerManager == null)
79             throw new ServiceUnavailableException("Container " + RestMessages.SERVICEUNAVAILABLE.toString());
80
81         boolean found = false;
82         List<String> containerNames = containerManager.getContainerNames();
83         for (String cName : containerNames)
84             if (cName.trim().equalsIgnoreCase(containerName.trim()))
85                 found = true;
86         if (found == false)
87             throw new ResourceNotFoundException(containerName + " " + RestMessages.NOCONTAINER.toString());
88
89         IAnalyticsManager analyticsManager = (IAnalyticsManager) ServiceHelper.getInstance(IAnalyticsManager.class, containerName, this);
90         if (analyticsManager == null)
91             throw new ServiceUnavailableException("Analytics " + RestMessages.SERVICEUNAVAILABLE.toString());
92         return analyticsManager;
93     }
94
95     /**
96      * @param containerName: Name of the Container
97      * @param dataLayerAddr: DataLayerAddress for the host
98      * @param networkAddr: NetworkAddress for the host
99      * @return Statistics for a (src, dst) pair.
100      */
101     @Path("/{containerName}/hoststats/{srcNetworkAddr}/{dstNetworkAddr}")
102     @GET
103     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
104     @TypeHint(Statistics.class)
105     @StatusCodes({
106             @ResponseCode(code = 200, condition = "Operation successful"),
107             @ResponseCode(code = 404, condition = "The containerName is not found"),
108             @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
109     public Statistics getHostStatistics(
110            @PathParam("containerName") String containerName,
111            @PathParam("srcNetworkAddr") String srcNetworkAddr,
112            @PathParam("dstNetworkAddr") String dstNetworkAddr) {
113         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this))
114             throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName);
115         handleDefaultDisabled(containerName);
116
117         IAnalyticsManager analyticsManager = getAnalyticsService(containerName);
118         if (analyticsManager == null)
119             throw new ServiceUnavailableException("Analytics " + RestMessages.SERVICEUNAVAILABLE.toString());
120
121         Host srcHost = handleHostAvailability(containerName, srcNetworkAddr);
122         Host dstHost = handleHostAvailability(containerName, dstNetworkAddr);
123         long byteCount = analyticsManager.getByteCount(srcHost, dstHost);
124         long packetCount = analyticsManager.getPacketCount(srcHost, dstHost);
125         double duration = analyticsManager.getDuration(srcHost, dstHost);
126         double bitRate = analyticsManager.getBitRate(srcHost, dstHost);
127
128         return new Statistics(byteCount, packetCount, duration, bitRate);
129     }
130
131     /**
132      * @param containerName: Name of the Container
133      * @param srcIP: Source IP
134      * @param dstIP: Destination IP
135      * @param protocol: IP protocol
136      * @return Statistics for a (src, dst) pair and a particular protocol
137      */
138     @Path("/{containerName}/hoststats/{srcIP}/{dstIP}/{protocol}")
139     @GET
140     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
141     @TypeHint(Statistics.class)
142     @StatusCodes({
143         @ResponseCode(code = 200, condition = "Operation successful"),
144         @ResponseCode(code = 404, condition = "The containerName is not found"),
145         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
146     public Statistics getHostStatistics(
147         @PathParam("containerName") String containerName,
148         @PathParam("srcIP") String srcIP,
149         @PathParam("dstIP") String dstIP,
150         @PathParam("protocol") String protocol) {
151         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this))
152             throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName);
153         handleDefaultDisabled(containerName);
154
155         IAnalyticsManager analyticsManager = getAnalyticsService(containerName);
156         if (analyticsManager == null)
157             throw new ServiceUnavailableException("Analytics " + RestMessages.SERVICEUNAVAILABLE.toString());
158
159         Host srcHost = handleHostAvailability(containerName, srcIP);
160         Host dstHost = handleHostAvailability(containerName, dstIP);
161         long byteCount = analyticsManager.getByteCount(srcHost, dstHost, IPProtocols.getProtocolNumberByte(protocol));
162         long packetCount = analyticsManager.getPacketCount(srcHost, dstHost, IPProtocols.getProtocolNumberByte(protocol));
163         double duration = analyticsManager.getDuration(srcHost, dstHost, IPProtocols.getProtocolNumberByte(protocol));
164         double bitRate = analyticsManager.getBitRate(srcHost, dstHost, IPProtocols.getProtocolNumberByte(protocol));
165
166         return new Statistics(byteCount, packetCount, duration, bitRate);
167     }
168
169     /**
170      * @param containerName: Name of the Container
171      * @param srcIP: Source IP
172      * @param dstIP: Destination IP
173      * @return All statistics for a (src, dst) pair
174      */
175     @Path("/{containerName}/hoststats/{srcIP}/{dstIP}/all")
176     @GET
177     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
178     @TypeHint(AllStatistics.class)
179     @StatusCodes({
180         @ResponseCode(code = 200, condition = "Operation successful"),
181         @ResponseCode(code = 404, condition = "The containerName is not found"),
182         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
183     public AllStatistics getAllHostStatistics(
184         @PathParam("containerName") String containerName,
185         @PathParam("srcIP") String srcIP,
186         @PathParam("dstIP") String dstIP) {
187         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this))
188             throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName);
189         handleDefaultDisabled(containerName);
190
191         IAnalyticsManager analyticsManager = getAnalyticsService(containerName);
192         if (analyticsManager == null)
193             throw new ServiceUnavailableException("Analytics " + RestMessages.SERVICEUNAVAILABLE.toString());
194
195         Host srcHost = handleHostAvailability(containerName, srcIP);
196         Host dstHost = handleHostAvailability(containerName, dstIP);
197         Map<Byte, Long> byteCounts = analyticsManager.getAllByteCounts(srcHost, dstHost);
198         Map<Byte, Long> packetCounts = analyticsManager.getAllPacketCounts(srcHost, dstHost);
199         Map<Byte, Double> durations = analyticsManager.getAllDurations(srcHost, dstHost);
200         Map<Byte, Double> bitRates = analyticsManager.getAllBitRates(srcHost, dstHost);
201         return new AllStatistics(byteCounts, packetCounts, durations, bitRates);
202     }
203
204     /**
205      * @param containerName: Name of the Container
206      * @param linkName: AffinityLink name
207      * @return Statistics for an affinity link
208      */
209     @Path("/{containerName}/affinitylinkstats/{linkName}")
210     @GET
211     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
212     @TypeHint(Statistics.class)
213     @StatusCodes({
214         @ResponseCode(code = 200, condition = "Operation successful"),
215         @ResponseCode(code = 404, condition = "The containerName is not found"),
216         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
217    public Statistics getAffinityLinkStatistics(
218         @PathParam("containerName") String containerName,
219         @PathParam("linkName") String affinityLinkName) {
220         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this))
221             throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName);
222         handleDefaultDisabled(containerName);
223
224         IAnalyticsManager analyticsManager = getAnalyticsService(containerName);
225         if (analyticsManager == null)
226             throw new ServiceUnavailableException("Analytics " + RestMessages.SERVICEUNAVAILABLE.toString());
227
228         AffinityLink al = handleAffinityLinkAvailability(containerName, affinityLinkName);
229         long byteCount = analyticsManager.getByteCount(al);
230         long packetCount = analyticsManager.getPacketCount(al);
231         double duration = analyticsManager.getDuration(al);
232         double bitRate = analyticsManager.getBitRate(al);
233
234         return new Statistics(byteCount, packetCount, duration, bitRate);
235     }
236
237     /**
238      * @param containerName: Name of the Container
239      * @param linkName: AffinityLink name
240      * @param protocol: IP Protocol
241      * @return Statistics for an affinity link and a particular protocol
242      */
243     @Path("/{containerName}/affinitylinkstats/{linkName}/{protocol}")
244     @GET
245     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
246     @TypeHint(Statistics.class)
247     @StatusCodes({
248         @ResponseCode(code = 200, condition = "Operation successful"),
249         @ResponseCode(code = 404, condition = "The containerName is not found"),
250         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
251     public Statistics getAffinityLinkStatistics(
252         @PathParam("containerName") String containerName,
253         @PathParam("linkName") String affinityLinkName,
254         @PathParam("protocol") String protocol) {
255         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this))
256             throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName);
257         handleDefaultDisabled(containerName);
258
259         IAnalyticsManager analyticsManager = getAnalyticsService(containerName);
260         if (analyticsManager == null)
261             throw new ServiceUnavailableException("Analytics " + RestMessages.SERVICEUNAVAILABLE.toString());
262
263         AffinityLink al = handleAffinityLinkAvailability(containerName, affinityLinkName);
264         long byteCount = analyticsManager.getByteCount(al, IPProtocols.getProtocolNumberByte(protocol));
265         long packetCount = analyticsManager.getPacketCount(al, IPProtocols.getProtocolNumberByte(protocol));
266         double duration = analyticsManager.getDuration(al, IPProtocols.getProtocolNumberByte(protocol));
267         double bitRate = analyticsManager.getBitRate(al, IPProtocols.getProtocolNumberByte(protocol));
268
269         return new Statistics(byteCount, packetCount, duration, bitRate);
270     }
271
272     /**
273      * @param containerName: Name of the Container
274      * @param linkName: AffinityLink name
275      * @return All statistics for an affinity link
276      */
277     @Path("/{containerName}/affinitylinkstats/{linkName}/all")
278     @GET
279     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
280     @TypeHint(AllStatistics.class)
281     @StatusCodes({
282         @ResponseCode(code = 200, condition = "Operation successful"),
283         @ResponseCode(code = 404, condition = "The containerName is not found"),
284         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
285     public AllStatistics getAllAffinityLinkStatistics(
286         @PathParam("containerName") String containerName,
287         @PathParam("linkName") String affinityLinkName) {
288         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this))
289             throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName);
290         handleDefaultDisabled(containerName);
291
292         IAnalyticsManager analyticsManager = getAnalyticsService(containerName);
293         if (analyticsManager == null)
294             throw new ServiceUnavailableException("Analytics " + RestMessages.SERVICEUNAVAILABLE.toString());
295
296         AffinityLink al = handleAffinityLinkAvailability(containerName, affinityLinkName);
297         Map<Byte, Long> byteCounts = analyticsManager.getAllByteCounts(al);
298         Map<Byte, Long> packetCounts = analyticsManager.getAllPacketCounts(al);
299         Map<Byte, Double> durations = analyticsManager.getAllDurations(al);
300         Map<Byte, Double> bitRates = analyticsManager.getAllBitRates(al);
301         return new AllStatistics(byteCounts, packetCounts, durations, bitRates);
302     }
303
304     /**
305      * @param containerName: Name of the Container
306      * @param srcIP: Source IP prefix
307      * @param srcMask: Source mask
308      * @param dstIP: Destination IP prefix
309      * @param dstMask: Destination mask
310      * @return Statistics between subnets
311      */
312     @Path("/{containerName}/subnetstats/{srcIP}/{srcMask}/{dstIP}/{dstMask}")
313     @GET
314     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
315     @TypeHint(Statistics.class)
316     @StatusCodes({
317         @ResponseCode(code = 200, condition = "Operation successful"),
318         @ResponseCode(code = 404, condition = "The containerName is not found"),
319         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
320     public Statistics getSubnetStatistics(
321         @PathParam("containerName") String containerName,
322         @PathParam("srcIP") String srcIP,
323         @PathParam("srcMask") String srcMask,
324         @PathParam("dstIP") String dstIP,
325         @PathParam("dstMask") String dstMask) {
326         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this))
327             throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName);
328         handleDefaultDisabled(containerName);
329
330         IAnalyticsManager analyticsManager = getAnalyticsService(containerName);
331         if (analyticsManager == null)
332             throw new ServiceUnavailableException("Analytics " + RestMessages.SERVICEUNAVAILABLE.toString());
333
334         String srcString = srcIP + "/" + srcMask;
335         String dstString = dstIP + "/" + dstMask;
336         // TODO: This is hardly the most elegant way to handle null prefixes
337         if (srcString.equals("null/null"))
338             srcString = null;
339         if (dstString.equals("null/null"))
340             dstString = null;
341         long byteCount = analyticsManager.getByteCount(srcString, dstString);
342         long packetCount = analyticsManager.getPacketCount(srcString, dstString);
343         double duration = analyticsManager.getDuration(srcString, dstString);
344         double bitRate = analyticsManager.getBitRate(srcString, dstString);
345
346         return new Statistics(byteCount, packetCount, duration, bitRate);
347     }
348
349     /**
350      * @param containerName: Name of the Container
351      * @param srcIP: Source IP prefix
352      * @param srcMask: Source mask
353      * @param dstIP: Destination IP prefix
354      * @param dstMask: Destination mask
355      * @param protocol: IP protocol
356      * @return Statistics between subnets for a particular protocol
357      */
358     @Path("/{containerName}/subnetstats/{srcIP}/{srcMask}/{dstIP}/{dstMask}/{protocol}")
359     @GET
360     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
361     @TypeHint(Statistics.class)
362     @StatusCodes({
363         @ResponseCode(code = 200, condition = "Operation successful"),
364         @ResponseCode(code = 404, condition = "The containerName is not found"),
365         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
366     public Statistics getSubnetStatistics(
367         @PathParam("containerName") String containerName,
368         @PathParam("srcIP") String srcIP,
369         @PathParam("srcMask") String srcMask,
370         @PathParam("dstIP") String dstIP,
371         @PathParam("dstMask") String dstMask,
372         @PathParam("protocol") String protocol) {
373         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this))
374             throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName);
375         handleDefaultDisabled(containerName);
376
377         IAnalyticsManager analyticsManager = getAnalyticsService(containerName);
378         if (analyticsManager == null)
379             throw new ServiceUnavailableException("Analytics " + RestMessages.SERVICEUNAVAILABLE.toString());
380
381         String srcString = srcIP + "/" + srcMask;
382         String dstString = dstIP + "/" + dstMask;
383         // TODO: This is hardly the most elegant way to handle null prefixes
384         if (srcString.equals("null/null"))
385             srcString = null;
386         if (dstString.equals("null/null"))
387             dstString = null;
388         long byteCount = analyticsManager.getByteCount(srcString, dstString, IPProtocols.getProtocolNumberByte(protocol));
389         long packetCount = analyticsManager.getByteCount(srcString, dstString, IPProtocols.getProtocolNumberByte(protocol));
390         double duration = analyticsManager.getDuration(srcString, dstString, IPProtocols.getProtocolNumberByte(protocol));
391         double bitRate = analyticsManager.getBitRate(srcString, dstString, IPProtocols.getProtocolNumberByte(protocol));
392
393         return new Statistics(byteCount, packetCount, duration, bitRate);
394     }
395
396     /**
397      * @param containerName: Name of the Container
398      * @param srcIP: Source IP prefix
399      * @param srcMask: Source mask
400      * @param dstIP: Destination IP prefix
401      * @param dstMask: Destination mask
402      * @return Statistics between subnets for a particular protocol
403      */
404     @Path("/{containerName}/subnetstats/{srcIP}/{srcMask}/{dstIP}/{dstMask}/all")
405     @GET
406     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
407     @TypeHint(AllStatistics.class)
408     @StatusCodes({
409         @ResponseCode(code = 200, condition = "Operation successful"),
410         @ResponseCode(code = 404, condition = "The containerName is not found"),
411         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
412     public AllStatistics getAllSubnetStatistics(
413         @PathParam("containerName") String containerName,
414         @PathParam("srcIP") String srcIP,
415         @PathParam("srcMask") String srcMask,
416         @PathParam("dstIP") String dstIP,
417         @PathParam("dstMask") String dstMask) {
418         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this))
419             throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName);
420         handleDefaultDisabled(containerName);
421
422         IAnalyticsManager analyticsManager = getAnalyticsService(containerName);
423         if (analyticsManager == null)
424             throw new ServiceUnavailableException("Analytics " + RestMessages.SERVICEUNAVAILABLE.toString());
425
426         String srcString = srcIP + "/" + srcMask;
427         String dstString = dstIP + "/" + dstMask;
428         // TODO: This is hardly the most elegant way to handle null prefixes
429         if (srcString.equals("null/null"))
430             srcString = null;
431         if (dstString.equals("null/null"))
432             dstString = null;
433
434         Map<Byte, Long> byteCounts = analyticsManager.getAllByteCounts(srcString, dstString);
435         Map<Byte, Long> packetCounts = analyticsManager.getAllPacketCounts(srcString, dstString);
436         Map<Byte, Double> durations = analyticsManager.getAllDurations(srcString, dstString);
437         Map<Byte, Double> bitRates = analyticsManager.getAllBitRates(srcString, dstString);
438         return new AllStatistics(byteCounts, packetCounts, durations, bitRates);
439     }
440
441     /**
442      * @param containerName: Name of the Container
443      * @param ip: IP prefix
444      * @param mask: Mask
445      * @return Hosts that sent data into this subnet
446      */
447     @Path("/{containerName}/subnetstats/incoming/{ip}/{mask}/")
448     @GET
449     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
450     @TypeHint(IncomingHostData.class)
451     @StatusCodes({
452         @ResponseCode(code = 200, condition = "Operation successful"),
453         @ResponseCode(code = 404, condition = "The containerName is not found"),
454         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
455     public IncomingHostData getIncomingHostByteCounts(
456         @PathParam("containerName") String containerName,
457         @PathParam("ip") String ip,
458         @PathParam("mask") String mask) {
459         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this))
460             throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName);
461         handleDefaultDisabled(containerName);
462
463         IAnalyticsManager analyticsManager = getAnalyticsService(containerName);
464         if (analyticsManager == null)
465             throw new ServiceUnavailableException("Analytics " + RestMessages.SERVICEUNAVAILABLE.toString());
466
467         Map<Host, Long> hosts = analyticsManager.getIncomingHostByteCounts(ip + "/" + mask);
468         return new IncomingHostData(hosts);
469     }
470
471     /**
472      * @param containerName: Name of the Container
473      * @param ip: IP prefix
474      * @param mask: Mask
475      * @param protocol: IP protocol
476      * @return Hosts that sent data into this subnet using this protocol
477      */
478     @Path("/{containerName}/subnetstats/incoming/{ip}/{mask}/{protocol}")
479     @GET
480     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
481     @TypeHint(IncomingHostData.class)
482     @StatusCodes({
483         @ResponseCode(code = 200, condition = "Operation successful"),
484         @ResponseCode(code = 404, condition = "The containerName is not found"),
485         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
486     public IncomingHostData getIncomingHostByteCounts(
487         @PathParam("containerName") String containerName,
488         @PathParam("ip") String ip,
489         @PathParam("mask") String mask,
490         @PathParam("protocol") String protocol) {
491         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this))
492             throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName);
493         handleDefaultDisabled(containerName);
494
495         IAnalyticsManager analyticsManager = getAnalyticsService(containerName);
496         if (analyticsManager == null)
497             throw new ServiceUnavailableException("Analytics " + RestMessages.SERVICEUNAVAILABLE.toString());
498
499         Map<Host, Long> hosts = analyticsManager.getIncomingHostByteCounts(ip + "/" + mask, IPProtocols.getProtocolNumberByte(protocol));
500         return new IncomingHostData(hosts);
501     }
502
503     private void handleDefaultDisabled(String containerName) {
504         IContainerManager containerManager = (IContainerManager) ServiceHelper.getGlobalInstance(IContainerManager.class, this);
505         if (containerManager == null)
506             throw new InternalServerErrorException(RestMessages.INTERNALERROR.toString());
507         if (containerName.equals(GlobalConstants.DEFAULT.toString()) && containerManager.hasNonDefaultContainer())
508             throw new ResourceConflictException(RestMessages.DEFAULTDISABLED.toString());
509     }
510
511     private AffinityLink handleAffinityLinkAvailability(String containerName, String linkName) {
512         IAffinityManager affinityManager = (IAffinityManager) ServiceHelper.getInstance(IAffinityManager.class, containerName, this);
513         if (affinityManager == null)
514             throw new ServiceUnavailableException("Affinity manager " + RestMessages.SERVICEUNAVAILABLE.toString());
515         AffinityLink al = affinityManager.getAffinityLink(linkName);
516         if (al == null)
517             throw new ResourceNotFoundException(linkName + " : AffinityLink does not exist");
518         return al;
519     }
520
521
522     private Host handleHostAvailability(String containerName, String networkAddr) {
523         IfIptoHost hostTracker = (IfIptoHost) ServiceHelper.getInstance(IfIptoHost.class, containerName, this);
524         if (hostTracker == null)
525             throw new ServiceUnavailableException("Host tracker " + RestMessages.SERVICEUNAVAILABLE.toString());
526
527         Set<HostNodeConnector> allHosts = hostTracker.getAllHosts();
528         if (allHosts == null)
529             throw new ResourceNotFoundException(networkAddr + " : " + RestMessages.NOHOST.toString());
530
531         Host host = null;
532         try {
533             InetAddress networkAddress = InetAddress.getByName(networkAddr);
534             for (Host h : allHosts) {
535                 if (h.getNetworkAddress().equals(networkAddress)) {
536                     host = h;
537                     break;
538                 }
539             }
540         } catch (UnknownHostException e) {
541         }
542
543         if (host == null)
544             throw new ResourceNotFoundException(networkAddr + " : " + RestMessages.NOHOST.toString());
545         return host;
546     }
547 }