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