Merge "Update for OOM integration"
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / onap / dmaap / datarouter / provisioning / DRFeedsServlet.java
1 /*******************************************************************************
2  * ============LICENSE_START==================================================
3  * * org.onap.dmaap
4  * * ===========================================================================
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6  * * ===========================================================================
7  * * Licensed under the Apache License, Version 2.0 (the "License");
8  * * you may not use this file except in compliance with the License.
9  * * You may obtain a copy of the License at
10  * *
11  *  *      http://www.apache.org/licenses/LICENSE-2.0
12  * *
13  *  * Unless required by applicable law or agreed to in writing, software
14  * * distributed under the License is distributed on an "AS IS" BASIS,
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * * See the License for the specific language governing permissions and
17  * * limitations under the License.
18  * * ============LICENSE_END====================================================
19  * *
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  * *
22  ******************************************************************************/
23
24
25 package org.onap.dmaap.datarouter.provisioning;
26
27 import java.io.IOException;
28 import java.io.InvalidObjectException;
29 import java.util.List;
30
31 import javax.servlet.http.HttpServletRequest;
32 import javax.servlet.http.HttpServletResponse;
33
34 import org.json.JSONObject;
35 import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
36 import org.onap.dmaap.datarouter.provisioning.beans.EventLogRecord;
37 import org.onap.dmaap.datarouter.provisioning.beans.Feed;
38 import org.onap.dmaap.datarouter.provisioning.eelf.EelfMsgs;
39 import org.onap.dmaap.datarouter.provisioning.utils.JSONUtilities;
40
41 import com.att.eelf.configuration.EELFLogger;
42 import com.att.eelf.configuration.EELFManager;
43
44 /**
45  * This servlet handles provisioning for the <drFeedsURL> which is the URL on the provisioning server used to
46  * create new feeds.  It supports POST to create new feeds, and GET to support the Feeds Collection Query function.
47  *
48  * @author Robert Eby
49  * @version $Id$
50  */
51 @SuppressWarnings("serial")
52 public class DRFeedsServlet extends ProxyServlet {
53
54     //Adding EELF Logger Rally:US664892
55     private static EELFLogger eelflogger = EELFManager.getInstance()
56         .getLogger("org.onap.dmaap.datarouter.provisioning.DRFeedsServlet");
57
58     /**
59      * DELETE on the <drFeedsURL> -- not supported.
60      */
61     @Override
62     public void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
63         setIpAndFqdnForEelf("doDelete");
64         eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID, req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");
65         String message = "DELETE not allowed for the drFeedsURL.";
66         EventLogRecord elr = new EventLogRecord(req);
67         elr.setMessage(message);
68         elr.setResult(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
69         eventlogger.info(elr);
70         resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, message);
71     }
72
73     /**
74      * GET on the &lt;drFeedsURL&gt; -- query the list of feeds already existing in the DB. See the <i>Feeds Collection
75      * Queries</i> section in the <b>Provisioning API</b> document for details on how this method should be invoked.
76      */
77     @Override
78     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
79         setIpAndFqdnForEelf("doGet");
80         eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID, req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");
81         EventLogRecord elr = new EventLogRecord(req);
82         String message = isAuthorizedForProvisioning(req);
83         if (message != null) {
84             elr.setMessage(message);
85             elr.setResult(HttpServletResponse.SC_FORBIDDEN);
86             eventlogger.info(elr);
87             resp.sendError(HttpServletResponse.SC_FORBIDDEN, message);
88             return;
89         }
90         if (isProxyServer()) {
91             super.doGet(req, resp);
92             return;
93         }
94         String bhdr = req.getHeader(BEHALF_HEADER);
95         if (bhdr == null) {
96             message = "Missing " + BEHALF_HEADER + " header.";
97             elr.setMessage(message);
98             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
99             eventlogger.info(elr);
100             resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
101             return;
102         }
103         String path = req
104             .getRequestURI(); // Note: I think this should be getPathInfo(), but that doesn't work (Jetty bug?)
105         if (path != null && !path.equals("/")) {
106             message = "Bad URL.";
107             elr.setMessage(message);
108             elr.setResult(HttpServletResponse.SC_NOT_FOUND);
109             eventlogger.info(elr);
110             resp.sendError(HttpServletResponse.SC_NOT_FOUND, message);
111             return;
112         }
113         // Check with the Authorizer
114         AuthorizationResponse aresp = authz.decide(req);
115         if (!aresp.isAuthorized()) {
116             message = "Policy Engine disallows access.";
117             elr.setMessage(message);
118             elr.setResult(HttpServletResponse.SC_FORBIDDEN);
119             eventlogger.info(elr);
120             resp.sendError(HttpServletResponse.SC_FORBIDDEN, message);
121             return;
122         }
123
124         String name = req.getParameter("name");
125         String vers = req.getParameter("version");
126         String publ = req.getParameter("publisher");
127         String subs = req.getParameter("subscriber");
128         if (name != null && vers != null) {
129             // Display a specific feed
130             Feed feed = Feed.getFeedByNameVersion(name, vers);
131             if (feed == null || feed.isDeleted()) {
132                 message = "This feed does not exist in the database.";
133                 elr.setMessage(message);
134                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
135                 eventlogger.info(elr);
136                 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
137             } else {
138                 // send response
139                 elr.setResult(HttpServletResponse.SC_OK);
140                 eventlogger.info(elr);
141                 resp.setStatus(HttpServletResponse.SC_OK);
142                 resp.setContentType(FEEDFULL_CONTENT_TYPE);
143                 resp.getOutputStream().print(feed.asJSONObject(true).toString());
144             }
145         } else {
146             // Display a list of URLs
147             List<String> list = null;
148             if (name != null) {
149                 list = Feed.getFilteredFeedUrlList("name", name);
150             } else if (publ != null) {
151                 list = Feed.getFilteredFeedUrlList("publ", publ);
152             } else if (subs != null) {
153                 list = Feed.getFilteredFeedUrlList("subs", subs);
154             } else {
155                 list = Feed.getFilteredFeedUrlList("all", null);
156             }
157             String t = JSONUtilities.createJSONArray(list);
158             // send response
159             elr.setResult(HttpServletResponse.SC_OK);
160             eventlogger.info(elr);
161             resp.setStatus(HttpServletResponse.SC_OK);
162             resp.setContentType(FEEDLIST_CONTENT_TYPE);
163             resp.getOutputStream().print(t);
164         }
165     }
166
167     /**
168      * PUT on the &lt;drFeedsURL&gt; -- not supported.
169      */
170     @Override
171     public void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException {
172         setIpAndFqdnForEelf("doPut");
173         eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID, req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");
174         String message = "PUT not allowed for the drFeedsURL.";
175         EventLogRecord elr = new EventLogRecord(req);
176         elr.setMessage(message);
177         elr.setResult(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
178         eventlogger.info(elr);
179         resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, message);
180     }
181
182     /**
183      * POST on the &lt;drFeedsURL&gt; -- create a new feed. See the <i>Creating a Feed</i> section in the
184      * <b>Provisioning API</b> document for details on how this method should be invoked.
185      */
186     @Override
187     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
188         setIpAndFqdnForEelf("doPost");
189         eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF, req.getHeader(BEHALF_HEADER));
190         EventLogRecord elr = new EventLogRecord(req);
191         String message = isAuthorizedForProvisioning(req);
192         if (message != null) {
193             elr.setMessage(message);
194             elr.setResult(HttpServletResponse.SC_FORBIDDEN);
195             eventlogger.info(elr);
196             resp.sendError(HttpServletResponse.SC_FORBIDDEN, message);
197             return;
198         }
199         if (isProxyServer()) {
200             super.doPost(req, resp);
201             return;
202         }
203         String bhdr = req.getHeader(BEHALF_HEADER);
204         if (bhdr == null) {
205             message = "Missing " + BEHALF_HEADER + " header.";
206             elr.setMessage(message);
207             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
208             eventlogger.info(elr);
209             resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
210             return;
211         }
212         String path = req
213             .getRequestURI(); // Note: I think this should be getPathInfo(), but that doesn't work (Jetty bug?)
214         if (path != null && !path.equals("/")) {
215             message = "Bad URL.";
216             elr.setMessage(message);
217             elr.setResult(HttpServletResponse.SC_NOT_FOUND);
218             eventlogger.info(elr);
219             resp.sendError(HttpServletResponse.SC_NOT_FOUND, message);
220             return;
221         }
222         // check content type is FEED_CONTENT_TYPE, version 1.0
223         ContentHeader ch = getContentHeader(req);
224         String ver = ch.getAttribute("version");
225         if (!ch.getType().equals(FEED_BASECONTENT_TYPE) || !(ver.equals("1.0") || ver.equals("2.0"))) {
226             message = "Incorrect content-type";
227             elr.setMessage(message);
228             elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
229             eventlogger.info(elr);
230             resp.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message);
231             return;
232         }
233         // Check with the Authorizer
234         AuthorizationResponse aresp = authz.decide(req);
235         if (!aresp.isAuthorized()) {
236             message = "Policy Engine disallows access.";
237             elr.setMessage(message);
238             elr.setResult(HttpServletResponse.SC_FORBIDDEN);
239             eventlogger.info(elr);
240             resp.sendError(HttpServletResponse.SC_FORBIDDEN, message);
241             return;
242         }
243         JSONObject jo = getJSONfromInput(req);
244         if (jo == null) {
245             message = "Badly formed JSON";
246             elr.setMessage(message);
247             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
248             eventlogger.info(elr);
249             resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
250             return;
251         }
252         if (intlogger.isDebugEnabled()) {
253             intlogger.debug(jo.toString());
254         }
255         if (++activeFeeds > maxFeeds) {
256             activeFeeds--;
257             message = "Cannot create feed; the maximum number of feeds has been configured.";
258             elr.setMessage(message);
259             elr.setResult(HttpServletResponse.SC_CONFLICT);
260             eventlogger.info(elr);
261             resp.sendError(HttpServletResponse.SC_CONFLICT, message);
262             return;
263         }
264         Feed feed = null;
265         try {
266             feed = new Feed(jo);
267         } catch (InvalidObjectException e) {
268             message = e.getMessage();
269             elr.setMessage(message);
270             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
271             eventlogger.info(elr);
272             resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
273             return;
274         }
275         feed.setPublisher(bhdr);    // set from X-ATT-DR-ON-BEHALF-OF header
276
277         // Check if this feed already exists
278         Feed feed2 = Feed.getFeedByNameVersion(feed.getName(), feed.getVersion());
279         if (feed2 != null) {
280             message = "This feed already exists in the database.";
281             elr.setMessage(message);
282             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
283             eventlogger.info(elr);
284             resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
285             return;
286         }
287
288         // Create FEED table entries
289         if (doInsert(feed)) {
290             // send response
291             elr.setResult(HttpServletResponse.SC_CREATED);
292             eventlogger.info(elr);
293             resp.setStatus(HttpServletResponse.SC_CREATED);
294             resp.setContentType(FEEDFULL_CONTENT_TYPE);
295             resp.setHeader("Location", feed.getLinks().getSelf());
296             resp.getOutputStream().print(feed.asLimitedJSONObject().toString());
297             provisioningDataChanged();
298         } else {
299             // Something went wrong with the INSERT
300             elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
301             eventlogger.info(elr);
302             resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, DB_PROBLEM_MSG);
303         }
304     }
305 }