1 /*******************************************************************************
2 * ============LICENSE_START==================================================
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
11 * * http://www.apache.org/licenses/LICENSE-2.0
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====================================================
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 ******************************************************************************/
25 package org.onap.dmaap.datarouter.provisioning;
27 import static org.onap.dmaap.datarouter.provisioning.utils.HttpServletUtils.sendResponseError;
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;
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.
52 @SuppressWarnings("serial")
54 public class SubscribeServlet extends ProxyServlet {
56 //Adding EELF Logger Rally:US664892
57 private static EELFLogger eelfLogger = EELFManager.getInstance()
58 .getLogger(SubscribeServlet.class);
61 * DELETE on the <subscribeUrl> -- not supported.
64 public void doDelete(HttpServletRequest req, HttpServletResponse resp) {
65 setIpFqdnRequestIDandInvocationIDForEelf("doDelete", req);
66 eelfLogger.info(EelfMsgs.ENTRY);
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);
77 eelfLogger.info(EelfMsgs.EXIT);
82 * GET on the <subscribeUrl> -- 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.
86 public void doGet(HttpServletRequest req, HttpServletResponse resp) {
87 setIpFqdnRequestIDandInvocationIDForEelf("doGet", req);
88 eelfLogger.info(EelfMsgs.ENTRY);
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);
101 if (isProxyServer()) {
102 super.doGet(req, resp);
105 String bhdr = req.getHeader(BEHALF_HEADER);
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);
114 int feedid = getIdFromPath(req);
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);
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);
132 // Display a list of URLs
133 Collection<String> list = Subscription.getSubscriptionUrlList(feedid);
134 String strList = JSONUtilities.createJSONArray(list);
137 elr.setResult(HttpServletResponse.SC_OK);
138 eventlogger.info(elr.toString());
139 resp.setStatus(HttpServletResponse.SC_OK);
140 resp.setContentType(SUBLIST_CONTENT_TYPE);
142 resp.getOutputStream().print(strList);
143 } catch (IOException ioe) {
144 eventlogger.error("PROV0181 SubscribeServlet.doGet: " + ioe.getMessage(), ioe);
147 eelfLogger.info(EelfMsgs.EXIT);
152 * PUT on the <subscribeUrl> -- not supported.
155 public void doPut(HttpServletRequest req, HttpServletResponse resp) {
156 setIpFqdnRequestIDandInvocationIDForEelf("doPut", req);
157 eelfLogger.info(EelfMsgs.ENTRY);
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);
168 eelfLogger.info(EelfMsgs.EXIT);
173 * POST on the <subscribeUrl> -- 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.
177 public void doPost(HttpServletRequest req, HttpServletResponse resp) {
178 setIpFqdnRequestIDandInvocationIDForEelf("doPost", req);
179 eelfLogger.info(EelfMsgs.ENTRY);
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);
191 if (isProxyServer()) {
192 super.doPost(req, resp);
195 String bhdr = req.getHeader(BEHALF_HEADER);
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);
204 int feedid = getIdFromPath(req);
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);
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);
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);
234 JSONObject jo = getJSONfromInput(req);
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);
243 if (++activeSubs > maxSubs) {
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);
254 sub = new Subscription(jo);
255 } catch (InvalidObjectException e) {
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);
264 sub.setFeedid(feedid);
265 sub.setSubscriber(bhdr); // set from X-DMAAP-DR-ON-BEHALF-OF header
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
271 String feedAafInstance = feed.getAafInstance();
272 String subAafInstance = sub.getAafInstance();
273 boolean subAafLegacyEmptyOrNull = (subAafInstance == null
274 || "".equals(subAafInstance) || "legacy".equalsIgnoreCase(subAafInstance));
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);
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);
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);
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);
326 // Check if this subscription already exists; not an error (yet), just warn
327 Subscription sub2 = Subscription.getSubscriptionMatching(sub);
330 "PROV0011 Creating a duplicate subscription: new subid="
331 + sub.getSubid() + ", old subid=" + sub2.getSubid());
334 // Create SUBSCRIPTIONS table entries
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());
343 resp.getOutputStream().print(sub.asLimitedJSONObject().toString());
344 } catch (IOException ioe) {
345 eventlogger.error("PROV0182 SubscribeServlet.doPost: " + ioe.getMessage(), ioe);
348 provisioningDataChanged();
350 // Something went wrong with the INSERT
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);
357 eelfLogger.info(EelfMsgs.EXIT);