Replace ATT headers
[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 java.io.IOException;
28 import java.io.InvalidObjectException;
29 import java.util.Collection;
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.beans.Subscription;
39 import org.onap.dmaap.datarouter.provisioning.eelf.EelfMsgs;
40 import org.onap.dmaap.datarouter.provisioning.utils.JSONUtilities;
41
42 import com.att.eelf.configuration.EELFLogger;
43 import com.att.eelf.configuration.EELFManager;
44
45 import static org.onap.dmaap.datarouter.provisioning.utils.HttpServletUtils.sendResponseError;
46
47 /**
48  * This servlet handles provisioning for the <subscribeURL> which is generated by the provisioning server to
49  * handle the creation and inspection of subscriptions to a specific feed.
50  *
51  * @author Robert Eby
52  * @version $Id$
53  */
54 @SuppressWarnings("serial")
55 public class SubscribeServlet extends ProxyServlet {
56
57     //Adding EELF Logger Rally:US664892
58     private static EELFLogger eelflogger = EELFManager.getInstance()
59         .getLogger(SubscribeServlet.class);
60
61     /**
62      * DELETE on the <subscribeUrl> -- not supported.
63      */
64     @Override
65     public void doDelete(HttpServletRequest req, HttpServletResponse resp) {
66         setIpFqdnRequestIDandInvocationIDForEelf("doDelete", req);
67         eelflogger.info(EelfMsgs.ENTRY);
68         try {
69             eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_SUBID, 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.info(elr);
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, req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");
91             EventLogRecord elr = new EventLogRecord(req);
92             String message = isAuthorizedForProvisioning(req);
93             if (message != null) {
94                 elr.setMessage(message);
95                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);
96                 eventlogger.info(elr);
97                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
98                 return;
99             }
100             if (isProxyServer()) {
101                 super.doGet(req, resp);
102                 return;
103             }
104             String bhdr = req.getHeader(BEHALF_HEADER);
105             if (bhdr == null) {
106                 message = "Missing " + BEHALF_HEADER + " header.";
107                 elr.setMessage(message);
108                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
109                 eventlogger.info(elr);
110                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
111                 return;
112             }
113             int feedid = getIdFromPath(req);
114             if (feedid < 0) {
115                 message = "Missing or bad feed number.";
116                 elr.setMessage(message);
117                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
118                 eventlogger.info(elr);
119                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
120                 return;
121             }
122             Feed feed = Feed.getFeedById(feedid);
123             if (feed == null || feed.isDeleted()) {
124                 message = "Missing or bad feed number.";
125                 elr.setMessage(message);
126                 elr.setResult(HttpServletResponse.SC_NOT_FOUND);
127                 eventlogger.info(elr);
128                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
129                 return;
130             }
131             // Check with the Authorizer
132             AuthorizationResponse aresp = authz.decide(req);
133             if (!aresp.isAuthorized()) {
134                 message = "Policy Engine disallows access.";
135                 elr.setMessage(message);
136                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);
137                 eventlogger.info(elr);
138                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
139                 return;
140             }
141
142             // Display a list of URLs
143             Collection<String> list = Subscription.getSubscriptionUrlList(feedid);
144             String t = JSONUtilities.createJSONArray(list);
145
146             // send response
147             elr.setResult(HttpServletResponse.SC_OK);
148             eventlogger.info(elr);
149             resp.setStatus(HttpServletResponse.SC_OK);
150             resp.setContentType(SUBLIST_CONTENT_TYPE);
151             try {
152                 resp.getOutputStream().print(t);
153             } catch (IOException ioe) {
154                 eventlogger.error("IOException: " + ioe.getMessage());
155             }
156         } finally {
157             eelflogger.info(EelfMsgs.EXIT);
158         }
159     }
160
161     /**
162      * PUT on the &lt;subscribeUrl&gt; -- not supported.
163      */
164     @Override
165     public void doPut(HttpServletRequest req, HttpServletResponse resp) {
166         setIpFqdnRequestIDandInvocationIDForEelf("doPut", req);
167         eelflogger.info(EelfMsgs.ENTRY);
168         try {
169             eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_SUBID, req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");
170             String message = "PUT not allowed for the subscribeURL.";
171             EventLogRecord elr = new EventLogRecord(req);
172             elr.setMessage(message);
173             elr.setResult(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
174             eventlogger.info(elr);
175             sendResponseError(resp, HttpServletResponse.SC_METHOD_NOT_ALLOWED, message, eventlogger);
176         } finally {
177             eelflogger.info(EelfMsgs.EXIT);
178         }
179     }
180
181     /**
182      * POST on the &lt;subscribeUrl&gt; -- create a new subscription to a feed. See the <i>Creating a Subscription</i>
183      * section in the <b>Provisioning API</b> document for details on how this method should be invoked.
184      */
185     @Override
186     public void doPost(HttpServletRequest req, HttpServletResponse resp) {
187         setIpFqdnRequestIDandInvocationIDForEelf("doPost", req);
188         eelflogger.info(EelfMsgs.ENTRY);
189         try {
190             eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF, req.getHeader(BEHALF_HEADER));
191             EventLogRecord elr = new EventLogRecord(req);
192             String message = isAuthorizedForProvisioning(req);
193             if (message != null) {
194                 elr.setMessage(message);
195                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);
196                 eventlogger.info(elr);
197                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
198                 return;
199             }
200             if (isProxyServer()) {
201                 super.doPost(req, resp);
202                 return;
203             }
204             String bhdr = req.getHeader(BEHALF_HEADER);
205             if (bhdr == null) {
206                 message = "Missing " + BEHALF_HEADER + " header.";
207                 elr.setMessage(message);
208                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
209                 eventlogger.info(elr);
210                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
211                 return;
212             }
213             int feedid = getIdFromPath(req);
214             if (feedid < 0) {
215                 message = "Missing or bad feed number.";
216                 elr.setMessage(message);
217                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
218                 eventlogger.info(elr);
219                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
220                 return;
221             }
222             Feed feed = Feed.getFeedById(feedid);
223             if (feed == null || feed.isDeleted()) {
224                 message = "Missing or bad feed number.";
225                 elr.setMessage(message);
226                 elr.setResult(HttpServletResponse.SC_NOT_FOUND);
227                 eventlogger.info(elr);
228                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
229                 return;
230             }
231             // Check with the Authorizer
232             AuthorizationResponse aresp = authz.decide(req);
233             if (!aresp.isAuthorized()) {
234                 message = "Policy Engine disallows access.";
235                 elr.setMessage(message);
236                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);
237                 eventlogger.info(elr);
238                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
239                 return;
240             }
241
242             // check content type is SUB_CONTENT_TYPE, version 1.0
243             ContentHeader ch = getContentHeader(req);
244             String ver = ch.getAttribute("version");
245             if (!ch.getType().equals(SUB_BASECONTENT_TYPE) || !(ver.equals("1.0") || ver.equals("2.0"))) {
246                 intlogger.debug("Content-type is: " + req.getHeader("Content-Type"));
247                 message = "Incorrect content-type";
248                 elr.setMessage(message);
249                 elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
250                 eventlogger.info(elr);
251                 sendResponseError(resp, HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message, eventlogger);
252                 return;
253             }
254             JSONObject jo = getJSONfromInput(req);
255             if (jo == null) {
256                 message = "Badly formed JSON";
257                 elr.setMessage(message);
258                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
259                 eventlogger.info(elr);
260                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
261                 return;
262             }
263             if (intlogger.isDebugEnabled()) {
264                 intlogger.debug(jo.toString());
265             }
266             if (++activeSubs > maxSubs) {
267                 activeSubs--;
268                 message = "Cannot create subscription; the maximum number of subscriptions has been configured.";
269                 elr.setMessage(message);
270                 elr.setResult(HttpServletResponse.SC_CONFLICT);
271                 eventlogger.info(elr);
272                 sendResponseError(resp, HttpServletResponse.SC_CONFLICT, message, eventlogger);
273                 return;
274             }
275             Subscription sub = null;
276             try {
277                 sub = new Subscription(jo);
278             } catch (InvalidObjectException e) {
279                 activeSubs--;
280                 message = e.getMessage();
281                 elr.setMessage(message);
282                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
283                 eventlogger.info(elr);
284                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
285                 return;
286             }
287             sub.setFeedid(feedid);
288             sub.setSubscriber(bhdr);    // set from X-DMAAP-DR-ON-BEHALF-OF header
289
290             // Check if this subscription already exists; not an error (yet), just warn
291             Subscription sub2 = Subscription.getSubscriptionMatching(sub);
292             if (sub2 != null) {
293                 intlogger.warn(
294                     "PROV0011 Creating a duplicate subscription: new subid=" + sub.getSubid() + ", old subid=" + sub2
295                         .getSubid());
296             }
297
298             // Create SUBSCRIPTIONS table entries
299             if (doInsert(sub)) {
300                 // send response
301                 elr.setResult(HttpServletResponse.SC_CREATED);
302                 eventlogger.info(elr);
303                 resp.setStatus(HttpServletResponse.SC_CREATED);
304                 resp.setContentType(SUBFULL_CONTENT_TYPE);
305                 resp.setHeader("Location", sub.getLinks().getSelf());
306                 try {
307                     resp.getOutputStream().print(sub.asLimitedJSONObject().toString());
308                 } catch (IOException ioe) {
309                     eventlogger.error("IOException: " + ioe.getMessage());
310                 }
311
312                 provisioningDataChanged();
313             } else {
314                 // Something went wrong with the INSERT
315                 activeSubs--;
316                 elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
317                 eventlogger.info(elr);
318                 sendResponseError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, DB_PROBLEM_MSG, eventlogger);
319             }
320         } finally {
321             eelflogger.info(EelfMsgs.EXIT);
322         }
323     }
324 }