update link to upper-constraints.txt
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / onap / dmaap / datarouter / provisioning / FeedServlet.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 static org.onap.dmaap.datarouter.provisioning.utils.HttpServletUtils.sendResponseError;
28
29 import com.att.eelf.configuration.EELFLogger;
30 import com.att.eelf.configuration.EELFManager;
31 import jakarta.servlet.http.HttpServletRequest;
32 import jakarta.servlet.http.HttpServletResponse;
33 import java.io.IOException;
34 import java.io.InvalidObjectException;
35 import org.json.JSONException;
36 import org.json.JSONObject;
37 import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
38 import org.onap.dmaap.datarouter.provisioning.beans.EventLogRecord;
39 import org.onap.dmaap.datarouter.provisioning.beans.Feed;
40 import org.onap.dmaap.datarouter.provisioning.eelf.EelfMsgs;
41
42
43
44 /**
45  * This servlet handles provisioning for the <feedURL> which is generated by the provisioning
46  * server to handle a particular feed. It supports DELETE to mark the feed as deleted,
47  * and GET to retrieve information about the feed, and PUT to modify the feed.
48  *
49  * @author Robert Eby
50  * @version $Id$
51  */
52 @SuppressWarnings("serial")
53
54 public class FeedServlet extends ProxyServlet {
55
56     private static final EELFLogger eelfLogger = EELFManager.getInstance().getLogger(FeedServlet.class);
57
58     /**
59      * Delete the Feed at the address /feed/<feednumber>.
60      * See the <i>Deleting a Feed</i> section in the <b>Provisioning API</b>
61      * document for details on how this method should be invoked.
62      */
63     @Override
64     public void doDelete(HttpServletRequest req, HttpServletResponse resp) {
65         setIpFqdnRequestIDandInvocationIDForEelf("doDelete", req);
66         eelfLogger.info(EelfMsgs.ENTRY);
67         try {
68             eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID,
69                     req.getHeader(BEHALF_HEADER),getIdFromPath(req) + "");
70             EventLogRecord elr = new EventLogRecord(req);
71             String message = isAuthorizedForProvisioning(req);
72             if (message != null) {
73                 elr.setMessage(message);
74                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);
75                 eventlogger.error(elr.toString());
76                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
77                 return;
78             }
79             if (isProxyServer()) {
80                 super.doDelete(req, resp);
81                 return;
82             }
83             String bhdr = req.getHeader(BEHALF_HEADER);
84             if (bhdr == null) {
85                 message = MISSING_ON_BEHALF;
86                 elr.setMessage(message);
87                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
88                 eventlogger.error(elr.toString());
89                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
90                 return;
91             }
92             int feedid = getIdFromPath(req);
93             if (feedid < 0) {
94                 message = MISSING_FEED;
95                 elr.setMessage(message);
96                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
97                 eventlogger.error(elr.toString());
98                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
99                 return;
100             }
101             Feed feed = Feed.getFeedById(feedid);
102             if (feed == null || feed.isDeleted()) {
103                 message = MISSING_FEED;
104                 elr.setMessage(message);
105                 elr.setResult(HttpServletResponse.SC_NOT_FOUND);
106                 eventlogger.error(elr.toString());
107                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
108                 return;
109             }
110             // Delete FEED table entry (set DELETED flag)
111             feed.setDeleted(true);
112             if (doUpdate(feed)) {
113                 activeFeeds--;
114                 // send response
115                 elr.setResult(HttpServletResponse.SC_NO_CONTENT);
116                 eventlogger.info(elr.toString());
117                 resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
118                 provisioningDataChanged();
119             } else {
120                 // Something went wrong with the UPDATE
121                 elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
122                 eventlogger.error(elr.toString());
123                 sendResponseError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, DB_PROBLEM_MSG, eventlogger);
124             }
125         } finally {
126             eelfLogger.info(EelfMsgs.EXIT);
127         }
128     }
129
130     /**
131      * Get information on the feed at the address /feed/&lt;feednumber&gt;.
132      * See the <i>Retrieving Information about a Feed</i> section in the <b>Provisioning API</b>
133      * document for details on how this method should be invoked.
134      */
135     @Override
136     public void doGet(HttpServletRequest req, HttpServletResponse resp) {
137         setIpFqdnRequestIDandInvocationIDForEelf("doGet", req);
138         eelfLogger.info(EelfMsgs.ENTRY);
139         try {
140             eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID,
141                     req.getHeader(BEHALF_HEADER),getIdFromPath(req) + "");
142             EventLogRecord elr = new EventLogRecord(req);
143             String message = isAuthorizedForProvisioning(req);
144             if (message != null) {
145                 elr.setMessage(message);
146                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);
147                 eventlogger.error(elr.toString());
148                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
149                 return;
150             }
151             if (isProxyServer()) {
152                 super.doGet(req, resp);
153                 return;
154             }
155             String bhdr = req.getHeader(BEHALF_HEADER);
156             if (bhdr == null) {
157                 message = MISSING_ON_BEHALF;
158                 elr.setMessage(message);
159                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
160                 eventlogger.error(elr.toString());
161                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
162                 return;
163             }
164             int feedid = getIdFromPath(req);
165             if (feedid < 0) {
166                 message = MISSING_FEED;
167                 elr.setMessage(message);
168                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
169                 eventlogger.error(elr.toString());
170                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
171                 return;
172             }
173             Feed feed = Feed.getFeedById(feedid);
174             if (feed == null || feed.isDeleted()) {
175                 message = MISSING_FEED;
176                 elr.setMessage(message);
177                 elr.setResult(HttpServletResponse.SC_NOT_FOUND);
178                 eventlogger.error(elr.toString());
179                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
180                 return;
181             }
182             // Check with the Authorizer
183             AuthorizationResponse aresp = authz.decide(req);
184             if (! aresp.isAuthorized()) {
185                 message = POLICY_ENGINE;
186                 elr.setMessage(message);
187                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);
188                 eventlogger.error(elr.toString());
189                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
190                 return;
191             }
192
193             // send response
194             elr.setResult(HttpServletResponse.SC_OK);
195             eventlogger.info(elr.toString());
196             resp.setStatus(HttpServletResponse.SC_OK);
197             resp.setContentType(FEEDFULL_CONTENT_TYPE);
198             try {
199                 resp.getOutputStream().print(feed.asJSONObject(true).toString());
200             } catch (IOException ioe) {
201                 eventlogger.error("PROV0101 FeedServlet.doGet: " + ioe.getMessage(), ioe);
202             }
203         } finally {
204             eelfLogger.info(EelfMsgs.EXIT);
205         }
206     }
207
208     /**
209      * PUT on the &lt;feedURL&gt; for a feed.
210      * See the <i>Modifying a Feed</i> section in the <b>Provisioning API</b>
211      * document for details on how this method should be invoked.
212      */
213     @Override
214     public void doPut(HttpServletRequest req, HttpServletResponse resp) {
215         setIpFqdnRequestIDandInvocationIDForEelf("doPut", req);
216         eelfLogger.info(EelfMsgs.ENTRY);
217         try {
218             eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID,
219                     req.getHeader(BEHALF_HEADER),getIdFromPath(req) + "");
220             EventLogRecord elr = new EventLogRecord(req);
221             String message = isAuthorizedForProvisioning(req);
222             if (message != null) {
223                 elr.setMessage(message);
224                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);
225                 eventlogger.error(elr.toString());
226                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
227                 return;
228             }
229             if (isProxyServer()) {
230                 super.doPut(req, resp);
231                 return;
232             }
233             String bhdr = req.getHeader(BEHALF_HEADER);
234             if (bhdr == null) {
235                 message = MISSING_ON_BEHALF;
236                 elr.setMessage(message);
237                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
238                 eventlogger.error(elr.toString());
239                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
240                 return;
241             }
242             int feedid = getIdFromPath(req);
243             if (feedid < 0) {
244                 message = MISSING_FEED;
245                 elr.setMessage(message);
246                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
247                 eventlogger.error(elr.toString());
248                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
249                 return;
250             }
251             Feed oldFeed = Feed.getFeedById(feedid);
252             if (oldFeed == null || oldFeed.isDeleted()) {
253                 message = MISSING_FEED;
254                 elr.setMessage(message);
255                 elr.setResult(HttpServletResponse.SC_NOT_FOUND);
256                 eventlogger.error(elr.toString());
257                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
258                 return;
259             }
260             // check content type is FEED_CONTENT_TYPE, version 1.0
261             ContentHeader ch = getContentHeader(req);
262             String ver = ch.getAttribute("version");
263             if (!ch.getType().equals(FEED_BASECONTENT_TYPE) || !("1.0".equals(ver) || "2.0".equals(ver))) {
264                 message = "Incorrect content-type";
265                 elr.setMessage(message);
266                 elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
267                 eventlogger.error(elr.toString());
268                 sendResponseError(resp, HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message, eventlogger);
269                 return;
270             }
271             JSONObject jo = getJSONfromInput(req);
272             if (jo == null) {
273                 message = BAD_JSON;
274                 elr.setMessage(message);
275                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
276                 eventlogger.error(elr.toString());
277                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
278                 return;
279             }
280             Feed feed;
281             try {
282                 feed = new Feed(jo);
283             } catch (InvalidObjectException e) {
284                 message = e.getMessage();
285                 elr.setMessage(message);
286                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
287                 eventlogger.error(elr.toString(), e);
288                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
289                 return;
290             }
291             feed.setFeedid(feedid);
292             feed.setPublisher(bhdr);    // set from X-DMAAP-DR-ON-BEHALF-OF header
293
294             //Adding for group feature:Rally US708115
295             String subjectgroup = (req.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP"));
296             if (!oldFeed.getPublisher().equals(feed.getPublisher()) && subjectgroup == null) {
297                 message = "This feed must be modified by the same publisher that created it.";
298                 elr.setMessage(message);
299                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
300                 eventlogger.error(elr.toString());
301                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
302                 return;
303             }
304             if (!oldFeed.getName().equals(feed.getName())) {
305                 message = "The name of the feed may not be updated.";
306                 elr.setMessage(message);
307                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
308                 eventlogger.error(elr.toString());
309                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
310                 return;
311             }
312             //  US DSCDR-19 for DCAE if version is not null, version can't be changed
313             if ((oldFeed.getVersion() != null) && (feed.getVersion() != null)
314                         && !oldFeed.getVersion().equals(feed.getVersion())) {
315                 message = "The version of the feed may not be updated.";
316                 elr.setMessage(message);
317                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
318                 eventlogger.error(elr.toString());
319                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
320                 return;
321             }
322
323             // Update FEEDS table entries
324             if (doUpdate(feed)) {
325                 // send response
326                 elr.setResult(HttpServletResponse.SC_OK);
327                 eventlogger.info(elr.toString());
328                 resp.setStatus(HttpServletResponse.SC_OK);
329                 resp.setContentType(FEEDFULL_CONTENT_TYPE);
330                 try {
331                     resp.getOutputStream().print(feed.asLimitedJSONObject().toString());
332                 } catch (IOException ioe) {
333                     eventlogger.error("PROV0102 FeedServlet.doPut: " + ioe.getMessage(), ioe);
334                 }
335
336
337                 /**Change Owner ship of Feed //Adding for group feature. :Rally US708115*/
338                 if (jo.has("changeowner") && subjectgroup != null) {
339                     try {
340                         Boolean changeowner = (Boolean) jo.get("changeowner");
341                         if (changeowner != null && changeowner.equals(true)) {
342                             feed.setPublisher(req.getHeader(BEHALF_HEADER));
343                             feed.changeOwnerShip();
344                         }
345                     } catch (JSONException je) {
346                         eventlogger.error("PROV0103 FeedServlet.doPut: " + je.getMessage(), je);
347                     }
348                 }
349                 /***End of change ownership.*/
350
351                 provisioningDataChanged();
352             } else {
353                 // Something went wrong with the UPDATE
354                 elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
355                 eventlogger.error(elr.toString());
356                 sendResponseError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, DB_PROBLEM_MSG, eventlogger);
357             }
358         } finally {
359             eelfLogger.info(EelfMsgs.EXIT);
360         }
361     }
362
363     /**
364      * POST on the &lt;feedURL&gt; -- not supported.
365      */
366     @Override
367     public void doPost(HttpServletRequest req, HttpServletResponse resp) {
368         setIpFqdnRequestIDandInvocationIDForEelf("doPost", req);
369         eelfLogger.info(EelfMsgs.ENTRY);
370         try {
371             eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF, req.getHeader(BEHALF_HEADER));
372             String message = "POST not allowed for the feedURL.";
373             EventLogRecord elr = new EventLogRecord(req);
374             elr.setMessage(message);
375             elr.setResult(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
376             eventlogger.error(elr.toString());
377             sendResponseError(resp, HttpServletResponse.SC_METHOD_NOT_ALLOWED, message, eventlogger);
378         } finally {
379             eelfLogger.info(EelfMsgs.EXIT);
380         }
381     }
382 }