3769cc7818e8e2268dc0f1a11f07cad8f5103ff8
[controller.git] / opendaylight / adsal / northbound / hosttracker / src / main / java / org / opendaylight / controller / hosttracker / northbound / HostTrackerNorthbound.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, 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.controller.hosttracker.northbound;
10
11 import java.net.InetAddress;
12 import java.net.UnknownHostException;
13 import java.util.HashSet;
14 import java.util.List;
15 import java.util.Set;
16
17 import javax.ws.rs.Consumes;
18 import javax.ws.rs.DELETE;
19 import javax.ws.rs.GET;
20 import javax.ws.rs.PUT;
21 import javax.ws.rs.Path;
22 import javax.ws.rs.PathParam;
23 import javax.ws.rs.Produces;
24 import javax.ws.rs.QueryParam;
25 import javax.ws.rs.core.Context;
26 import javax.ws.rs.core.MediaType;
27 import javax.ws.rs.core.Response;
28 import javax.ws.rs.core.SecurityContext;
29 import javax.ws.rs.core.UriInfo;
30 import javax.ws.rs.ext.ContextResolver;
31
32 import org.codehaus.enunciate.jaxrs.ResponseCode;
33 import org.codehaus.enunciate.jaxrs.StatusCodes;
34 import org.codehaus.enunciate.jaxrs.TypeHint;
35 import org.opendaylight.controller.containermanager.IContainerManager;
36 import org.opendaylight.controller.hosttracker.IfIptoHost;
37 import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
38 import org.opendaylight.controller.northbound.commons.RestMessages;
39 import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
40 import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
41 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
42 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
43 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
44 import org.opendaylight.controller.northbound.commons.query.QueryContext;
45 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
46 import org.opendaylight.controller.sal.authorization.Privilege;
47 import org.opendaylight.controller.sal.core.Node;
48 import org.opendaylight.controller.sal.core.NodeConnector;
49 import org.opendaylight.controller.sal.utils.GlobalConstants;
50 import org.opendaylight.controller.sal.utils.ServiceHelper;
51 import org.opendaylight.controller.sal.utils.Status;
52 import org.opendaylight.controller.switchmanager.ISwitchManager;
53
54 /**
55  * Host Tracker Northbound REST APIs.<br>
56  * This class provides REST APIs to track host location in a network. Host
57  * Location is represented by Host node connector which is essentially a logical
58  * entity that represents a Switch/Port. A host is represented by it's
59  * IP-address and mac-address.
60  *
61  * <br>
62  * <br>
63  * Authentication scheme : <b>HTTP Basic</b><br>
64  * Authentication realm : <b>opendaylight</b><br>
65  * Transport : <b>HTTP and HTTPS</b><br>
66  * <br>
67  * HTTPS Authentication is disabled by default.
68  *
69  */
70
71 @Path("/")
72 public class HostTrackerNorthbound {
73
74     private String username;
75     private QueryContext queryContext;
76
77     @Context
78     public void setQueryContext(ContextResolver<QueryContext> queryCtxResolver) {
79       if (queryCtxResolver != null) {
80         queryContext = queryCtxResolver.getContext(QueryContext.class);
81       }
82     }
83
84     @Context
85     public void setSecurityContext(SecurityContext context) {
86         if (context != null && context.getUserPrincipal() != null) {
87             username = context.getUserPrincipal().getName();
88         }
89     }
90
91     protected String getUserName() {
92         return username;
93     }
94
95     private IfIptoHost getIfIpToHostService(String containerName) {
96         IContainerManager containerManager = (IContainerManager) ServiceHelper.getGlobalInstance(
97                 IContainerManager.class, this);
98         if (containerManager == null) {
99             throw new ServiceUnavailableException("Container " + RestMessages.SERVICEUNAVAILABLE.toString());
100         }
101
102         boolean found = false;
103         List<String> containerNames = containerManager.getContainerNames();
104         for (String cName : containerNames) {
105             if (cName.trim().equalsIgnoreCase(containerName.trim())) {
106                 found = true;
107                 break;
108             }
109         }
110
111         if (!found) {
112             throw new ResourceNotFoundException(containerName + " " + RestMessages.NOCONTAINER.toString());
113         }
114
115         IfIptoHost hostTracker = (IfIptoHost) ServiceHelper.getInstance(IfIptoHost.class, containerName, this);
116         if (hostTracker == null) {
117             throw new ServiceUnavailableException("Host Tracker " + RestMessages.SERVICEUNAVAILABLE.toString());
118         }
119
120         return hostTracker;
121     }
122
123     private Set<HostConfig> convertHosts(Set<HostNodeConnector> hostNodeConnectors) {
124         if(hostNodeConnectors == null) {
125             return null;
126         }
127         Set<HostConfig> hosts = new HashSet<HostConfig>();
128         for(HostNodeConnector hnc : hostNodeConnectors) {
129             hosts.add(HostConfig.convert(hnc));
130         }
131         return hosts;
132     }
133
134     /**
135      * Returns a list of all Hosts : both configured via PUT API and dynamically
136      * learnt on the network.
137      *
138      * @param containerName
139      *            Name of the Container. The Container name for the base
140      *            controller is "default".
141      * @return List of Active Hosts.
142      * <pre>
143      *
144      * Example:
145      *
146      * Request URL:
147      * http://localhost:8080/controller/nb/v2/hosttracker/default/hosts/active
148      *
149      * Response body in XML
150      *
151      * &lt;list&gt;
152      * &#x20;&lt;hostConfig&gt;
153      * &#x20;&#x20;&lt;dataLayerAddress&gt;00:00:00:00:01:01&lt;/dataLayerAddress&gt;
154      * &#x20;&#x20;&lt;networkAddress&gt;1.1.1.1&lt;/networkAddress&gt;
155      * &#x20;&#x20;&lt;nodeType&gt;OF&lt;/nodeType&gt;
156      * &#x20;&#x20;&lt;nodeId&gt;00:00:00:00:00:00:00:01&lt;/nodeId&gt;
157      * &#x20;&#x20;&lt;nodeConnectorType&gt;OF&lt;/nodeConnectorType&gt;
158      * &#x20;&#x20;&lt;nodeConnectorId&gt;9&lt;/nodeConnectorId&gt;
159      * &#x20;&#x20;&lt;vlan&gt;0&lt;/vlan&gt;
160      * &#x20;&#x20;&lt;staticHost&gt;false&lt;/staticHost&gt;
161      * &#x20;&lt;/hostConfig&gt;
162      * &#x20;&lt;hostConfig&gt;
163      * &#x20;&#x20;&lt;dataLayerAddress&gt;00:00:00:00:02:02&lt;/dataLayerAddress&gt;
164      * &#x20;&#x20;&lt;networkAddress&gt;2.2.2.2&lt;/networkAddress&gt;
165      * &#x20;&#x20;&lt;nodeType&gt;OF&lt;/nodeType&gt;
166      * &#x20;&#x20;&lt;nodeId&gt;00:00:00:00:00:00:00:02&lt;/nodeId&gt;
167      * &#x20;&#x20;&lt;nodeConnectorType&gt;OF&lt;/nodeConnectorType&gt;
168      * &#x20;&#x20;&lt;nodeConnectorId&gt;5&lt;/nodeConnectorId&gt;
169      * &#x20;&#x20;&lt;vlan&gt;0&lt;/vlan&gt;
170      * &#x20;&#x20;&lt;staticHost&gt;false&lt;/staticHost&gt;
171      * &#x20;&lt;/hostConfig&gt;
172      * &lt;/list&gt;
173      *
174      * Response body in JSON:
175      *
176      * {
177      * &#x20;"hostConfig":[
178      * &#x20;&#x20;{
179      * &#x20;&#x20;&#x20;"dataLayerAddress":"00:00:00:00:01:01",
180      * &#x20;&#x20;&#x20;"nodeType":"OF",
181      * &#x20;&#x20;&#x20;"nodeId":"00:00:00:00:00:00:00:01",
182      * &#x20;&#x20;&#x20;"nodeConnectorType":"OF",
183      * &#x20;&#x20;&#x20;"nodeConnectorId":"9",
184      * &#x20;&#x20;&#x20;"vlan":"0",
185      * &#x20;&#x20;&#x20;"staticHost":"false",
186      * &#x20;&#x20;&#x20;"networkAddress":"1.1.1.1"
187      * &#x20;&#x20;},
188      * &#x20;&#x20;{
189      * &#x20;&#x20;&#x20;"dataLayerAddress":"00:00:00:00:02:02",
190      * &#x20;&#x20;&#x20;"nodeType":"OF",
191      * &#x20;&#x20;&#x20;"nodeId":"00:00:00:00:00:00:00:02",
192      * &#x20;&#x20;&#x20;"nodeConnectorType":"OF",
193      * &#x20;&#x20;&#x20;"nodeConnectorId":"5",
194      * &#x20;&#x20;&#x20;"vlan":"0",
195      * &#x20;&#x20;&#x20;"staticHost":"false",
196      * &#x20;&#x20;&#x20;"networkAddress":"2.2.2.2"
197      * &#x20;&#x20;}
198      * &#x20;]
199      * }
200      * </pre>
201      */
202     @Path("/{containerName}/hosts/active")
203     @GET
204     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
205     @TypeHint(Hosts.class)
206     @StatusCodes({
207             @ResponseCode(code = 200, condition = "Operation successful"),
208             @ResponseCode(code = 404, condition = "The containerName is not found"),
209             @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
210     public Hosts getActiveHosts(@PathParam("containerName") String containerName,
211         @QueryParam("_q") String queryString) {
212
213         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
214             throw new UnauthorizedException("User is not authorized to perform this operation on container "
215                     + containerName);
216         }
217         IfIptoHost hostTracker = getIfIpToHostService(containerName);
218         Hosts hosts = new Hosts(convertHosts(hostTracker.getAllHosts()));
219         if (queryString != null) {
220             queryContext.createQuery(queryString, Hosts.class)
221                 .filter(hosts, HostConfig.class);
222         }
223         return hosts;
224     }
225
226     /**
227      * Returns a list of Hosts that are statically configured and are connected
228      * to a NodeConnector that is down.
229      *
230      * @param containerName
231      *            Name of the Container. The Container name for the base
232      *            controller is "default".
233      * @return List of inactive Hosts.
234      * <pre>
235      *
236      * Example:
237      *
238      * Request URL:
239      * http://localhost:8080/controller/nb/v2/hosttracker/default/hosts/inactive
240      *
241      * Response body in XML
242      *
243      * &lt;list&gt;
244      * &#x20;&lt;hostConfig&gt;
245      * &#x20;&#x20;&lt;dataLayerAddress&gt;00:00:00:00:01:01&lt;/dataLayerAddress&gt;
246      * &#x20;&#x20;&lt;networkAddress&gt;1.1.1.1&lt;/networkAddress&gt;
247      * &#x20;&#x20;&lt;nodeType&gt;OF&lt;/nodeType&gt;
248      * &#x20;&#x20;&lt;nodeId&gt;00:00:00:00:00:00:00:01&lt;/nodeId&gt;
249      * &#x20;&#x20;&lt;nodeConnectorType&gt;OF&lt;/nodeConnectorType&gt;
250      * &#x20;&#x20;&lt;nodeConnectorId&gt;9&lt;/nodeConnectorId&gt;
251      * &#x20;&#x20;&lt;vlan&gt;0&lt;/vlan&gt;
252      * &#x20;&#x20;&lt;staticHost&gt;false&lt;/staticHost&gt;
253      * &#x20;&lt;/hostConfig&gt;
254      * &#x20;&lt;hostConfig&gt;
255      * &#x20;&#x20;&lt;dataLayerAddress&gt;00:00:00:00:02:02&lt;/dataLayerAddress&gt;
256      * &#x20;&#x20;&lt;networkAddress&gt;2.2.2.2&lt;/networkAddress&gt;
257      * &#x20;&#x20;&lt;nodeType&gt;OF&lt;/nodeType&gt;
258      * &#x20;&#x20;&lt;nodeId&gt;00:00:00:00:00:00:00:02&lt;/nodeId&gt;
259      * &#x20;&#x20;&lt;nodeConnectorType&gt;OF&lt;/nodeConnectorType&gt;
260      * &#x20;&#x20;&lt;nodeConnectorId&gt;5&lt;/nodeConnectorId&gt;
261      * &#x20;&#x20;&lt;vlan&gt;0&lt;/vlan&gt;
262      * &#x20;&#x20;&lt;staticHost&gt;false&lt;/staticHost&gt;
263      * &#x20;&lt;/hostConfig&gt;
264      * &lt;/list&gt;
265      *
266      * Response body in JSON:
267      *
268      * {
269      * &#x20;"hostConfig":[
270      * &#x20;&#x20;{
271      * &#x20;&#x20;&#x20;"dataLayerAddress":"00:00:00:00:01:01",
272      * &#x20;&#x20;&#x20;"nodeType":"OF",
273      * &#x20;&#x20;&#x20;"nodeId":"00:00:00:00:00:00:00:01",
274      * &#x20;&#x20;&#x20;"nodeConnectorType":"OF",
275      * &#x20;&#x20;&#x20;"nodeConnectorId":"9",
276      * &#x20;&#x20;&#x20;"vlan":"0",
277      * &#x20;&#x20;&#x20;"staticHost":"false",
278      * &#x20;&#x20;&#x20;"networkAddress":"1.1.1.1"
279      * &#x20;&#x20;},
280      * &#x20;&#x20;{
281      * &#x20;&#x20;&#x20;"dataLayerAddress":"00:00:00:00:02:02",
282      * &#x20;&#x20;&#x20;"nodeType":"OF",
283      * &#x20;&#x20;&#x20;"nodeId":"00:00:00:00:00:00:00:02",
284      * &#x20;&#x20;&#x20;"nodeConnectorType":"OF",
285      * &#x20;&#x20;&#x20;"nodeConnectorId":"5",
286      * &#x20;&#x20;&#x20;"vlan":"0",
287      * &#x20;&#x20;&#x20;"staticHost":"false",
288      * &#x20;&#x20;&#x20;"networkAddress":"2.2.2.2"
289      * &#x20;&#x20;}
290      * &#x20;]
291      * }
292      * </pre>
293      */
294     @Path("/{containerName}/hosts/inactive")
295     @GET
296     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
297     @TypeHint(Hosts.class)
298     @StatusCodes({
299             @ResponseCode(code = 200, condition = "Operation successful"),
300             @ResponseCode(code = 404, condition = "The containerName is not found"),
301             @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
302     public Hosts getInactiveHosts(
303             @PathParam("containerName") String containerName,
304             @QueryParam("_q") String queryString) {
305         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
306             throw new UnauthorizedException("User is not authorized to perform this operation on container "
307                     + containerName);
308         }
309         IfIptoHost hostTracker = getIfIpToHostService(containerName);
310         Hosts hosts = new Hosts(convertHosts(hostTracker.getInactiveStaticHosts()));
311         if (queryString != null) {
312             queryContext.createQuery(queryString, Hosts.class)
313                 .filter(hosts, HostConfig.class);
314         }
315         return hosts;
316     }
317
318     /**
319      * Returns a host that matches the IP Address value passed as parameter.
320      *
321      * @param containerName
322      *            Name of the Container. The Container name for the base
323      *            controller is "default".
324      * @param networkAddress
325      *            IP Address being looked up
326      * @return host that matches the IP Address
327      * <pre>
328      *
329      * Example:
330      *
331      * Request URL:
332      * http://localhost:8080/controller/nb/v2/hosttracker/default/address/1.1.1.1
333      *
334      * Response body in XML
335      *
336      * &lt;hostConfig&gt;
337      * &#x20;&lt;dataLayerAddress&gt;00:00:00:00:01:01&lt;/dataLayerAddress&gt;
338      * &#x20;&lt;networkAddress&gt;1.1.1.1&lt;/networkAddress&gt;
339      * &#x20;&lt;nodeType&gt;OF&lt;/nodeType&gt;
340      * &#x20;&lt;nodeId&gt;00:00:00:00:00:00:00:01&lt;/nodeId&gt;
341      * &#x20;&lt;nodeConnectorType&gt;OF&lt;/nodeConnectorType&gt;
342      * &#x20;&lt;nodeConnectorId&gt;9&lt;/nodeConnectorId&gt;
343      * &#x20;&lt;vlan&gt;0&lt;/vlan&gt;
344      * &#x20;&lt;staticHost&gt;false&lt;/staticHost&gt;
345      * &lt;/hostConfig&gt;
346      *
347      * Response body in JSON:
348      *
349      * {
350      * &#x20;"dataLayerAddress":"00:00:00:00:01:01",
351      * &#x20;"nodeType":"OF",
352      * &#x20;"nodeId":"00:00:00:00:00:00:00:01",
353      * &#x20;"nodeConnectorType":"OF",
354      * &#x20;"nodeConnectorId":"9",
355      * &#x20;"vlan":"0",
356      * &#x20;"staticHost":"false",
357      * &#x20;"networkAddress":"1.1.1.1"
358      * }
359      * </pre>
360      */
361     @Path("/{containerName}/address/{networkAddress}")
362     @GET
363     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
364     @TypeHint(HostConfig.class)
365     @StatusCodes({
366             @ResponseCode(code = 200, condition = "Operation successful"),
367             @ResponseCode(code = 400, condition = "Invalid IP specified in networkAddress parameter"),
368             @ResponseCode(code = 404, condition = "The containerName is not found"),
369             @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
370     public HostConfig getHostDetails(
371             @PathParam("containerName") String containerName,
372             @PathParam("networkAddress") String networkAddress) {
373         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
374             throw new UnauthorizedException("User is not authorized to perform this operation on container "
375                     + containerName);
376         }
377         IfIptoHost hostTracker = getIfIpToHostService(containerName);
378
379         InetAddress ip;
380         try {
381             ip = InetAddress.getByName(networkAddress);
382         } catch (UnknownHostException e) {
383             throw new BadRequestException(RestMessages.INVALIDADDRESS.toString() + " " + networkAddress);
384         }
385         for (HostNodeConnector host : hostTracker.getAllHosts()) {
386             if (host.getNetworkAddress().equals(ip)) {
387                 return HostConfig.convert(host);
388             }
389         }
390         throw new ResourceNotFoundException(RestMessages.NOHOST.toString());
391     }
392
393     /**
394      * Add a Static Host configuration. If a host by the given address already
395      * exists, this method will respond with a non-successful status response.
396      *
397      * @param containerName
398      *            Name of the Container. The Container name for the base
399      *            controller is "default".
400      * @param networkAddress
401      *            Host IP Address
402      * @param hostConfig
403      *            Host Config Details
404      * @return Response as dictated by the HTTP Response Status code
405      *
406      * <pre>
407      *
408      * Example:
409      *
410      * Request URL:
411      * http://localhost:8080/controller/nb/v2/hosttracker/default/address/1.1.1.1
412      *
413      * Request body in XML
414      *
415      * &lt;hostConfig&gt;
416      * &#x20;&lt;dataLayerAddress&gt;00:00:00:00:01:01&lt;/dataLayerAddress&gt;
417      * &#x20;&lt;networkAddress&gt;1.1.1.1&lt;/networkAddress&gt;
418      * &#x20;&lt;nodeType&gt;OF&lt;/nodeType&gt;
419      * &#x20;&lt;nodeId&gt;00:00:00:00:00:00:00:01&lt;/nodeId&gt;
420      * &#x20;&lt;nodeConnectorType&gt;OF&lt;/nodeConnectorType&gt;
421      * &#x20;&lt;nodeConnectorId&gt;9&lt;/nodeConnectorId&gt;
422      * &#x20;&lt;vlan&gt;1&lt;/vlan&gt;
423      * &#x20;&lt;staticHost&gt;true&lt;/staticHost&gt;
424      * &lt;/hostConfig&gt;
425      *
426      * Request body in JSON:
427      *
428      * {
429      * &#x20;"dataLayerAddress":"00:00:00:00:01:01",
430      * &#x20;"nodeType":"OF",
431      * &#x20;"nodeId":"00:00:00:00:00:00:00:01",
432      * &#x20;"nodeConnectorType":"OF",
433      * &#x20;"nodeConnectorId":"9",
434      * &#x20;"vlan":"1",
435      * &#x20;"staticHost":"true",
436      * &#x20;"networkAddress":"1.1.1.1"
437      * }
438      * </pre>
439      */
440
441     @Path("/{containerName}/address/{networkAddress}")
442     @PUT
443     @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
444     @StatusCodes({
445             @ResponseCode(code = 201, condition = "Static host created successfully"),
446             @ResponseCode(code = 400, condition = "Invalid parameters specified, see response body for details"),
447             @ResponseCode(code = 404, condition = "The container or resource is not found"),
448             @ResponseCode(code = 409, condition = "Resource conflict, see response body for details"),
449             @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
450     public Response addHost(@Context UriInfo uriInfo, @PathParam("containerName") String containerName,
451             @PathParam("networkAddress") String networkAddress,
452             @TypeHint(HostConfig.class) HostConfig hostConfig) {
453
454         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
455             return Response.status(Response.Status.UNAUTHORIZED)
456                     .entity("User is not authorized to perform this operation on container " + containerName)
457                     .build();
458         }
459         handleDefaultDisabled(containerName);
460
461         IfIptoHost hostTracker = getIfIpToHostService(containerName);
462
463         HostConfig hc = hostConfig;
464         if (!networkAddress.equals(hc.getNetworkAddress())) {
465             return Response.status(Response.Status.CONFLICT)
466                     .entity("Resource name in config object doesn't match URI")
467                     .build();
468         }
469         if (!hc.isStaticHost()) {
470             return Response.status(Response.Status.BAD_REQUEST)
471                     .entity("Can only add static host.")
472                     .build();
473         }
474         Node node = handleNodeAvailability(containerName, hc.getNodeType(), hc.getNodeId());
475         NodeConnector nc = NodeConnector.fromStringNoNode(hc.getNodeConnectorType(), hc.getNodeConnectorId(), node);
476
477         Status status = hostTracker.addStaticHost(networkAddress, hc.getDataLayerAddress(), nc, hc.getVlan());
478         if (status.isSuccess()) {
479             NorthboundUtils.auditlog("Static Host", username, "added", networkAddress, containerName);
480             return Response.created(uriInfo.getRequestUri()).build();
481         }
482
483         return NorthboundUtils.getResponse(status);
484     }
485
486     /**
487      * Delete a Static Host configuration
488      *
489      * @param containerName
490      *            Name of the Container. The Container name for the base
491      *            controller is "default".
492      * @param networkAddress
493      *            IP Address
494      * @return Response as dictated by the HTTP Response code.
495      *
496      * Example:
497      *
498      * Request URL:
499      * http://localhost:8080/controller/nb/v2/hosttracker/default/address/1.1.1.1
500      *
501      */
502
503     @Path("/{containerName}/address/{networkAddress}")
504     @DELETE
505     @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
506     @StatusCodes({
507             @ResponseCode(code = 204, condition = "Static host deleted successfully"),
508             @ResponseCode(code = 404, condition = "The container or a specified resource was not found"),
509             @ResponseCode(code = 406, condition = "Cannot operate on Default Container when other Containers are active"),
510             @ResponseCode(code = 503, condition = "One or more of Controller service is unavailable") })
511     public Response deleteHost(
512             @PathParam(value = "containerName") String containerName,
513             @PathParam(value = "networkAddress") String networkAddress) {
514
515         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
516             return Response.status(Response.Status.UNAUTHORIZED)
517                     .entity("User is not authorized to perform this operation on container " + containerName)
518                     .build();
519         }
520         handleDefaultDisabled(containerName);
521         IfIptoHost hostTracker = getIfIpToHostService(containerName);
522
523         Status status = hostTracker.removeStaticHost(networkAddress);
524         if (status.isSuccess()) {
525             NorthboundUtils.auditlog("Static Host", username, "removed", networkAddress, containerName);
526             return Response.noContent().build();
527         }
528         return NorthboundUtils.getResponse(status);
529
530     }
531
532     private void handleDefaultDisabled(String containerName) {
533         IContainerManager containerManager = (IContainerManager) ServiceHelper
534                 .getGlobalInstance(IContainerManager.class, this);
535         if (containerManager == null) {
536             throw new ServiceUnavailableException(
537                     RestMessages.SERVICEUNAVAILABLE.toString());
538         }
539         if (containerName.equals(GlobalConstants.DEFAULT.toString())
540                 && containerManager.hasNonDefaultContainer()) {
541             throw new ResourceConflictException(
542                     RestMessages.DEFAULTDISABLED.toString());
543         }
544     }
545
546     private Node handleNodeAvailability(String containerName, String nodeType, String nodeId) {
547
548         Node node = Node.fromString(nodeType, nodeId);
549         if (node == null) {
550             throw new ResourceNotFoundException(nodeId + " : "
551                     + RestMessages.NONODE.toString());
552         }
553
554         ISwitchManager sm = (ISwitchManager) ServiceHelper.getInstance(
555                 ISwitchManager.class, containerName, this);
556
557         if (sm == null) {
558             throw new ServiceUnavailableException("Switch Manager "
559                     + RestMessages.SERVICEUNAVAILABLE.toString());
560         }
561
562         if (!sm.getNodes().contains(node)) {
563             throw new ResourceNotFoundException(node.toString() + " : "
564                     + RestMessages.NONODE.toString());
565         }
566         return node;
567     }
568
569 }