WidgetMSController and WebAnalyticsExtAppVersionController Up 04/96404/2
authorDominik Mizyn <d.mizyn@samsung.com>
Mon, 30 Sep 2019 08:42:17 +0000 (10:42 +0200)
committerDominik Mizyn <d.mizyn@samsung.com>
Thu, 3 Oct 2019 08:25:27 +0000 (10:25 +0200)
WidgetMSController, WebAnalyticsExtAppVersionController,
WebAnalyticsExtAppController Up

Issue-ID: PORTAL-710
Change-Id: Ie1d775e9122aa17d8ee709e793fb6a42d60c91ed
Signed-off-by: Dominik Mizyn <d.mizyn@samsung.com>
portal-BE/pom.xml
portal-BE/src/main/java/org/onap/portal/annotation/ApiVersion.java [new file with mode: 0644]
portal-BE/src/main/java/org/onap/portal/controller/WebAnalyticsExtAppController.java [new file with mode: 0644]
portal-BE/src/main/java/org/onap/portal/controller/WebAnalyticsExtAppVersionController.java [new file with mode: 0644]
portal-BE/src/main/java/org/onap/portal/controller/WidgetMSController.java [new file with mode: 0644]

index 9aed3d5..f31b0a6 100644 (file)
                   <version>4.0.1</version>
                   <scope>compile</scope>
             </dependency>
+            <dependency>
+                  <groupId>io.swagger</groupId>
+                  <artifactId>swagger-annotations</artifactId>
+                  <version>2.0.0-rc2</version>
+                  <scope>compile</scope>
+            </dependency>
+            <dependency>
+                  <groupId>io.swagger</groupId>
+                  <artifactId>swagger-annotations</artifactId>
+                  <version>2.0.0-rc2</version>
+                  <scope>compile</scope>
+            </dependency>
+            <dependency>
+                  <groupId>io.swagger</groupId>
+                  <artifactId>swagger-annotations</artifactId>
+                  <version>1.5.20</version>
+            </dependency>
       </dependencies>
       <properties>
             <docker.image.prefix>portal</docker.image.prefix>
