Removing passwordencryption key
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / onap / dmaap / datarouter / provisioning / SubscribeServlet.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 java.io.IOException;
32 import java.io.InvalidObjectException;
33 import java.util.Collection;
34 import javax.servlet.http.HttpServletRequest;
35 import javax.servlet.http.HttpServletResponse;
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.beans.Subscription;
41 import org.onap.dmaap.datarouter.provisioning.eelf.EelfMsgs;
42 import org.onap.dmaap.datarouter.provisioning.utils.JSONUtilities;
43
44
45 /**
46  * This servlet handles provisioning for the <subscribeURL> which is generated by the provisioning server to
47  * handle the creation and inspection of subscriptions to a specific feed.
48  *
49  * @author Robert Eby
50  * @version $Id$
51  */
52 @SuppressWarnings("serial")
53
54 public class SubscribeServlet extends ProxyServlet {
55
56     //Adding EELF Logger Rally:US664892
57     private static EELFLogger eelfLogger = EELFManager.getInstance()
58         .getLogger(SubscribeServlet.class);
59
60     /**
61      * DELETE on the <subscribeUrl> -- not supported.
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_SUBID,
69                     req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");
70             String message = "DELETE not allowed for the subscribeURL.";
71             EventLogRecord elr = new EventLogRecord(req);
72             elr.setMessage(message);
73             elr.setResult(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
74             eventlogger.error(elr.toString());
75             sendResponseError(resp, HttpServletResponse.SC_METHOD_NOT_ALLOWED, message, eventlogger);
76         } finally {
77             eelfLogger.info(EelfMsgs.EXIT);
78         }
79     }
80
81     /**
82      * GET on the &lt;subscribeUrl&gt; -- get the list of subscriptions to a feed. See the <i>Subscription Collection
83      * Query</i> section in the <b>Provisioning API</b> document for details on how this method should be invoked.
84      */
85     @Override
86     public void doGet(HttpServletRequest req, HttpServletResponse resp) {
87         setIpFqdnRequestIDandInvocationIDForEelf("doGet", req);
88         eelfLogger.info(EelfMsgs.ENTRY);
89         try {
90             eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_SUBID,
91                     req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");
92             EventLogRecord elr = new EventLogRecord(req);
93             String message = isAuthorizedForProvisioning(req);
94             if (message != null) {
95                 elr.setMessage(message);
96                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);
97                 eventlogger.error(elr.toString());
98                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
99                 return;
100             }
101             if (isProxyServer()) {
102                 super.doGet(req, resp);
103                 return;
104             }
105             String bhdr = req.getHeader(BEHALF_HEADER);
106             if (bhdr == null) {
107                 message = "Missing " + BEHALF_HEADER + " header.";
108                 elr.setMessage(message);
109                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
110                 eventlogger.error(elr.toString());
111                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
112                 return;
113             }
114             int feedid = getIdFromPath(req);
115             if (feedid < 0) {
116                 message = MISSING_FEED;
117                 elr.setMessage(message);
118                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
119                 eventlogger.error(elr.toString());
120                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
121                 return;
122             }
123             Feed feed = Feed.getFeedById(feedid);
124             if (feed == null || feed.isDeleted()) {
125                 message = MISSING_FEED;
126                 elr.setMessage(message);
127                 elr.setResult(HttpServletResponse.SC_NOT_FOUND);
128                 eventlogger.error(elr.toString());
129                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
130                 return;
131             }
132             // Display a list of URLs
133             Collection<String> list = Subscription.getSubscriptionUrlList(feedid);
134             String strList = JSONUtilities.createJSONArray(list);
135
136             // send response
137             elr.setResult(HttpServletResponse.SC_OK);
138             eventlogger.info(elr.toString());
139             resp.setStatus(HttpServletResponse.SC_OK);
140             resp.setContentType(SUBLIST_CONTENT_TYPE);
141             try {
142                 resp.getOutputStream().print(strList);
143             } catch (IOException ioe) {
144                 eventlogger.error("PROV0181 SubscribeServlet.doGet: " + ioe.getMessage(), ioe);
145             }
146         } finally {
147             eelfLogger.info(EelfMsgs.EXIT);
148         }
149     }
150
151     /**
152      * PUT on the &lt;subscribeUrl&gt; -- not supported.
153      */
154     @Override
155     public void doPut(HttpServletRequest req, HttpServletResponse resp) {
156         setIpFqdnRequestIDandInvocationIDForEelf("doPut", req);
157         eelfLogger.info(EelfMsgs.ENTRY);
158         try {
159             eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_SUBID,
160                     req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");
161             String message = "PUT not allowed for the subscribeURL.";
162             EventLogRecord elr = new EventLogRecord(req);
163             elr.setMessage(message);
164             elr.setResult(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
165             eventlogger.error(elr.toString());
166             sendResponseError(resp, HttpServletResponse.SC_METHOD_NOT_ALLOWED, message, eventlogger);
167         } finally {
168             eelfLogger.info(EelfMsgs.EXIT);
169         }
170     }
171
172     /**
173      * POST on the &lt;subscribeUrl&gt; -- create a new subscription to a feed. See the <i>Creating a Subscription</i>
174      * section in the <b>Provisioning API</b> document for details on how this method should be invoked.
175      */
176     @Override
177     public void doPost(HttpServletRequest req, HttpServletResponse resp) {
178         setIpFqdnRequestIDandInvocationIDForEelf("doPost", req);
179         eelfLogger.info(EelfMsgs.ENTRY);
180         try {
181             eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF, req.getHeader(BEHALF_HEADER));
182             EventLogRecord elr = new EventLogRecord(req);
183             String message = isAuthorizedForProvisioning(req);
184             if (message != null) {
185                 elr.setMessage(message);
186                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);
187                 eventlogger.error(elr.toString());
188                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
189                 return;
190             }
191             if (isProxyServer()) {
192                 super.doPost(req, resp);
193                 return;
194             }
195             String bhdr = req.getHeader(BEHALF_HEADER);
196             if (bhdr == null) {
197                 message = "Missing " + BEHALF_HEADER + " header.";
198                 elr.setMessage(message);
199                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
200                 eventlogger.error(elr.toString());
201                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
202                 return;
203             }
204             int feedid = getIdFromPath(req);
205             if (feedid < 0) {
206                 message = MISSING_FEED;
207                 elr.setMessage(message);
208                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
209                 eventlogger.error(elr.toString());
210                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
211                 return;
212             }
213             Feed feed = Feed.getFeedById(feedid);
214             if (feed == null || feed.isDeleted()) {
215                 message = MISSING_FEED;
216                 elr.setMessage(message);
217                 elr.setResult(HttpServletResponse.SC_NOT_FOUND);
218                 eventlogger.error(elr.toString());
219                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
220                 return;
221             }
222             // check content type is SUB_CONTENT_TYPE, version 1.0
223             ContentHeader ch = getContentHeader(req);
224             String ver = ch.getAttribute("version");
225             if (!ch.getType().equals(SUB_BASECONTENT_TYPE) || !("1.0".equals(ver) || "2.0".equals(ver))) {
226                 intlogger.debug("Content-type is: " + req.getHeader("Content-Type"));
227                 message = "Incorrect content-type";
228                 elr.setMessage(message);
229                 elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
230                 eventlogger.error(elr.toString());
231                 sendResponseError(resp, HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message, eventlogger);
232                 return;
233             }
234             JSONObject jo = getJSONfromInput(req);
235             if (jo == null) {
236                 message = BAD_JSON;
237                 elr.setMessage(message);
238                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
239                 eventlogger.error(elr.toString());
240                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
241                 return;
242             }
243             if (++activeSubs > maxSubs) {
244                 activeSubs--;
245                 message = "Cannot create subscription; the maximum number of subscriptions has been configured.";
246                 elr.setMessage(message);
247                 elr.setResult(HttpServletResponse.SC_CONFLICT);
248                 eventlogger.error(elr.toString());
249                 sendResponseError(resp, HttpServletResponse.SC_CONFLICT, message, eventlogger);
250                 return;
251             }
252             Subscription sub;
253             try {
254                 sub = new Subscription(jo);
255             } catch (InvalidObjectException e) {
256                 activeSubs--;
257                 message = e.getMessage();
258                 elr.setMessage(message);
259                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
260                 eventlogger.error(elr.toString(), e);
261                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
262                 return;
263             }
264             sub.setFeedid(feedid);
265             sub.setSubscriber(bhdr);    // set from X-DMAAP-DR-ON-BEHALF-OF header
266             /*
267              * START - AAF changes
268              * TDP EPIC US# 307413
269              * CADI code - check on permissions based on Legacy/AAF users to allow to create/add subscription
270              */
271             String feedAafInstance = feed.getAafInstance();
272             String subAafInstance = sub.getAafInstance();
273             boolean subAafLegacyEmptyOrNull = (subAafInstance == null
274                                          || "".equals(subAafInstance) || "legacy".equalsIgnoreCase(subAafInstance));
275
276             // This extra check added to verify AAF feed with AAF subscriber having empty aaf instance check
277             if (feedAafInstance == null || "".equals(feedAafInstance) || "legacy".equalsIgnoreCase(feedAafInstance)) {
278                 if (subAafLegacyEmptyOrNull) {
279                     AuthorizationResponse aresp = authz.decide(req);
280                     if (!aresp.isAuthorized()) {
281                         message = POLICY_ENGINE;
282                         elr.setMessage(message);
283                         elr.setResult(HttpServletResponse.SC_FORBIDDEN);
284                         eventlogger.error(elr.toString());
285                         sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
286                         return;
287                     }
288                 } else {
289                     //If Legacy Feed and AAF instance provided in Subscriber JSON
290                     message = "AAF Subscriber can not be added to legacy Feed- " + feedid;
291                     elr.setMessage(message);
292                     elr.setResult(HttpServletResponse.SC_FORBIDDEN);
293                     eventlogger.error(elr.toString());
294                     sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
295                     return;
296                 }
297             } else {
298                 //New AAF Requirement to add legacy subscriber to AAF Feed
299                 if (subAafLegacyEmptyOrNull) {
300                     AuthorizationResponse aresp = authz.decide(req);
301                     if (!aresp.isAuthorized()) {
302                         message = POLICY_ENGINE;
303                         elr.setMessage(message);
304                         elr.setResult(HttpServletResponse.SC_FORBIDDEN);
305                         eventlogger.error(elr.toString());
306                         sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
307                         return;
308                     }
309                 } else {
310                     //New AAF Requirement to add subscriber by publisher on publisher approval only
311                     String permission = getSubscriberPermission(subAafInstance, BaseServlet.APPROVE_SUB_PERMISSION);
312                     eventlogger.info("SubscribeServlet.doPost().. Permission String - " + permission);
313                     if (!req.isUserInRole(permission)) {
314                         message = "AAF disallows access to permission - " + permission;
315                         elr.setMessage(message);
316                         elr.setResult(HttpServletResponse.SC_FORBIDDEN);
317                         eventlogger.error(elr.toString());
318                         sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
319                         return;
320                     }
321                 }
322             }
323             /*
324              * END - AAF changes
325              */
326             // Check if this subscription already exists; not an error (yet), just warn
327             Subscription sub2 = Subscription.getSubscriptionMatching(sub);
328             if (sub2 != null) {
329                 intlogger.warn(
330                     "PROV0011 Creating a duplicate subscription: new subid="
331                             + sub.getSubid() + ", old subid=" + sub2.getSubid());
332             }
333
334             // Create SUBSCRIPTIONS table entries
335             if (doInsert(sub)) {
336                 // send response
337                 elr.setResult(HttpServletResponse.SC_CREATED);
338                 eventlogger.info(elr.toString());
339                 resp.setStatus(HttpServletResponse.SC_CREATED);
340                 resp.setContentType(SUBFULL_CONTENT_TYPE);
341                 resp.setHeader("Location", sub.getLinks().getSelf());
342                 try {
343                     resp.getOutputStream().print(sub.asLimitedJSONObject().toString());
344                 } catch (IOException ioe) {
345                     eventlogger.error("PROV0182 SubscribeServlet.doPost: " + ioe.getMessage(), ioe);
346                 }
347
348                 provisioningDataChanged();
349             } else {
350                 // Something went wrong with the INSERT
351                 activeSubs--;
352                 elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
353                 eventlogger.error(elr.toString());
354                 sendResponseError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, DB_PROBLEM_MSG, eventlogger);
355             }
356         } finally {
357             eelfLogger.info(EelfMsgs.EXIT);
358         }
359     }
360 }