1 package org.onap.dcae.dmaapbc.dbcapp.controller;
4 import java.util.HashMap;
8 import javax.servlet.http.HttpServletRequest;
10 import org.onap.dcae.dmaapbc.client.DmaapBcRestClient;
11 import org.onap.dcae.dmaapbc.dbcapp.domain.DmaapAccess;
12 import org.onap.dcae.dmaapbc.model.Dmaap;
13 import org.onap.dcae.dmaapbc.model.DmaapObject;
14 import org.onap.dcae.dmaapbc.model.ErrorResponse;
15 import org.openecomp.portalsdk.core.domain.User;
16 import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
17 import org.openecomp.portalsdk.core.util.SystemProperties;
18 import org.openecomp.portalsdk.core.web.support.UserUtils;
20 import org.springframework.stereotype.Controller;
21 import org.springframework.web.bind.annotation.PathVariable;
22 import org.springframework.web.bind.annotation.RequestMapping;
23 import org.springframework.web.bind.annotation.RequestMethod;
24 import org.springframework.web.bind.annotation.ResponseBody;
26 import com.fasterxml.jackson.databind.ObjectMapper;
29 * DMaaP Access controller: serves Ajax requests made by Angular on pages where
30 * the user adds, edits and deletes DMaaP access profiles. This controller must
31 * defend the database against rogue requests including SQL injection attacks.
35 public class DmaapAccessController extends DbcappRestrictedBaseController {
38 * Logger that conforms with ECOMP guidelines
40 private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(DmaapAccessController.class);
42 private static final String DMAAP_ACCESS_PATH = "/dmaap_access";
43 private static final String SELECT_DMAAP_ACCESS_PATH = "/select_dmaap_access";
46 * For general use in these methods
48 private final ObjectMapper mapper;
51 * Never forget that Spring autowires fields AFTER the constructor is
54 public DmaapAccessController() {
55 mapper = new ObjectMapper();
59 * Gets a list of DMaaP access profiles for this user from the database and
60 * returns them in a JSON array nested within a response object. Traps errors and constructs an appropriate JSON block if an error
63 * See {@link #getOrInitDmaapAccessList(String)}.
67 * @return JSON with access profiles, or an error JSON if the request fails.
69 @RequestMapping(value = { DMAAP_ACCESS_PATH }, method = RequestMethod.GET, produces = "application/json")
71 public String getDmaapAccessList(HttpServletRequest request) {
72 MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, DataBusHomeController.logDateFormat.format(new Date()));
73 logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, DataBusHomeController.APP_NAME);
74 String outboundJson = null;
76 User appUser = UserUtils.getUserSession(request);
77 if (appUser == null || appUser.getLoginId() == null || appUser.getLoginId().length() == 0)
78 throw new Exception("getDmaapAccessList: Failed to get Login ID");
79 List<DmaapAccess> dbAccessList = getOrInitDmaapAccessList(appUser.getLoginId());
80 // Wrap the list in the status indicator.
81 Map<String, Object> model = new HashMap<String, Object>();
82 model.put(STATUS_RESPONSE_KEY, new Integer(200));
83 model.put(DATA_RESPONSE_KEY, dbAccessList);
84 outboundJson = mapper.writeValueAsString(model);
85 } catch (Exception ex) {
86 outboundJson = buildJsonError(500, "Failed to get DMaaP access profile list", ex);
88 MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, DataBusHomeController.logDateFormat.format(new Date()));
89 logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
94 * Adds a DMaaP access profile for the requesting user ID; ignores any
95 * values for row ID and user ID in the body. Traps errors and
96 * constructs an appropriate JSON block if an error happens.
100 * @return Trivial JSON object indicating success or failure.
102 @RequestMapping(value = { DMAAP_ACCESS_PATH }, method = RequestMethod.POST, produces = "application/json")
104 public String addDmaapAccess(HttpServletRequest request) {
105 MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, DataBusHomeController.logDateFormat.format(new Date()));
106 logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, DataBusHomeController.APP_NAME);
107 String outboundJson = null;
109 User appUser = UserUtils.getUserSession(request);
110 if (appUser == null || appUser.getLoginId() == null || appUser.getLoginId().length() == 0)
111 throw new Exception("addDmaapAccess: Failed to get Login ID");
113 DmaapAccess dmaapAccess = mapper.readValue(request.getReader(), DmaapAccess.class);
114 logger.debug("addDmaapAccess: received object: {} ", dmaapAccess);
116 // Null out ID to get an auto-generated ID
117 dmaapAccess.setId(null);
118 // Overwrite any submitted user id
119 dmaapAccess.setUserId(appUser.getLoginId());
121 if (dmaapAccess.getPassword() != null)
122 dmaapAccess.encryptPassword(dmaapAccess.getPassword());
125 getDmaapAccessService().saveDmaapAccess(dmaapAccess);
128 outboundJson = buildJsonSuccess(200, null);
129 } catch (Exception ex) {
130 outboundJson = buildJsonError(500, "Failed to add DMaaP access profile", ex);
132 MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, DataBusHomeController.logDateFormat.format(new Date()));
133 logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
138 * Updates a DMaaP access profile if the row user ID matches the requesting
139 * user ID. Traps errors and
140 * constructs an appropriate JSON block if an error happens.
143 * Path parameter with ID of the DMaaP access profile
146 * @return Trivial JSON object indicating success or failure.
148 @RequestMapping(value = { DMAAP_ACCESS_PATH + "/{id}" }, method = RequestMethod.PUT, produces = "application/json")
150 public String updateDmaapAccess(@PathVariable("id") long id, HttpServletRequest request) {
151 MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, DataBusHomeController.logDateFormat.format(new Date()));
152 logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, DataBusHomeController.APP_NAME);
153 String outboundJson = null;
155 User appUser = UserUtils.getUserSession(request);
156 if (appUser == null || appUser.getLoginId() == null || appUser.getLoginId().length() == 0)
157 throw new Exception("updateDmaapAccess: Failed to get Login ID");
159 DmaapAccess domainObj = getDmaapAccessService().getDmaapAccess(id);
160 if (!appUser.getLoginId().equals(domainObj.getUserId()))
161 throw new Exception("updateDmaapAccess: mismatch of appUser and row user ID");
163 DmaapAccess dmaapAccess = mapper.readValue(request.getReader(), DmaapAccess.class);
164 logger.debug("updateDmaapAccess: received object: {} ", dmaapAccess);
166 // Use the path-parameter id; don't trust the one in the object
167 dmaapAccess.setId(id);
168 // Encrypt password if present
169 if (dmaapAccess.getPassword() != null)
170 dmaapAccess.encryptPassword(dmaapAccess.getPassword());
172 // Update the existing row
173 getDmaapAccessService().saveDmaapAccess(dmaapAccess);
176 outboundJson = buildJsonSuccess(200, null);
177 } catch (Exception ex) {
178 outboundJson = buildJsonError(500, "Failed to update DMaaP access profile", ex);
180 MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, DataBusHomeController.logDateFormat.format(new Date()));
181 logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
186 * Deletes a DMaaP access profile if the row user ID matches the requesting
187 * user ID. Traps errors and
188 * constructs an appropriate JSON block if an error happens.
191 * Path parameter with ID of the DMaaP access profile
194 * @return Trivial JSON object indicating success or failure (altho this is
195 * slightly contrary to conventions for a DELETE method)
197 @RequestMapping(value = {
198 DMAAP_ACCESS_PATH + "/{id}" }, method = RequestMethod.DELETE, produces = "application/json")
200 public String deleteDmaapAccess(@PathVariable("id") long id, HttpServletRequest request) {
201 MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, DataBusHomeController.logDateFormat.format(new Date()));
202 logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, DataBusHomeController.APP_NAME);
203 String outboundJson = null;
205 User appUser = UserUtils.getUserSession(request);
206 if (appUser == null || appUser.getLoginId() == null || appUser.getLoginId().length() == 0)
207 throw new Exception("deleteDmaapAccess: Failed to get Login ID");
208 // Validate that this user owns the row with the specified ID
209 DmaapAccess domainObj = getDmaapAccessService().getDmaapAccess(id);
210 if (!appUser.getLoginId().equals(domainObj.getUserId()))
211 throw new Exception("deleteDmaapAccess: mismatch of appUser and row user ID");
213 getDmaapAccessService().deleteDmaapAccess(id);
216 outboundJson = buildJsonSuccess(200, null);
217 } catch (Exception ex) {
218 outboundJson = buildJsonError(500, "Failed to delete DMaaP access profile", ex);
220 MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, DataBusHomeController.logDateFormat.format(new Date()));
221 logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
226 * Gets the selected DMaaP access row for the requesting user.
228 * See {@link #getSelectedDmaapAccess(String)}
232 * @return JSON object with one DmaapAccessProfile, or an error
234 @RequestMapping(value = { SELECT_DMAAP_ACCESS_PATH }, method = RequestMethod.GET, produces = "application/json")
236 public String getSelectedDmaapAccessProfile(HttpServletRequest request) {
237 MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, DataBusHomeController.logDateFormat.format(new Date()));
238 logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, DataBusHomeController.APP_NAME);
239 String outboundJson = null;
241 User appUser = UserUtils.getUserSession(request);
242 if (appUser == null || appUser.getLoginId() == null || appUser.getLoginId().length() == 0)
243 throw new Exception("getSelectedDmaapAccessProfile: Failed to get Login ID");
244 DmaapAccess selected = super.getSelectedDmaapAccess(appUser.getLoginId());
246 DmaapAccess clear = new DmaapAccess(selected);
248 clear.setPassword(clear.decryptPassword());
249 } catch (Exception ex) {
250 // Should never happen
251 throw new RuntimeException("getSelectedDmaapAccessProfile: Failed to decrypt password", ex);
253 outboundJson = buildJsonSuccess(200, clear);
254 } catch (Exception ex) {
255 outboundJson = buildJsonError(500, "Failed to get selected DMaaP access profile", ex);
257 MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, DataBusHomeController.logDateFormat.format(new Date()));
258 logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
263 * Marks the DMaaP access row as selected (first choice) for the requesting
264 * user if the row user ID matches the requesting user ID. As a side effect,
265 * removes selected marking from all other user rows. Returns status,
266 * additionally an error message on failure. Traps errors and
267 * constructs an appropriate JSON block if an error happens.
269 * Choice of PUT is fairly arbitrary - there is no body, but GET is for
270 * actions that do not change data.
273 * Path parameter with ID of the DMaaP access profile
276 * @return Trivial JSON object indicating success or failure.
278 @RequestMapping(value = {
279 SELECT_DMAAP_ACCESS_PATH + "/{id}" }, method = RequestMethod.PUT, produces = "application/json")
281 public String selectDmaapAccess(@PathVariable("id") long id, HttpServletRequest request) {
282 MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, DataBusHomeController.logDateFormat.format(new Date()));
283 logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, DataBusHomeController.APP_NAME);
284 String outboundJson = null;
286 User appUser = UserUtils.getUserSession(request);
287 if (appUser == null || appUser.getLoginId() == null || appUser.getLoginId().length() == 0)
288 throw new Exception("selectDmaapAccess: Failed to get Login UID");
289 // A little inefficient in that it requires 3 database accesses;
290 // probably could be done in 1 with some sophisticated SQL.
291 List<DmaapAccess> dmaapAccessList = getDmaapAccessService().getDmaapAccessList(appUser.getLoginId());
292 for (DmaapAccess dmaap : dmaapAccessList) {
293 // Only write out the changed rows.
294 boolean changed = false;
295 if (id == dmaap.getId()) {
296 changed = !dmaap.getSelected();
297 dmaap.setSelected(true);
299 changed = dmaap.getSelected();
300 dmaap.setSelected(false);
303 getDmaapAccessService().saveDmaapAccess(dmaap);
307 outboundJson = buildJsonSuccess(200, null);
308 } catch (Exception ex) {
309 outboundJson = buildJsonError(500, "Failed to select a DMaaP access profile", ex);
311 MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, DataBusHomeController.logDateFormat.format(new Date()));
312 logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
317 * Tests the URL in the DMaaP access profile object. Traps errors and
318 * constructs an appropriate JSON block if an error happens.
322 * @return JSON with a Dmaap object (which has name etc.) on success, error
325 @RequestMapping(value = { "test_dmaap_access" }, method = RequestMethod.POST, produces = "application/json")
327 public String testDmaapAccess(HttpServletRequest request) {
328 MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, DataBusHomeController.logDateFormat.format(new Date()));
329 logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, DataBusHomeController.APP_NAME);
330 String outboundJson = null;
332 DmaapAccess dmaapAccess = mapper.readValue(request.getReader(), DmaapAccess.class);
333 logger.debug("testDmaapAccess: received object: {} ", dmaapAccess);
334 if (dmaapAccess.getDmaapUrl() == null || dmaapAccess.getDmaapUrl().trim().length() == 0)
335 throw new Exception("Null or empty URL");
337 DmaapBcRestClient restClient = getDmaapBcRestClient(dmaapAccess);
338 // Get the instance so the page can display its name
339 DmaapObject dmaap = restClient.getDmaap();
340 if (dmaap instanceof Dmaap) {
341 outboundJson = buildJsonSuccess(200, dmaap);
343 // Bad credentials lands here.
344 ErrorResponse err = (ErrorResponse) dmaap;
345 outboundJson = buildJsonError(500, "Test failed: " + err.getMessage(), null);
347 } catch (Exception ex) {
348 // This is entirely likely; e.e., unknown host exception on typo.
349 outboundJson = buildJsonError(500, "Invalid DMaaP URL", ex);
351 MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, DataBusHomeController.logDateFormat.format(new Date()));
352 logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());