diff --git a/portal-BE/src/main/java/org/onap/portal/annotation/ApiVersion.java b/portal-BE/src/main/java/org/onap/portal/annotation/ApiVersion.java
new file mode 100644 (file)
index 0000000..1c4fafc
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * Modifications Copyright (c) 2019 Samsung
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+
+package org.onap.portal.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ApiVersion {
+       
+       String service() default "";
+       String max()  default "";
+       int min()  default 0;   
+       String method() default "";
+
+}
diff --git a/portal-BE/src/main/java/org/onap/portal/controller/WebAnalyticsExtAppController.java b/portal-BE/src/main/java/org/onap/portal/controller/WebAnalyticsExtAppController.java
new file mode 100644 (file)
index 0000000..849b262
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * Modifications Copyright (c) 2019 Samsung
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+
+package org.onap.portal.controller;
+
+import io.swagger.annotations.ApiOperation;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import javax.servlet.http.HttpServletRequest;
+import lombok.NoArgsConstructor;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.onap.portal.domain.db.fn.FnApp;
+import org.onap.portal.domain.dto.ecomp.EcompAuditLog;
+import org.onap.portal.domain.dto.transport.Analytics;
+import org.onap.portal.logging.aop.EPAuditLog;
+import org.onap.portal.logging.aop.EPEELFLoggerAdvice;
+import org.onap.portal.logging.logic.EPLogUtil;
+import org.onap.portal.service.WidgetMService;
+import org.onap.portal.service.fn.old.AppsCacheService;
+import org.onap.portal.utils.EPCommonSystemProperties;
+import org.onap.portal.utils.EcompPortalUtils;
+import org.onap.portal.utils.PortalConstants;
+import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.onap.portalsdk.core.onboarding.crossapi.PortalAPIResponse;
+import org.onap.portalsdk.core.util.SystemProperties;
+import org.slf4j.MDC;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.concurrent.FailureCallback;
+import org.springframework.util.concurrent.ListenableFuture;
+import org.springframework.util.concurrent.SuccessCallback;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.AsyncRestTemplate;
+
+@RestController
+@RequestMapping(PortalConstants.REST_AUX_API)
+@Configuration
+@EnableAspectJAutoProxy
+@EPAuditLog
+@NoArgsConstructor
+public class WebAnalyticsExtAppController {
+
+       private static final String MACHINE_LEARNING_SERVICE_CTX = "/ml_api";
+       private static final String REGISTER_ACTION = MACHINE_LEARNING_SERVICE_CTX + "/" + "registerAction";
+       private static final String CONSUL_ML_SERVICE_ID = "machine-learning";
+       private static final String APP_KEY = "uebkey";
+       private final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(WebAnalyticsExtAppController.class);
+       private final AsyncRestTemplate restTemplate = new AsyncRestTemplate();
+       private final SuccessCallback<ResponseEntity<String>> successCallback = arg -> logger.info(EELFLoggerDelegate.debugLogger, arg.getBody());
+       private final FailureCallback failureCallback = arg -> logger.error(EELFLoggerDelegate.errorLogger, "storeAuxAnalytics failed", arg);
+
+       private WidgetMService widgetMService;
+       private AppsCacheService appCacheService;
+
+       @Autowired
+       public WebAnalyticsExtAppController(final WidgetMService widgetMService,
+               final AppsCacheService appCacheService) {
+               this.widgetMService = widgetMService;
+               this.appCacheService = appCacheService;
+       }
+
+       /**
+        * Answers requests from partner applications for a file that is expected to
+        * contain javascript to support web analytics.
+        * 
+        * @param request
+        *            HttpServletRequest
+        * @return String
+        */
+       @ApiOperation(value = "Gets javascript with functions that support gathering and reporting web analytics.", response = String.class)
+       @RequestMapping(value = { "/analytics" }, method = RequestMethod.GET, produces = "application/javascript")
+       public String getAnalyticsScript(HttpServletRequest request) {
+               String responseText = "";
+               FnApp app = null;
+               String version = "";
+               try {
+                       app = getApp(request);
+               } catch (Exception e) {
+                       logger.error(EELFLoggerDelegate.errorLogger,
+                                       " Error retrieving Application to capture app name for analytics; Proceeding with empty app name");
+               }
+               if (app != null) {
+                       String restEndPoint = app.getAppRestEndpoint();
+                       if(restEndPoint.indexOf("/api")!=-1) {
+                               version = restEndPoint.substring(restEndPoint.indexOf("api"));
+                       }
+               }
+               String endPoint = "/storeAnalytics";
+               if(StringUtils.isNotBlank(version)) {
+                       endPoint = version + "/storeAnalytics";
+               }
+
+               final String fileName = "analytics.txt";
+               try (InputStream analyticsFileStream = this.getClass().getClassLoader().getResourceAsStream(fileName)) {
+                       responseText = IOUtils.toString(Objects.requireNonNull(analyticsFileStream), StandardCharsets.UTF_8.name());
+               } catch (IOException e) {
+                       logger.error(EELFLoggerDelegate.errorLogger, "Error reading contents of the file " + fileName, e);
+               }
+
+               String feURLContext = SystemProperties.getProperty("frontend_url");
+               String feURL = feURLContext.substring(0, feURLContext.lastIndexOf('/'));
+               responseText = responseText.replace("PORTAL_ENV_URL", feURL);
+               responseText = responseText.replace("$END_POINT", endPoint);
+               return responseText;
+       }
+
+       /**
+        * Accepts data from partner applications with web analytics data.
+        * 
+        * @param request
+        *            HttpServletRequest
+        * @param analyticsMap
+        *            Analytics
+        * @return PortalAPIResponse
+        */
+       @RequestMapping(value = { "/storeAnalytics" }, method = RequestMethod.POST, produces = "application/json")
+       @ResponseBody
+       @ApiOperation(value = "Accepts data from partner applications with web analytics data.", response = PortalAPIResponse.class)
+       public PortalAPIResponse storeAnalyticsScript(HttpServletRequest request, @RequestBody Analytics analyticsMap) {
+               try {
+                       MDC.put(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP, EPEELFLoggerAdvice.getCurrentDateTimeUTC());
+                       String appName = "";
+                       try {
+                               appName = getAppName(request, appName);
+                       } catch (Exception e) {
+                               logger.error(EELFLoggerDelegate.errorLogger,
+                                               " Error retrieving Application to capture app name for analytics; Proceeding with empty app name");
+                       }
+
+                       try {
+                               storeAuxAnalytics(analyticsMap, appName);
+                       } catch (Exception e) {
+                               logger.error(EELFLoggerDelegate.errorLogger,
+                                               " Error retrieving Application to capture app name for analytics; Proceeding with empty app name");
+                       }
+
+                       MDC.put(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP, EPEELFLoggerAdvice.getCurrentDateTimeUTC());
+
+                       EcompPortalUtils.calculateDateTimeDifferenceForLog(
+                                       MDC.get(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP),
+                                       MDC.get(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP));
+                       logger.info(EELFLoggerDelegate.auditLogger,
+                                       EPLogUtil.formatStoreAnalyticsAuditLogMessage(analyticsMap.getUserid(), appName,
+                                                       "WebAnalyticsExtAppController.postWebAnalyticsData",
+                                                       EcompAuditLog.CD_ACTIVITY_STORE_ANALYTICS, analyticsMap.getAction(), analyticsMap.getPage(),
+                                                       analyticsMap.getFunction(), analyticsMap.getType()));
+
+                       MDC.remove(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP);
+                       MDC.remove(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP);
+                       MDC.remove(SystemProperties.MDC_TIMER);
+
+                       return new PortalAPIResponse(true, "success");
+               } catch (Exception e) {
+                       logger.error(EELFLoggerDelegate.errorLogger, "storeAnalytics failed", e);
+                       return new PortalAPIResponse(true, "error");
+               }
+       }
+
+       private String getAppName(HttpServletRequest request, String appName) {
+               
+               FnApp appRecord = getApp(request);
+               if (appRecord != null) {
+                       appName = appRecord.getAppName();
+               }
+               return appName;
+       }
+       
+       private FnApp getApp(HttpServletRequest request) {
+               String appKeyValue = request.getHeader(APP_KEY);
+               FnApp appRecord = null;
+               if (appKeyValue == null || appKeyValue.equals("")) {
+                       logger.error(EELFLoggerDelegate.errorLogger, " App Key unavailable; Proceeding with null app name");
+               } else {
+                        appRecord = appCacheService.getAppFromUeb(appKeyValue);
+               }
+               return appRecord;
+       }
+
+       private void storeAuxAnalytics(Analytics analyticsMap, String appName) {
+               logger.info(EELFLoggerDelegate.debugLogger,
+                               " Registering an action for recommendation: AppName/Function/UserId " + appName + "/"
+                                               + analyticsMap.getFunction() + "/" + analyticsMap.getUserid());
+
+               Map<String, String> requestMapping = new HashMap<>();
+               requestMapping.put("id", analyticsMap.getUserid());
+               requestMapping.put("action", appName + "|" + analyticsMap.getFunction());
+
+               HttpHeaders headers = new HttpHeaders();
+               headers.setContentType(MediaType.APPLICATION_JSON);
+
+               // set your entity to send
+               HttpEntity<Map<String, String>> entity = new HttpEntity<>(requestMapping, headers);
+
+               // send it!
+               ListenableFuture<ResponseEntity<String>> out = restTemplate.exchange(
+                               EcompPortalUtils.widgetMsProtocol() + "://"
+                                               + widgetMService.getServiceLocation(CONSUL_ML_SERVICE_ID,
+                                                               SystemProperties.getProperty("microservices.m-learn.local.port"))
+                                               + REGISTER_ACTION,
+                               HttpMethod.POST, entity, String.class);
+               out.addCallback(successCallback, failureCallback);
+       }
+       
+}
diff --git a/portal-BE/src/main/java/org/onap/portal/controller/WebAnalyticsExtAppVersionController.java b/portal-BE/src/main/java/org/onap/portal/controller/WebAnalyticsExtAppVersionController.java
new file mode 100644 (file)
index 0000000..87be543
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * Modifications Copyright (c) 2019 Samsung
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+
+package org.onap.portal.controller;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.onap.portal.annotation.ApiVersion;
+import org.onap.portal.domain.dto.transport.Analytics;
+import org.onap.portal.logging.aop.EPAuditLog;
+import org.onap.portalsdk.core.onboarding.crossapi.PortalAPIResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+
+@Configuration
+@EnableAspectJAutoProxy
+@EPAuditLog
+@ApiVersion
+public class WebAnalyticsExtAppVersionController {
+
+       private final WebAnalyticsExtAppController webAnalyticsExtAppController;
+
+       @Autowired
+       public WebAnalyticsExtAppVersionController(final
+               WebAnalyticsExtAppController webAnalyticsExtAppController) {
+               this.webAnalyticsExtAppController = webAnalyticsExtAppController;
+       }
+
+       @ApiVersion(max = "v3", service = "/v3/analytics", min = 0,method = "GET")
+       public String getAnalyticsScript(HttpServletRequest request, HttpServletResponse response) throws Exception {
+               return webAnalyticsExtAppController.getAnalyticsScript(request);
+       }
+
+       @ApiVersion(max = "v3", service = "/v3/storeAnalytics", min = 0,method = "POST")
+       public PortalAPIResponse storeAnalyticsScript(HttpServletRequest request, HttpServletResponse response, Analytics analyticsMap) throws Exception {
+               return webAnalyticsExtAppController.storeAnalyticsScript(request, analyticsMap);
+       }
+
+}
diff --git a/portal-BE/src/main/java/org/onap/portal/controller/WidgetMSController.java b/portal-BE/src/main/java/org/onap/portal/controller/WidgetMSController.java
new file mode 100644 (file)
index 0000000..b943482
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * Modifications Copyright (c) 2019 Samsung
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+
+package org.onap.portal.controller;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.onap.portal.domain.dto.ecomp.PortalRestResponse;
+import org.onap.portal.domain.dto.ecomp.PortalRestStatusEnum;
+import org.onap.portal.service.WidgetMService;
+import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/portalApi/consul")
+public class WidgetMSController {
+       private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(WidgetMSController.class);
+
+       private final WidgetMService widgetMService;
+
+       @Autowired
+       public WidgetMSController(final WidgetMService widgetMService) {
+               this.widgetMService = widgetMService;
+       }
+
+       // Get location of a healthy node running our service
+       @RequestMapping(value = { "/service/{service}" }, method = RequestMethod.GET, produces = "application/json")
+       public PortalRestResponse<String> getServiceLocation(HttpServletRequest request, HttpServletResponse response,
+                       @PathVariable("service") String service) {
+
+               try {
+                       return new PortalRestResponse<>(PortalRestStatusEnum.OK, "Success!",
+                                       widgetMService.getServiceLocation(service, null));
+               }
+                catch (Exception e) {
+                       logger.error(EELFLoggerDelegate.errorLogger, "Couldn't get the service location");
+                       return new PortalRestResponse<>(PortalRestStatusEnum.ERROR, "Error!",
+                                       "Couldn't get the service location");
+               
+           }
+       }
+
+}