AbstractNeutronNorthbound: make cast more accurate
[neutron.git] / northbound-api / src / main / java / org / opendaylight / neutron / northbound / api / AbstractNeutronNorthbound.java
1 /*
2  * Copyright (c) 2015 Intel Corporation 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.neutron.northbound.api;
10
11 import java.lang.reflect.Constructor;
12 import java.lang.reflect.InvocationTargetException;
13 import java.lang.reflect.ParameterizedType;
14 import java.net.HttpURLConnection;
15 import java.util.List;
16 import javax.ws.rs.core.Response;
17 import org.opendaylight.neutron.spi.INeutronCRUD;
18 import org.opendaylight.neutron.spi.INeutronObject;
19 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 public abstract class AbstractNeutronNorthbound<T extends INeutronObject<T>, NeutronRequest extends INeutronRequest<T>,
24         I extends INeutronCRUD<T>> {
25     private static final Logger LOGGER = LoggerFactory.getLogger(AbstractNeutronNorthbound.class);
26
27     protected static final int HTTP_OK_BOTTOM = 200;
28     protected static final int HTTP_OK_TOP = 299;
29
30     private static final String INTERFACE_NAME_BASE = " CRUD Interface";
31     private static final String UUID_NO_EXIST_BASE = " UUID does not exist.";
32
33     protected final String serviceUnavailable() {
34         return getResourceName() + INTERFACE_NAME_BASE + RestMessages.SERVICEUNAVAILABLE.toString();
35     }
36
37     protected final String uuidNoExist() {
38         return getResourceName() + UUID_NO_EXIST_BASE;
39     }
40
41     protected abstract String getResourceName();
42
43     private NeutronRequest newNeutronRequest(T o) {
44         // return new NeutronRequest(o);
45
46         ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
47         // argumentClass = T.class
48         Class<T> argumentClass = (Class<T>) parameterizedType.getActualTypeArguments()[0];
49         // cls = NeturonRequest.class
50         Class<NeutronRequest> cls = (Class<NeutronRequest>) parameterizedType.getActualTypeArguments()[1];
51         try {
52             // ctor = NeutronRequest constructor
53             Constructor<NeutronRequest> ctor = cls.getDeclaredConstructor(argumentClass);
54             return ctor.newInstance(o);
55         } catch (NoSuchMethodException | InstantiationException
56                  | IllegalAccessException | InvocationTargetException e) {
57             // This case shouldn't happen
58             throw new RuntimeException(e);
59         }
60     }
61
62     protected I getNeutronCRUD() {
63         ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
64         // cls = I.class
65         Class<I> cls = (Class<I>) parameterizedType.getActualTypeArguments()[2];
66         I neutronCrud = NeutronCRUDInterfaces.fetchINeutronCRUD(cls, (Object) this);
67         if (neutronCrud == null) {
68             throw new ServiceUnavailableException(serviceUnavailable());
69         }
70         return neutronCrud;
71     }
72
73     protected Response show(String uuid,
74             // return fields
75             List<String> fields) {
76         I neutronCRUD = getNeutronCRUD();
77         T ans = neutronCRUD.get(uuid);
78         if (ans == null) {
79             throw new ResourceNotFoundException(uuidNoExist());
80         }
81
82         if (fields.size() > 0) {
83             return Response.status(HttpURLConnection.HTTP_OK).entity(newNeutronRequest(ans.extractFields(fields)))
84                     .build();
85         } else {
86             return Response.status(HttpURLConnection.HTTP_OK).entity(newNeutronRequest(ans)).build();
87         }
88     }
89
90     protected Response create(final NeutronRequest input) {
91         I neutronCRUD = getNeutronCRUD();
92         if (input.isSingleton()) {
93             T singleton = input.getSingleton();
94
95             singleton.initDefaults();
96             neutronCRUD.add(singleton);
97         } else {
98             if (input.getBulk() == null) {
99                 throw new BadRequestException("Invalid requests");
100             }
101             for (T test : input.getBulk()) {
102                 test.initDefaults();
103                 neutronCRUD.add(test);
104             }
105         }
106         return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build();
107     }
108
109     protected void updateDelta(String uuid, T delta, T original) {
110     }
111
112     protected Response update(String uuid, final NeutronRequest input) {
113         I neutronCRUD = getNeutronCRUD();
114         if (!input.isSingleton()) {
115             throw new BadRequestException("Only singleton edit supported");
116         }
117         T delta = input.getSingleton();
118         T original = neutronCRUD.get(uuid);
119         if (original == null) {
120             throw new ResourceNotFoundException(uuidNoExist());
121         }
122         updateDelta(uuid, delta, original);
123
124         /*
125          * update the object and return it
126          */
127         if (!neutronCRUD.update(uuid, delta)) {
128             throw new ResourceNotFoundException(uuidNoExist());
129         }
130         T updated = neutronCRUD.get(uuid);
131         return Response.status(HttpURLConnection.HTTP_OK).entity(newNeutronRequest(updated)).build();
132     }
133
134     protected Response delete(String uuid) {
135         final I neutronCRUD = getNeutronCRUD();
136
137         /*
138          * remove it and return 204 status
139          */
140         boolean exist = false;
141         try {
142             exist = neutronCRUD.remove(uuid);
143         } catch (Exception e) {
144             final String resourceName = getResourceName();
145             LOGGER.debug("exception during remove {} {} {}", resourceName, uuid, e);
146             throw new InternalServerErrorException("Could not delete " + resourceName);
147         }
148         if (!exist) {
149             throw new ResourceNotFoundException(uuidNoExist());
150         }
151
152         return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build();
153     }
154 }