[DMAAP-48] Initial code import
[dmaap/datarouter.git] / datarouter-prov / src / main / java / com / att / research / datarouter / provisioning / FeedServlet.java
1 /*******************************************************************************\r
2  * ============LICENSE_START==================================================\r
3  * * org.onap.dmaap\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * * ===========================================================================\r
7  * * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * * you may not use this file except in compliance with the License.\r
9  * * You may obtain a copy of the License at\r
10  * * \r
11  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * * \r
13  *  * Unless required by applicable law or agreed to in writing, software\r
14  * * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * * See the License for the specific language governing permissions and\r
17  * * limitations under the License.\r
18  * * ============LICENSE_END====================================================\r
19  * *\r
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 \r
24 \r
25 package com.att.research.datarouter.provisioning;\r
26 \r
27 import java.io.IOException;\r
28 import java.io.InvalidObjectException;\r
29 \r
30 import javax.servlet.http.HttpServletRequest;\r
31 import javax.servlet.http.HttpServletResponse;\r
32 \r
33 import org.json.JSONObject;\r
34 \r
35 import com.att.eelf.configuration.EELFLogger;\r
36 import com.att.eelf.configuration.EELFManager;\r
37 import com.att.research.datarouter.authz.AuthorizationResponse;\r
38 import com.att.research.datarouter.provisioning.beans.EventLogRecord;\r
39 import com.att.research.datarouter.provisioning.beans.Feed;\r
40 import com.att.research.datarouter.provisioning.eelf.EelfMsgs;\r
41 \r
42 /**\r
43  * This servlet handles provisioning for the <feedURL> which is generated by the provisioning\r
44  * server to handle a particular feed. It supports DELETE to mark the feed as deleted,\r
45  * and GET to retrieve information about the feed, and PUT to modify the feed.\r
46  *\r
47  * @author Robert Eby\r
48  * @version $Id$\r
49  */\r
50 @SuppressWarnings("serial")\r
51 public class FeedServlet extends ProxyServlet {\r
52 \r
53         //Adding EELF Logger Rally:US664892 \r
54     private static EELFLogger eelflogger = EELFManager.getInstance().getLogger("com.att.research.datarouter.provisioning.FeedServlet");\r
55 \r
56         /**\r
57          * Delete the Feed at the address /feed/<feednumber>.\r
58          * See the <i>Deleting a Feed</i> section in the <b>Provisioning API</b>\r
59          * document for details on how this method should be invoked.\r
60          */\r
61         @Override\r
62         public void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException {\r
63                 setIpAndFqdnForEelf("doDelete");\r
64                 eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID, req.getHeader(BEHALF_HEADER),getIdFromPath(req)+"");\r
65                 EventLogRecord elr = new EventLogRecord(req);\r
66                 String message = isAuthorizedForProvisioning(req);\r
67                 if (message != null) {\r
68                         elr.setMessage(message);\r
69                         elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
70                         eventlogger.info(elr);\r
71                         resp.sendError(HttpServletResponse.SC_FORBIDDEN, message);\r
72                         return;\r
73                 }\r
74                 if (isProxyServer()) {\r
75                         super.doDelete(req, resp);\r
76                         return;\r
77                 }\r
78                 String bhdr = req.getHeader(BEHALF_HEADER);\r
79                 if (bhdr == null) {\r
80                         message = "Missing "+BEHALF_HEADER+" header.";\r
81                         elr.setMessage(message);\r
82                         elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
83                         eventlogger.info(elr);\r
84                         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);\r
85                         return;\r
86                 }\r
87                 int feedid = getIdFromPath(req);\r
88                 if (feedid < 0) {\r
89                         message = "Missing or bad feed number.";\r
90                         elr.setMessage(message);\r
91                         elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
92                         eventlogger.info(elr);\r
93                         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);\r
94                         return;\r
95                 }\r
96                 Feed feed = Feed.getFeedById(feedid);\r
97                 if (feed == null || feed.isDeleted()) {\r
98                         message = "Missing or bad feed number.";\r
99                         elr.setMessage(message);\r
100                         elr.setResult(HttpServletResponse.SC_NOT_FOUND);\r
101                         eventlogger.info(elr);\r
102                         resp.sendError(HttpServletResponse.SC_NOT_FOUND, message);\r
103                         return;\r
104                 }\r
105                 // Check with the Authorizer\r
106                 AuthorizationResponse aresp = authz.decide(req);\r
107                 if (! aresp.isAuthorized()) {\r
108                         message = "Policy Engine disallows access.";\r
109                         elr.setMessage(message);\r
110                         elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
111                         eventlogger.info(elr);\r
112                         resp.sendError(HttpServletResponse.SC_FORBIDDEN, message);\r
113                         return;\r
114                 }\r
115 \r
116                 // Delete FEED table entry (set DELETED flag)\r
117                 feed.setDeleted(true);\r
118                 if (doUpdate(feed)) {\r
119                         active_feeds--;\r
120                         // send response\r
121                         elr.setResult(HttpServletResponse.SC_NO_CONTENT);\r
122                         eventlogger.info(elr);\r
123                         resp.setStatus(HttpServletResponse.SC_NO_CONTENT);\r
124                         provisioningDataChanged();\r
125                 } else {\r
126                         // Something went wrong with the UPDATE\r
127                         elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);\r
128                         eventlogger.info(elr);\r
129                         resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, DB_PROBLEM_MSG);\r
130                 }\r
131         }\r
132         /**\r
133          * Get information on the feed at the address /feed/&lt;feednumber&gt;.\r
134          * See the <i>Retrieving Information about a Feed</i> section in the <b>Provisioning API</b>\r
135          * document for details on how this method should be invoked.\r
136          */\r
137         @Override\r
138         public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {\r
139                 setIpAndFqdnForEelf("doGet");\r
140                 eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID, req.getHeader(BEHALF_HEADER),getIdFromPath(req)+"");\r
141                 EventLogRecord elr = new EventLogRecord(req);\r
142                 String message = isAuthorizedForProvisioning(req);\r
143                 if (message != null) {\r
144                         elr.setMessage(message);\r
145                         elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
146                         eventlogger.info(elr);\r
147                         resp.sendError(HttpServletResponse.SC_FORBIDDEN, message);\r
148                         return;\r
149                 }\r
150                 if (isProxyServer()) {\r
151                         super.doGet(req, resp);\r
152                         return;\r
153                 }\r
154                 String bhdr = req.getHeader(BEHALF_HEADER);\r
155                 if (bhdr == null) {\r
156                         message = "Missing "+BEHALF_HEADER+" header.";\r
157                         elr.setMessage(message);\r
158                         elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
159                         eventlogger.info(elr);\r
160                         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);\r
161                         return;\r
162                 }\r
163                 int feedid = getIdFromPath(req);\r
164                 if (feedid < 0) {\r
165                         message = "Missing or bad feed number.";\r
166                         elr.setMessage(message);\r
167                         elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
168                         eventlogger.info(elr);\r
169                         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);\r
170                         return;\r
171                 }\r
172                 Feed feed = Feed.getFeedById(feedid);\r
173                 if (feed == null || feed.isDeleted()) {\r
174                         message = "Missing or bad feed number.";\r
175                         elr.setMessage(message);\r
176                         elr.setResult(HttpServletResponse.SC_NOT_FOUND);\r
177                         eventlogger.info(elr);\r
178                         resp.sendError(HttpServletResponse.SC_NOT_FOUND, message);\r
179                         return;\r
180                 }\r
181                 // Check with the Authorizer\r
182                 AuthorizationResponse aresp = authz.decide(req);\r
183                 if (! aresp.isAuthorized()) {\r
184                         message = "Policy Engine disallows access.";\r
185                         elr.setMessage(message);\r
186                         elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
187                         eventlogger.info(elr);\r
188                         resp.sendError(HttpServletResponse.SC_FORBIDDEN, message);\r
189                         return;\r
190                 }\r
191 \r
192                 // send response\r
193                 elr.setResult(HttpServletResponse.SC_OK);\r
194                 eventlogger.info(elr);\r
195                 resp.setStatus(HttpServletResponse.SC_OK);\r
196                 resp.setContentType(FEEDFULL_CONTENT_TYPE);\r
197                 resp.getOutputStream().print(feed.asJSONObject(true).toString());\r
198         }\r
199         /**\r
200          * PUT on the &lt;feedURL&gt; for a feed.\r
201          * See the <i>Modifying a Feed</i> section in the <b>Provisioning API</b>\r
202          * document for details on how this method should be invoked.\r
203          */\r
204         @Override\r
205         public void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException {\r
206                 setIpAndFqdnForEelf("doPut");\r
207                 eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID, req.getHeader(BEHALF_HEADER),getIdFromPath(req)+"");\r
208                 EventLogRecord elr = new EventLogRecord(req);\r
209                 String message = isAuthorizedForProvisioning(req);\r
210                 if (message != null) {\r
211                         elr.setMessage(message);\r
212                         elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
213                         eventlogger.info(elr);\r
214                         resp.sendError(HttpServletResponse.SC_FORBIDDEN, message);\r
215                         return;\r
216                 }\r
217                 if (isProxyServer()) {\r
218                         super.doPut(req, resp);\r
219                         return;\r
220                 }\r
221                 String bhdr = req.getHeader(BEHALF_HEADER);\r
222                 if (bhdr == null) {\r
223                         message = "Missing "+BEHALF_HEADER+" header.";\r
224                         elr.setMessage(message);\r
225                         elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
226                         eventlogger.info(elr);\r
227                         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);\r
228                         return;\r
229                 }\r
230                 int feedid = getIdFromPath(req);\r
231                 if (feedid < 0) {\r
232                         message = "Missing or bad feed number.";\r
233                         elr.setMessage(message);\r
234                         elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
235                         eventlogger.info(elr);\r
236                         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);\r
237                         return;\r
238                 }\r
239                 Feed oldFeed = Feed.getFeedById(feedid);\r
240                 if (oldFeed == null || oldFeed.isDeleted()) {\r
241                         message = "Missing or bad feed number.";\r
242                         elr.setMessage(message);\r
243                         elr.setResult(HttpServletResponse.SC_NOT_FOUND);\r
244                         eventlogger.info(elr);\r
245                         resp.sendError(HttpServletResponse.SC_NOT_FOUND, message);\r
246                         return;\r
247                 }\r
248                 // check content type is FEED_CONTENT_TYPE, version 1.0\r
249                 ContentHeader ch = getContentHeader(req);\r
250                 String ver = ch.getAttribute("version");\r
251                 if (!ch.getType().equals(FEED_BASECONTENT_TYPE) || !(ver.equals("1.0") || ver.equals("2.0"))) {\r
252                         message = "Incorrect content-type";\r
253                         elr.setMessage(message);\r
254                         elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);\r
255                         eventlogger.info(elr);\r
256                         resp.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message);\r
257                         return;\r
258                 }\r
259                 JSONObject jo = getJSONfromInput(req);\r
260                 if (jo == null) {\r
261                         message = "Badly formed JSON";\r
262                         elr.setMessage(message);\r
263                         elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
264                         eventlogger.info(elr);\r
265                         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);\r
266                         return;\r
267                 }\r
268                 if (intlogger.isDebugEnabled())\r
269                         intlogger.debug(jo.toString());\r
270                 Feed feed = null;\r
271                 try {\r
272                         feed = new Feed(jo);\r
273                 } catch (InvalidObjectException e) {\r
274                         message = e.getMessage();\r
275                         elr.setMessage(message);\r
276                         elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
277                         eventlogger.info(elr);\r
278                         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);\r
279                         return;\r
280                 }\r
281                 feed.setFeedid(feedid);\r
282                 feed.setPublisher(bhdr);        // set from X-ATT-DR-ON-BEHALF-OF header\r
283 \r
284                 String subjectgroup = (req.getHeader("X-ATT-DR-ON-BEHALF-OF-GROUP"));  //Adding for group feature:Rally US708115  \r
285                 if (!oldFeed.getPublisher().equals(feed.getPublisher()) && subjectgroup == null) {\r
286                         message = "This feed must be modified by the same publisher that created it.";\r
287                         elr.setMessage(message);\r
288                         elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
289                         eventlogger.info(elr);\r
290                         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);\r
291                         return;\r
292                 }\r
293                 if (!oldFeed.getName().equals(feed.getName())) {\r
294                         message = "The name of the feed may not be updated.";\r
295                         elr.setMessage(message);\r
296                         elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
297                         eventlogger.info(elr);\r
298                         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);\r
299                         return;\r
300                 }\r
301                 if (!oldFeed.getVersion().equals(feed.getVersion())) {\r
302                         message = "The version of the feed may not be updated.";\r
303                         elr.setMessage(message);\r
304                         elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
305                         eventlogger.info(elr);\r
306                         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);\r
307                         return;\r
308                 }\r
309                 // Check with the Authorizer\r
310                 AuthorizationResponse aresp = authz.decide(req);\r
311                 if (! aresp.isAuthorized()) {\r
312                         message = "Policy Engine disallows access.";\r
313                         elr.setMessage(message);\r
314                         elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
315                         eventlogger.info(elr);\r
316                         resp.sendError(HttpServletResponse.SC_FORBIDDEN, message);\r
317                         return;\r
318                 }\r
319 \r
320                 // Update FEEDS table entries\r
321                 if (doUpdate(feed)) {\r
322                         // send response\r
323                         elr.setResult(HttpServletResponse.SC_OK);\r
324                         eventlogger.info(elr);\r
325                         resp.setStatus(HttpServletResponse.SC_OK);\r
326                         resp.setContentType(FEEDFULL_CONTENT_TYPE);\r
327                         resp.getOutputStream().print(feed.asLimitedJSONObject().toString());\r
328 \r
329                         \r
330                         /**Change Owner ship of Feed //Adding for group feature:Rally US708115*/\r
331                         if (jo.has("changeowner") && subjectgroup != null) {\r
332                                 Boolean changeowner = (Boolean) jo.get("changeowner");\r
333                                 if (changeowner != null && changeowner.equals(true)) {\r
334                                         feed.setPublisher(req.getHeader(BEHALF_HEADER));\r
335                                         feed.changeOwnerShip();\r
336                                 }\r
337                         }\r
338                         /***End of change ownership*/\r
339 \r
340                         provisioningDataChanged();\r
341                 } else {\r
342                         // Something went wrong with the UPDATE\r
343                         elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);\r
344                         eventlogger.info(elr);\r
345                         resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, DB_PROBLEM_MSG);\r
346                 }\r
347         }\r
348         /**\r
349          * POST on the &lt;feedURL&gt; -- not supported.\r
350          */\r
351         @Override\r
352         public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {\r
353                 setIpAndFqdnForEelf("doPost");\r
354                 eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF, req.getHeader(BEHALF_HEADER));\r
355                 String message = "POST not allowed for the feedURL.";\r
356                 EventLogRecord elr = new EventLogRecord(req);\r
357                 elr.setMessage(message);\r
358                 elr.setResult(HttpServletResponse.SC_METHOD_NOT_ALLOWED);\r
359                 eventlogger.info(elr);\r
360                 resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, message);\r
361         }\r
362 }\r