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 java.io.IOException;
28 import java.io.InvalidObjectException;
29 import java.util.Collection;
31 import javax.servlet.http.HttpServletRequest;
32 import javax.servlet.http.HttpServletResponse;
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;
42 import com.att.eelf.configuration.EELFLogger;
43 import com.att.eelf.configuration.EELFManager;
45 import static org.onap.dmaap.datarouter.provisioning.utils.HttpServletUtils.sendResponseError;
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.
54 @SuppressWarnings("serial")
55 public class SubscribeServlet extends ProxyServlet {
57 //Adding EELF Logger Rally:US664892
58 private static EELFLogger eelfLogger = EELFManager.getInstance()
59 .getLogger(SubscribeServlet.class);
62 * DELETE on the <subscribeUrl> -- not supported.
65 public void doDelete(HttpServletRequest req, HttpServletResponse resp) {
66 setIpFqdnRequestIDandInvocationIDForEelf("doDelete", req);
67 eelfLogger.info(EelfMsgs.ENTRY);
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.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, 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.error(elr.toString());
97 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
100 if (isProxyServer()) {
101 super.doGet(req, resp);
104 String bhdr = req.getHeader(BEHALF_HEADER);
106 message = "Missing " + BEHALF_HEADER + " header.";
107 elr.setMessage(message);
108 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
109 eventlogger.error(elr.toString());
110 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
113 int feedid = getIdFromPath(req);
115 message = MISSING_FEED;
116 elr.setMessage(message);
117 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
118 eventlogger.error(elr.toString());
119 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
122 Feed feed = Feed.getFeedById(feedid);
123 if (feed == null || feed.isDeleted()) {
124 message = MISSING_FEED;
125 elr.setMessage(message);
126 elr.setResult(HttpServletResponse.SC_NOT_FOUND);
127 eventlogger.error(elr.toString());
128 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
131 // Display a list of URLs
132 Collection<String> list = Subscription.getSubscriptionUrlList(feedid);
133 String t = JSONUtilities.createJSONArray(list);
136 elr.setResult(HttpServletResponse.SC_OK);
137 eventlogger.info(elr.toString());
138 resp.setStatus(HttpServletResponse.SC_OK);
139 resp.setContentType(SUBLIST_CONTENT_TYPE);
141 resp.getOutputStream().print(t);
142 } catch (IOException ioe) {
143 eventlogger.error("PROV0181 SubscribeServlet.doGet: " + ioe.getMessage(), ioe);
146 eelfLogger.info(EelfMsgs.EXIT);
151 * PUT on the <subscribeUrl> -- not supported.
154 public void doPut(HttpServletRequest req, HttpServletResponse resp) {
155 setIpFqdnRequestIDandInvocationIDForEelf("doPut", req);
156 eelfLogger.info(EelfMsgs.ENTRY);
158 eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_SUBID, req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");
159 String message = "PUT not allowed for the subscribeURL.";
160 EventLogRecord elr = new EventLogRecord(req);
161 elr.setMessage(message);
162 elr.setResult(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
163 eventlogger.error(elr.toString());
164 sendResponseError(resp, HttpServletResponse.SC_METHOD_NOT_ALLOWED, message, eventlogger);
166 eelfLogger.info(EelfMsgs.EXIT);
171 * POST on the <subscribeUrl> -- create a new subscription to a feed. See the <i>Creating a Subscription</i>
172 * section in the <b>Provisioning API</b> document for details on how this method should be invoked.
175 public void doPost(HttpServletRequest req, HttpServletResponse resp) {
176 setIpFqdnRequestIDandInvocationIDForEelf("doPost", req);
177 eelfLogger.info(EelfMsgs.ENTRY);
179 eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF, req.getHeader(BEHALF_HEADER));
180 EventLogRecord elr = new EventLogRecord(req);
181 String message = isAuthorizedForProvisioning(req);
182 if (message != null) {
183 elr.setMessage(message);
184 elr.setResult(HttpServletResponse.SC_FORBIDDEN);
185 eventlogger.error(elr.toString());
186 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
189 if (isProxyServer()) {
190 super.doPost(req, resp);
193 String bhdr = req.getHeader(BEHALF_HEADER);
195 message = "Missing " + BEHALF_HEADER + " header.";
196 elr.setMessage(message);
197 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
198 eventlogger.error(elr.toString());
199 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
202 int feedid = getIdFromPath(req);
204 message = MISSING_FEED;
205 elr.setMessage(message);
206 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
207 eventlogger.error(elr.toString());
208 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
211 Feed feed = Feed.getFeedById(feedid);
212 if (feed == null || feed.isDeleted()) {
213 message = MISSING_FEED;
214 elr.setMessage(message);
215 elr.setResult(HttpServletResponse.SC_NOT_FOUND);
216 eventlogger.error(elr.toString());
217 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
220 // check content type is SUB_CONTENT_TYPE, version 1.0
221 ContentHeader ch = getContentHeader(req);
222 String ver = ch.getAttribute("version");
223 if (!ch.getType().equals(SUB_BASECONTENT_TYPE) || !("1.0".equals(ver) || "2.0".equals(ver))) {
224 intlogger.debug("Content-type is: " + req.getHeader("Content-Type"));
225 message = "Incorrect content-type";
226 elr.setMessage(message);
227 elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
228 eventlogger.error(elr.toString());
229 sendResponseError(resp, HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message, eventlogger);
232 JSONObject jo = getJSONfromInput(req);
235 elr.setMessage(message);
236 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
237 eventlogger.error(elr.toString());
238 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
241 if (intlogger.isDebugEnabled()) {
242 intlogger.debug(jo.toString());
244 if (++activeSubs > maxSubs) {
246 message = "Cannot create subscription; the maximum number of subscriptions has been configured.";
247 elr.setMessage(message);
248 elr.setResult(HttpServletResponse.SC_CONFLICT);
249 eventlogger.error(elr.toString());
250 sendResponseError(resp, HttpServletResponse.SC_CONFLICT, message, eventlogger);
255 sub = new Subscription(jo);
256 } catch (InvalidObjectException e) {
258 message = e.getMessage();
259 elr.setMessage(message);
260 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
261 eventlogger.error(elr.toString(), e);
262 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
265 sub.setFeedid(feedid);
266 sub.setSubscriber(bhdr); // set from X-DMAAP-DR-ON-BEHALF-OF header
268 * START - AAF changes
269 * TDP EPIC US# 307413
270 * CADI code - check on permissions based on Legacy/AAF users to allow to create/add subscription
272 String feedAafInstance = feed.getAafInstance();
273 String subAafInstance = sub.getAafInstance();
274 boolean subAafLegacyEmptyOrNull = (subAafInstance == null || "".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=" + sub.getSubid() + ", old subid=" + sub2.getSubid());
333 // Create SUBSCRIPTIONS table entries
336 elr.setResult(HttpServletResponse.SC_CREATED);
337 eventlogger.info(elr.toString());
338 resp.setStatus(HttpServletResponse.SC_CREATED);
339 resp.setContentType(SUBFULL_CONTENT_TYPE);
340 resp.setHeader("Location", sub.getLinks().getSelf());
342 resp.getOutputStream().print(sub.asLimitedJSONObject().toString());
343 } catch (IOException ioe) {
344 eventlogger.error("PROV0182 SubscribeServlet.doPost: " + ioe.getMessage(), ioe);
347 provisioningDataChanged();
349 // Something went wrong with the INSERT
351 elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
352 eventlogger.error(elr.toString());
353 sendResponseError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, DB_PROBLEM_MSG, eventlogger);
356 eelfLogger.info(EelfMsgs.EXIT);