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