From 1faf201e8608dfa4d7af3460fd3d1fc7ebec398b Mon Sep 17 00:00:00 2001 From: talasila Date: Tue, 7 Feb 2017 11:47:55 -0500 Subject: Initial OpenECOMP Portal SDK commit Change-Id: I66a3491600a4b9ea241128dc29267eed6a78ed76 Signed-off-by: talasila --- ecomp-sdk/thirdparty/.gitignore | 1 + ecomp-sdk/thirdparty/README.md | 23 + ecomp-sdk/thirdparty/pom.xml | 93 ++++ .../core/onboarding/client/ECOMPSSOFilter.java | 77 ++++ .../core/onboarding/client/SecureServlet.java | 61 +++ .../core/onboarding/client/UnSecureServlet.java | 61 +++ .../core/onboarding/crossapi/CipherUtil.java | 125 ++++++ .../core/onboarding/crossapi/ECOMPSSO.java | 238 ++++++++++ .../onboarding/crossapi/IPortalRestAPIService.java | 133 ++++++ .../onboarding/crossapi/IPortalUebAPIService.java | 46 ++ .../onboarding/crossapi/PortalAPIException.java | 49 ++ .../onboarding/crossapi/PortalAPIResponse.java | 58 +++ .../onboarding/crossapi/PortalApiConstants.java | 62 +++ .../onboarding/crossapi/PortalApiProperties.java | 98 ++++ .../onboarding/crossapi/PortalRestAPIProxy.java | 498 +++++++++++++++++++++ .../crossapi/PortalTimeoutBindingListener.java | 52 +++ .../onboarding/crossapi/PortalTimeoutHandler.java | 419 +++++++++++++++++ .../core/onboarding/crossapi/PortalTimeoutVO.java | 63 +++ .../onboarding/crossapi/SessionCommunication.java | 161 +++++++ .../onboarding/crossapi/UserContextListener.java | 52 +++ .../onboarding/crossapi/UserSessionListener.java | 84 ++++ .../core/onboarding/rest/FavoritesClient.java | 51 +++ .../core/onboarding/rest/FunctionalMenuClient.java | 54 +++ .../core/onboarding/rest/RestWebServiceClient.java | 178 ++++++++ .../portalsdk/core/onboarding/ueb/Consumer.java | 164 +++++++ .../core/onboarding/ueb/FunctionalMenu.java | 61 +++ .../portalsdk/core/onboarding/ueb/Helper.java | 64 +++ .../portalsdk/core/onboarding/ueb/Publisher.java | 124 +++++ .../core/onboarding/ueb/PublisherList.java | 77 ++++ .../core/onboarding/ueb/TopicManager.java | 121 +++++ .../core/onboarding/ueb/UebException.java | 65 +++ .../portalsdk/core/onboarding/ueb/UebManager.java | 358 +++++++++++++++ .../portalsdk/core/onboarding/ueb/UebMsg.java | 119 +++++ .../portalsdk/core/onboarding/ueb/UebMsgTypes.java | 28 ++ .../onboarding/ueb/WaitingRequestersQueueList.java | 73 +++ .../portalsdk/core/restful/domain/EcompRole.java | 87 ++++ .../portalsdk/core/restful/domain/EcompUser.java | 197 ++++++++ .../core/restful/domain/SharedContext.java | 300 +++++++++++++ 38 files changed, 4575 insertions(+) create mode 100644 ecomp-sdk/thirdparty/.gitignore create mode 100644 ecomp-sdk/thirdparty/README.md create mode 100644 ecomp-sdk/thirdparty/pom.xml create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/ECOMPSSOFilter.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/SecureServlet.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/UnSecureServlet.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/CipherUtil.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/ECOMPSSO.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalRestAPIService.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalUebAPIService.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIException.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIResponse.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiConstants.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiProperties.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalRestAPIProxy.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutBindingListener.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutHandler.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutVO.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/SessionCommunication.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserContextListener.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserSessionListener.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FavoritesClient.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FunctionalMenuClient.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/RestWebServiceClient.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Consumer.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/FunctionalMenu.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Helper.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Publisher.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/PublisherList.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/TopicManager.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebException.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebManager.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsg.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsgTypes.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/WaitingRequestersQueueList.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompRole.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompUser.java create mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/SharedContext.java (limited to 'ecomp-sdk/thirdparty') diff --git a/ecomp-sdk/thirdparty/.gitignore b/ecomp-sdk/thirdparty/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/ecomp-sdk/thirdparty/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/ecomp-sdk/thirdparty/README.md b/ecomp-sdk/thirdparty/README.md new file mode 100644 index 0000000..f916e99 --- /dev/null +++ b/ecomp-sdk/thirdparty/README.md @@ -0,0 +1,23 @@ +ECOMP Portal SDK Framework +========================== + +This is the Maven project for the ECOMP Portal SDK Framework, +which is distributed as ecompFW-nnn.jar. This library +(formerly called third-party onboarding) provides features to +partner applications that use a J2EE Servlet 3.0 container +as Apache Tomcat. These features include: +- REST endpoint for use by the ECOMP Portal aplication. This endpoint + answers queries about roles, users and user-role assignments. + The endpoint methods are defined by the Java interface class + IPortalRestAPIService. Application developers must provide a + class that implements this interface, and publish the name of + that class in the properties file as discussed below. +- A session listener that updates a collection with current user sessions + as sessions are created and destroyed. This information is used to maintain + and extend user session timeouts across applications that are on-boarded to + the ECOMP portal. +- Communication with the ECOMP Portal to fetch a user-specific functional menu, either + via REST or UEB. + +Unlike the other ECOMP SDK libraries, this library does NOT require Hibernate, +nor does it require Spring. \ No newline at end of file diff --git a/ecomp-sdk/thirdparty/pom.xml b/ecomp-sdk/thirdparty/pom.xml new file mode 100644 index 0000000..f98fed2 --- /dev/null +++ b/ecomp-sdk/thirdparty/pom.xml @@ -0,0 +1,93 @@ + + 4.0.0 + + + org.openecomp.ecompsdkos + ecompSDK-project + 1.0.0 + + + + ecompFW + + jar + Ecomp Portal Framework (thirdparty) + + + + + + + + + + + + src/main/java + + **/portal*.properties + + + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.6 + + + **/com/att/fusion/core/onboarding/client/* + + + + ${project.version} + ${sdk-internal.version} + + + + + + + + + + + + + + + javax.servlet + javax.servlet-api + 3.0.1 + + + commons-logging + commons-logging + 1.2 + + + com.fasterxml.jackson.core + jackson-annotations + 2.6.3 + + + com.fasterxml.jackson.core + jackson-databind + 2.6.3 + + + + + com.att.nsa + cambriaClient + 0.0.1 + + + + + + diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/ECOMPSSOFilter.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/ECOMPSSOFilter.java new file mode 100644 index 0000000..0fc6499 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/ECOMPSSOFilter.java @@ -0,0 +1,77 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.client; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.openecomp.portalsdk.core.onboarding.crossapi.ECOMPSSO; + +/** + * This is an example filter that uses the ecompFW library to require the + */ +@WebFilter("/secure/*") +public class ECOMPSSOFilter implements Filter { + + /* + * (non-Javadoc) + * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) + */ + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws java.io.IOException, ServletException { + if (ECOMPSSO.valdiateECOMPSSO((HttpServletRequest) request) == null) { + String redirectURL = ECOMPSSO.getECOMPSSORedirectURL(((HttpServletRequest) request), + ((HttpServletResponse) response), + (((HttpServletRequest) request).getRequestURI() + .substring(((HttpServletRequest) request).getContextPath().length() + 1) + + (((HttpServletRequest) request).getQueryString() != null + ? ("?" + ((HttpServletRequest) request).getQueryString()) : ""))); + ((HttpServletResponse) response).sendRedirect(redirectURL); + } else { + // Pass request back down the filter chain + chain.doFilter(request, response); + } + } + + /* + * (non-Javadoc) + * + * @see javax.servlet.Filter#destroy() + */ + public void destroy() { + // Called before the Filter instance is removed from service + } + + /* + * (non-Javadoc) + * + * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) + */ + public void init(FilterConfig arg0) throws ServletException { + // Called before the filter instance is installed into service. + } +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/SecureServlet.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/SecureServlet.java new file mode 100644 index 0000000..9a583d3 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/SecureServlet.java @@ -0,0 +1,61 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.client; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Servlet implementation class SecureServlet + */ +@WebServlet("/secure/SecureServlet") +public class SecureServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + /** + * @see HttpServlet#HttpServlet() + */ + public SecureServlet() { + super(); + // TODO Auto-generated constructor stub + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) + */ + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // TODO Auto-generated method stub + response.getWriter().append("Served at: ").append(request.getContextPath()); + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) + */ + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // TODO Auto-generated method stub + doGet(request, response); + } + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/UnSecureServlet.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/UnSecureServlet.java new file mode 100644 index 0000000..d5cd275 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/UnSecureServlet.java @@ -0,0 +1,61 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.client; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Servlet implementation class SecureServlet + */ +@WebServlet("/unsecure/SecureServlet") +public class UnSecureServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + /** + * @see HttpServlet#HttpServlet() + */ + public UnSecureServlet() { + super(); + // TODO Auto-generated constructor stub + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) + */ + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // TODO Auto-generated method stub + response.getWriter().append("Served at: ").append(request.getContextPath()); + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) + */ + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // TODO Auto-generated method stub + doGet(request, response); + } + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/CipherUtil.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/CipherUtil.java new file mode 100644 index 0000000..d355e10 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/CipherUtil.java @@ -0,0 +1,125 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.crossapi; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; + +import org.apache.commons.codec.binary.Base64; + +public class CipherUtil { + + private final static String key = "AGLDdG4D04BKm2IxIWEr8o==!"; + + /** + * @param plainText + * @param secretKey + * @return encrypted version of plain text. + * @throws Exception + */ + public static String encrypt(String plainText, String secretKey) throws Exception{ + byte[] rawKey; + String encryptedString; + SecretKeySpec sKeySpec; + byte[] encryptText = plainText.getBytes("UTF-8"); + Cipher cipher; + rawKey = Base64.decodeBase64(secretKey); + sKeySpec = new SecretKeySpec(rawKey, "AES"); + cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.ENCRYPT_MODE, sKeySpec); + encryptedString = Base64.encodeBase64String(cipher.doFinal(encryptText)); + + return encryptedString; + } + + /** + * + * @param plainText + * @return Encrypted Text + * @throws Exception + */ + public static String encrypt(String plainText) throws Exception + { + return CipherUtil.encrypt(plainText,key); + } + + /** + * @param encryptedText + * @param secretKey + * @return plain text version of encrypted text + * @throws Exception + */ + public static String decrypt(String encryptedText, String secretKey) throws Exception { + Cipher cipher; + String encryptedString; + byte[] encryptText = null; + byte[] rawKey; + SecretKeySpec sKeySpec; + + rawKey = Base64.decodeBase64(secretKey); + sKeySpec = new SecretKeySpec(rawKey, "AES"); + encryptText = Base64.decodeBase64(encryptedText.getBytes("UTF-8")); + cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.DECRYPT_MODE, sKeySpec); + encryptedString = new String(cipher.doFinal(encryptText)); + + return encryptedString; + } + + /** + * @param encryptedText + * @return Decrypted Text + * @throws Exception + */ + public static String decrypt(String encryptedText) throws Exception + { + return CipherUtil.decrypt(encryptedText,key); + } + + + public static void main(String[] args) throws Exception { + + String password = "Welcome123"; + String encrypted; + String decrypted; + + if (args.length != 2) { + System.out.println("Default password testing... "); + System.out.println("Plain password: " + password); + encrypted = encrypt(password); + System.out.println("Encrypted password: " + encrypted); + decrypted = decrypt(encrypted); + System.out.println("Decrypted password: " + decrypted); + } else { + String whatToDo = args[0]; + if (whatToDo.equalsIgnoreCase("d")) { + encrypted = args[1]; + System.out.println("Encrypted Text: " + encrypted); + decrypted = decrypt(encrypted); + System.out.println("Decrypted Text: " + decrypted); + } else { + decrypted = args[1]; + System.out.println("Plain Text: " + decrypted); + encrypted = encrypt(decrypted); + System.out.println("Encrypted Text" + encrypted); + } + } + } +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/ECOMPSSO.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/ECOMPSSO.java new file mode 100644 index 0000000..8fc2ec5 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/ECOMPSSO.java @@ -0,0 +1,238 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.crossapi; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + + +/** + * Provides authentication service for onboarded ECOMP applications. + */ +public class ECOMPSSO { + + private static final String EP_SERVICE = "EPService"; + private static final String USER_ID = "UserId"; + + private static final Log logger = LogFactory.getLog(ECOMPSSO.class); + + + public static String valdiateECOMPSSO(HttpServletRequest request) { + // Check ECOMP Portal cookie + if (!isLoginCookieExist(request)) + return null; + + String userid = null; + try { + userid = getUserIdFromCookie(request); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return userid; + } + + public static String getUserIdFromCookie(HttpServletRequest request) throws Exception { + String userId = ""; + Cookie[] cookies = request.getCookies(); + Cookie userIdcookie = null; + if (cookies != null) + for (Cookie cookie : cookies) + if (cookie.getName().equals(USER_ID)) + userIdcookie = cookie; + if(userIdcookie!=null){ + userId = CipherUtil.decrypt(userIdcookie.getValue(), + PortalApiProperties.getProperty(PortalApiConstants.Decryption_Key)); + } + return userId; + + } + + /** + * Builds a redirect URL from properties file and the specified relative + * path in this app. The intent is to take the user to the portal, which + * will redirect the user to Global Log On, and finally the user will be + * returned to the app. + * + * @param request + * HttpServletRequest + * @param response + * HttpServletResponse + * @param forwardPath + * portion of the application path after the protocol, server and + * context path plus any query parameters; e.g., "welcome.html"; + * empty string is allowed. + * @return URL that redirects user to ECOMP Portal for login. + */ + public static String getECOMPSSORedirectURL(HttpServletRequest request, HttpServletResponse response, + String forwardPath) { + // Construct a path for this server, this app's context, etc. + String appURL = (request.isSecure() ? "https://" : "http://") + request.getServerName() + ":" + + request.getServerPort() + request.getContextPath() + "/" + forwardPath; + String encodedAppURL = null; + try { + encodedAppURL = URLEncoder.encode(appURL, "UTF-8"); + } catch (UnsupportedEncodingException ex) { + // should never happen + logger.error("getECOMPSSORedirectURL: Failed to encode app URL " + appURL); + } + String portalURL = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL); + if (portalURL == null || portalURL.length() == 0) { + logger.error("getECOMPSSORedirectURL: Failed to get property " + PortalApiConstants.ECOMP_REDIRECT_URL); + return null; + } + String redirectURL = portalURL + "?redirectUrl=" + encodedAppURL; + return redirectURL; + } + + /** + * Answers whether the ECOMP Portal service cookie is present in the + * specified request. + * + * @param request + * @return true if the cookie is found, else false. + */ + private static boolean isLoginCookieExist(HttpServletRequest request) { + Cookie ep = getCookie(request, EP_SERVICE); + return (ep != null); + } + + /** + * Searches the request for a cookie with the specified name. + * + * @param request + * @param cookieName + * @return Cookie, or null if not found. + */ + public static Cookie getCookie(HttpServletRequest request, String cookieName) { + Cookie[] cookies = request.getCookies(); + if (cookies != null) + for (Cookie cookie : cookies) + if (cookie.getName().equals(cookieName)) + return cookie; + + return null; + } + + /** + * Splits a string into an array. + * + * @param str + * @param delimiter + * @return + */ + private static String[] delimitedListToStringArray(String str, String delimiter) { + return delimitedListToStringArray(str, delimiter, null); + } + + /** + * Splits a string into an array, optionally deleting characters. + * + * @param str + * String to be split + * @param delimiter + * Token to use as the delimiter + * @param charsToDelete + * Optional String of characters to be removed; ignored if null + * @return String array; empty if the input is null or delimiter are null. + */ + private static String[] delimitedListToStringArray(String str, String delimiter, String charsToDelete) { + if (str == null) + return new String[0]; + if (delimiter == null) + return new String[] { str }; + + List result = new ArrayList(); + if ("".equals(delimiter)) { + for (int i = 0; i < str.length(); i++) { + result.add(deleteAny(str.substring(i, i + 1), charsToDelete)); + } + } else { + int pos = 0; + int delPos = 0; + while ((delPos = str.indexOf(delimiter, pos)) != -1) { + result.add(deleteAny(str.substring(pos, delPos), charsToDelete)); + pos = delPos + delimiter.length(); + } + if (str.length() > 0 && pos <= str.length()) { + // Add rest of String, but not in case of empty input. + result.add(deleteAny(str.substring(pos), charsToDelete)); + } + } + return toStringArray(result); + } + + /** + * Convenience method that creates a string array from the items in the + * collection. + * + * @param collection + * @return + */ + private static String[] toStringArray(Collection collection) { + if (collection == null) + return null; + return (String[]) collection.toArray(new String[collection.size()]); + } + + /** + * Builds a new string that has none of the characters in the charsToDelete + * argument. + * + * @param inString + * @param charsToDelete + * @return Input string after removing all characters in the second + * argument. + */ + private static String deleteAny(String inString, String charsToDelete) { + if (!hasLength(inString) || !hasLength(charsToDelete)) { + return inString; + } + StringBuffer out = new StringBuffer(); + for (int i = 0; i < inString.length(); i++) { + char c = inString.charAt(i); + if (charsToDelete.indexOf(c) == -1) { + out.append(c); + } + } + return out.toString(); + } + + /** + * + * @param str + * @return + */ + private static boolean hasLength(String str) { + return (str != null && str.length() > 0); + } + + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalRestAPIService.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalRestAPIService.java new file mode 100644 index 0000000..25a8aef --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalRestAPIService.java @@ -0,0 +1,133 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.crossapi; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.portalsdk.core.restful.domain.EcompRole; +import org.openecomp.portalsdk.core.restful.domain.EcompUser; + +/** + * Defines the REST API Interface that an onboarding non-SDK (i.e., third-party) + * application must implement to answer queries and accept updates from the + * ECOMP Portal about the application's users, roles and user-role assignments. + * + * @author Ikram Ikramullah + */ +public interface IPortalRestAPIService { + + // EcompUser Interface + + /** + * Creates a new user. + * + * @param user + * Model object with attributes of user to be created. + * @throws PortalAPIException + * If any error occurs while processing the request; for + * example, user exists already. + */ + public void pushUser(EcompUser user) throws PortalAPIException; + + /** + * Updates an existing user's attributes. + * + * @param loginId + * EcompUser ID to be updated. + * @param user + * Model object with attributes of user to be updated. + * @throws PortalAPIException + * If any error occurs while processing the request; for + * example, unknown user. + */ + public void editUser(String loginId, EcompUser user) throws PortalAPIException; + + /** + * Gets details about an existing user. + * + * @param loginId + * EcompUser ID to be fetched + * @return Model object with user attributes. + * @throws PortalAPIException + * If any error occurs while processing the request; for + * example, unknown user. + */ + public EcompUser getUser(String loginId) throws PortalAPIException; + + /** + * Gets all users. + * + * @return List of user attribute model objects; empty array if none are + * found. + * @throws PortalAPIException + * If any error occurs while processing the request. + */ + public List getUsers() throws PortalAPIException; + + // Roles Interface + + /** + * Gets all defined roles. + * + * @return List of role attribute objects; empty array if none are + * found. + * @throws PortalAPIException + * If an unexpected error occurs while processing the request. + */ + public List getAvailableRoles() throws PortalAPIException; + + /** + * Replaces existing user roles with new roles. + * + * @param loginId + * EcompUser ID to be updated. + * @param roles + * List of model objects with role attributes + * @throws PortalAPIException + * If any error occurs while processing the request. + */ + public void pushUserRole(String loginId, List roles) throws PortalAPIException; + + /** + * Gets the roles defined for the specified user. + * + * @param loginId + * @return List of model objects; empty if no roles are found. + * @throws PortalAPIException + * If any error occurs while processing the request; e.g., user + * not found. + */ + public List getUserRoles(String loginId) throws PortalAPIException; + + // Security Interface + + /** + * Answers whether the request is authenticated. + * + * @param request + * @return true if the request contains appropriate credentials, else false. + * @throws PortalAPIException + * If an unexpected error occurs while processing the request. + */ + public boolean isAppAuthenticated(HttpServletRequest request) throws PortalAPIException; + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalUebAPIService.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalUebAPIService.java new file mode 100644 index 0000000..0b55a96 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalUebAPIService.java @@ -0,0 +1,46 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.crossapi; + + +/** + * + * @author Ikram Ikramullah + * + * UEB API Interface for all the onboarding third party applications. + * + */ + +public interface IPortalUebAPIService { + //User Interface + public String pushUser(String userJson) throws PortalAPIException; + public String editUser(String loginId, String userJson) throws PortalAPIException; + public String getUser(String loginId) throws PortalAPIException; + public String getUsers() throws PortalAPIException; + + //Roles Interface + public String getAvailableRoles() throws PortalAPIException; + public String getAvailableFullRoles() throws PortalAPIException; + public String pushUserRole(String loginId, String rolesJson) throws PortalAPIException; + public String getUserRoles(String loginId) throws PortalAPIException; + + //Security Interface + public boolean isAppAuthenticated(String appUserName, String appPassword) throws PortalAPIException; +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIException.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIException.java new file mode 100644 index 0000000..8a4c9e4 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIException.java @@ -0,0 +1,49 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.crossapi; + +/** + * @author Ikram Ikramullah + */ +public class PortalAPIException extends Exception{ + + private static final long serialVersionUID = 4854048794984375707L; + + public PortalAPIException() { + super(); + } + + public PortalAPIException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public PortalAPIException(String message, Throwable cause) { + super(message, cause); + } + + public PortalAPIException(String message) { + super(message); + } + + public PortalAPIException(Throwable cause) { + super(cause); + } + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIResponse.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIResponse.java new file mode 100644 index 0000000..f8d73ac --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIResponse.java @@ -0,0 +1,58 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.crossapi; + +/** + * This bean holds a response that is returned by the role and user-management + * REST API. + */ +public class PortalAPIResponse { + + /** + * Either "ok" or "error" + */ + private String status; + /** + * Optional if status is ok + */ + private String message; + + public PortalAPIResponse(boolean isOk, String msg) { + status = (isOk? "ok" : "error"); + message = msg; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiConstants.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiConstants.java new file mode 100644 index 0000000..667ad28 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiConstants.java @@ -0,0 +1,62 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.crossapi; + +public interface PortalApiConstants { + public static final String API_PREFIX = "/api"; + public static final String PORTAL_JSESSION_ID = "PORTAL_JSESSION_ID"; + public static final String PORTAL_JSESSION_BIND = "PORTAL_JSESSION_BIND"; + public static final String ACTIVE_USERS_NAME = "activeUsers"; + + /** Portal service cookie name */ + public static final String EP_SERVICE = "EPService"; + + public static final String GLOBAL_SESSION_MAX_IDLE_TIME = "global_session_max_idle_time"; + public static final String PORTAL_SESSION_SLOT_CHECK = "portal_session_slot_check"; + public static final String SESSION_PREVIOUS_ACCESS_TIME = "session_previous_access_time"; + public static final String MAX_IDLE_TIME = "max.idle.time"; + + // Names of keys in the portal.properties file + public static final String PORTAL_API_IMPL_CLASS = "portal.api.impl.class"; + public static final String ECOMP_REDIRECT_URL = "ecomp_redirect_url"; + public static final String ECOMP_REST_URL = "ecomp_rest_url"; + + // UEB related + public static final String UEB_URL_LIST = "ueb_url_list"; // In properties file + public static final String ECOMP_PORTAL_INBOX_NAME = "ecomp_portal_inbox_name"; + public static final String ECOMP_DEFAULT_MSG_ID = "0"; + public static final String ECOMP_GENERAL_UEB_PARTITION = "EPGeneralPartition"; + public static final String UEB_LISTENERS_ENABLE = "ueb_listeners_enable"; + public static final String UEB_APP_INBOUND_MAILBOX_NAME = "ueb_app_mailbox_name"; + public static final String UEB_APP_CONSUMER_GROUP_NAME = "ueb_app_consumer_group_name"; + // UebManager generates a consumer group name for special token {UUID} + public static final String UEB_APP_CONSUMER_GROUP_NAME_GENERATOR = "{UUID}"; + public static final String UEB_APP_KEY = "ueb_app_key"; + public static final String UEB_APP_SECRET = "ueb_app_secret"; + public static final String ECOMP_UEB_INVALID_MSG = "100: Invalid Message format."; + public static final String ECOMP_UEB_TIMEOUT_ERROR = "101: Timeout"; + public static final String ECOMP_UEB_UNKNOWN_PUBLISH_ERROR = "102: Unknown error during publish"; + public static final String ECOMP_UEB_UNKNOWN_CONSUME_ERROR = "103: Unknown error during consume"; + public static final String USE_REST_FOR_FUNCTIONAL_MENU = "use_rest_for_functional_menu"; + + //encrpt key + public static final String Decryption_Key = "decryption_key"; + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiProperties.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiProperties.java new file mode 100644 index 0000000..b9853a9 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiProperties.java @@ -0,0 +1,98 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.crossapi; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Singleton Class representing portal properties. Searches the classpath for + * the file "portal.properties". + * + * To put the file "portal.properties" on the classpath, it can be in the same + * directory where the first package folder is - 'myClasses' folder in the + * following case as an example: + * + */ +public class PortalApiProperties { + + private static final Log logger = LogFactory.getLog(PortalApiProperties.class); + + private static Properties properties; + private static String propertyFileName = "portal.properties"; + + /** + * Constructor is private. + */ + private PortalApiProperties() { + } + + /** + * Gets the property value for the specified key. + * + * @param property + * @return Value for the named property; null if the property file was not + * loaded or the key was not found. + */ + public static String getProperty(String property) { + if (properties == null) { + synchronized (propertyFileName) { + try { + if (!initialize()) { + logger.error("Failed to read property file " + propertyFileName); + return null; + } + } catch (IOException e) { + logger.error("Failed to read property file " + propertyFileName, e); + return null; + } + } + } + return properties.getProperty(property); + } + + /** + * Reads properties from a portal.properties file on the classpath. + * + * Clients DO NOT need to call this method. Clients MAY call this method to + * test whether the properties file can be loaded successfully. + * + * @return True if properties were successfully loaded, else false. + * @throws IOException + */ + public static boolean initialize() throws IOException { + if (properties != null) + return true; + InputStream in = PortalApiProperties.class.getClassLoader().getResourceAsStream(propertyFileName); + if (in == null) + return false; + properties = new Properties(); + try { + properties.load(in); + } finally { + in.close(); + } + return true; + } +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalRestAPIProxy.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalRestAPIProxy.java new file mode 100644 index 0000000..3012d1c --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalRestAPIProxy.java @@ -0,0 +1,498 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.crossapi; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.restful.domain.EcompRole; +import org.openecomp.portalsdk.core.restful.domain.EcompUser; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * This servlet responds to ECOMP Portal API calls to query and update user, + * role and user-role information. It registers itself at a path like "/api" + * (see {@link PortalApiConstants#API_PREFIX}) and proxies all requests on to a + * class that implements {@link IPortalRestAPIService}, as named in the required + * properties file ("portal.properties"). The servlet will not start if the + * properties file is not found. + * + * Implements the interface solely to ensure that changes to the interface are + * made here also, the compiler helps catch problems that way. + * + * @author Ikram Ikramullah + */ + +@WebServlet(urlPatterns = { PortalApiConstants.API_PREFIX + "/*" }) +public class PortalRestAPIProxy extends HttpServlet implements IPortalRestAPIService { + private static final long serialVersionUID = 1L; + + private final Log logger = LogFactory.getLog(getClass()); + + /** + * JSON to object etc. + */ + private final ObjectMapper mapper = new ObjectMapper(); + + /** + * Client-supplied class that implements our interface. + */ + private IPortalRestAPIService portalRestApiService; + + public PortalRestAPIProxy() { + // Ensure that any additional fields sent by the Portal + // will be ignored when creating objects. + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + + @Override + public void init() throws ServletException { + String className = PortalApiProperties.getProperty(PortalApiConstants.PORTAL_API_IMPL_CLASS); + if (className == null) + throw new ServletException( + "init: Failed to find class name property " + PortalApiConstants.PORTAL_API_IMPL_CLASS); + try { + logger.debug("init: creating instance of class " + className); + Class implClass = Class.forName(className); + portalRestApiService = (IPortalRestAPIService) (implClass.getConstructor().newInstance()); + } catch (Exception ex) { + throw new ServletException("init: Failed to find or instantiate class " + className, ex); + } + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { + + if (portalRestApiService == null) { + // Should never happen due to checks in init() + logger.error("doPost: no service class instance"); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + response.getWriter().write(buildJsonResponse(false, "Misconfigured - no instance of service class")); + return; + } + boolean secure = false; + try { + secure = isAppAuthenticated(request); + } catch (PortalAPIException ex) { + logger.error("doPost: isAppAuthenticated threw exception", ex); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + response.getWriter().write(buildJsonResponse(false, "Failed to authenticate request")); + return; + } + if (!secure) { + if (logger.isDebugEnabled()) + logger.debug("doPost: isAppAuthenticated answered false"); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + writeAndFlush(response, buildJsonResponse(false, "Not authorized")); + return; + } + + String requestUri = request.getRequestURI(); + try { + String requestBody = readRequestBody(request); + if (logger.isDebugEnabled()) + logger.debug("doPost: URI = " + requestUri + ", payload = " + requestBody); + + /* + * All APIs: + * + * 1. /user <-- save user + * + * 2. /user/{loginId} <-- edit user + * + * 3. /user/{loginId}/roles <-- save roles for user + */ + + // On success return the empty string. + String responseJson = ""; + if (requestUri.endsWith("/updateSessionTimeOuts")) { + if (updateSessionTimeOuts(requestBody)) { + if (logger.isDebugEnabled()) + logger.debug("doPost: updated session timeouts"); + response.setStatus(HttpServletResponse.SC_OK); + } else { + String msg = "Failed to update session time outs"; + logger.error("doPost: " + msg); + responseJson = buildJsonResponse(false, msg); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } else if (requestUri.endsWith("/timeoutSession")) { + String portalJSessionId = request.getParameter("portalJSessionId"); + if (portalJSessionId == null) { + portalJSessionId = ""; + } + if (timeoutSession(portalJSessionId)) { + if (logger.isDebugEnabled()) + logger.debug("doPost: timed out session"); + response.setStatus(HttpServletResponse.SC_OK); + } else { + String msg = "Failed to timeout session"; + logger.error("doPost: " + msg); + responseJson = buildJsonResponse(false, msg); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } else + // Example: /user <-- create user + if (requestUri.endsWith(PortalApiConstants.API_PREFIX + "/user")) { + try { + EcompUser user = mapper.readValue(requestBody, EcompUser.class); + pushUser(user); + if (logger.isDebugEnabled()) + logger.debug("doPost: pushUser: success"); + responseJson = buildJsonResponse(true, null); + response.setStatus(HttpServletResponse.SC_OK); + } catch (Exception ex) { + responseJson = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.error("doPost: pushUser: caught exception", ex); + } + } else + // Example: /user/fi241c <-- edit user fi241c + if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && !(requestUri.endsWith("/roles"))) { + String loginId = requestUri.substring(requestUri.lastIndexOf('/') + 1); + try { + EcompUser user = mapper.readValue(requestBody, EcompUser.class); + editUser(loginId, user); + if (logger.isDebugEnabled()) + logger.debug("doPost: editUser: success"); + responseJson = buildJsonResponse(true, null); + response.setStatus(HttpServletResponse.SC_OK); + } catch (Exception ex) { + responseJson = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.error("doPost: editUser: caught exception", ex); + } + } else + // Example: /user/{loginId}/roles <-- save roles for user + if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && requestUri.endsWith("/roles")) { + String loginId = requestUri.substring(requestUri.indexOf("/user/") + ("/user").length() + 1, + requestUri.lastIndexOf('/')); + try { + TypeReference> typeRef = new TypeReference>() { + }; + List roles = mapper.readValue(requestBody, typeRef); + pushUserRole(loginId, roles); + if (logger.isDebugEnabled()) + logger.debug("doPost: pushUserRole: success"); + responseJson = buildJsonResponse(true, null); + response.setStatus(HttpServletResponse.SC_OK); + } catch (Exception ex) { + responseJson = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.error("doPost: pushUserRole: caught exception", ex); + } + } else { + logger.warn("doPost: no match for request " + requestUri); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + } + writeAndFlush(response, responseJson); + } catch (Exception ex) { + logger.error("doPost: Failed to process request " + requestUri, ex); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + writeAndFlush(response, ex.toString()); + } + + } + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { + + if (portalRestApiService == null) { + // Should never happen due to checks in init() + logger.error("doGet: no service class instance"); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + writeAndFlush(response, buildJsonResponse(false, "Misconfigured - no instance of service class")); + return; + } + boolean secure = false; + try { + secure = isAppAuthenticated(request); + } catch (PortalAPIException ex) { + logger.error("doGet: isAppAuthenticated threw exception", ex); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + writeAndFlush(response, buildJsonResponse(false, "Failed to authenticate request")); + return; + } + if (!secure) { + if (logger.isDebugEnabled()) + logger.debug("doGet: isAppAuthenticated answered false"); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + writeAndFlush(response, buildJsonResponse(false, "Not authorized")); + return; + } + + String requestUri = request.getRequestURI(); + try { + // Ignore any request body in a GET. + // String requestBody = readRequestBody(request); + if (logger.isDebugEnabled()) + logger.debug("doGet: URI = " + requestUri); + + String responseJson = ""; + /* + * 1. /roles <-- get roles + * + * 2. /user/{loginId} <-- get user + * + * 3. /users <-- get all users + * + * 4. /user/{loginId}/roles <-- get roles for user + */ + + if (requestUri.endsWith("/sessionTimeOuts")) { + responseJson = getSessionTimeOuts(); + if (responseJson != null && responseJson.length() > 0) { + if (logger.isDebugEnabled()) + logger.debug("doGet: got session timeouts"); + response.setStatus(HttpServletResponse.SC_OK); + } else { + String msg = "Failed to get session time outs"; + logger.error("doGet: " + msg); + responseJson = buildJsonResponse(false, msg); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } else + // Example: /users <-- get all users + if (requestUri.endsWith(PortalApiConstants.API_PREFIX + "/users")) { + try { + List users = getUsers(); + responseJson = mapper.writeValueAsString(users); + if (logger.isDebugEnabled()) + logger.debug("doGet: getUsers: " + responseJson); + } catch (Exception ex) { + responseJson = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.error("doGet: getUsers: caught exception", ex); + } + } else + // Example: /roles <-- get all roles + if (requestUri.endsWith(PortalApiConstants.API_PREFIX + "/roles")) { + try { + List roles = getAvailableRoles(); + responseJson = mapper.writeValueAsString(roles); + if (logger.isDebugEnabled()) + logger.debug("doGet: getAvailableRoles: " + responseJson); + } catch (Exception ex) { + responseJson = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.error("doGet: getAvailableRoles: caught exception", ex); + } + } else + // Example: /user/fi241c <-- get user fi241c + if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && !requestUri.endsWith("/roles")) { + String loginId = requestUri.substring(requestUri.lastIndexOf('/') + 1); + try { + EcompUser user = getUser(loginId); + responseJson = mapper.writeValueAsString(user); + if (logger.isDebugEnabled()) + logger.debug("doGet: getUser: " + responseJson); + } catch (Exception ex) { + responseJson = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.error("doGet: getUser: caught exception", ex); + } + } + // Example: /user/fi241c/roles <-- get roles for user fi241c + else if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && requestUri.endsWith("/roles")) { + String loginId = requestUri.substring(requestUri.indexOf("/user/") + ("/user").length() + 1, + requestUri.lastIndexOf('/')); + try { + List roles = getUserRoles(loginId); + responseJson = mapper.writeValueAsString(roles); + if (logger.isDebugEnabled()) + logger.debug("doGet: getUserRoles: " + responseJson); + } catch (Exception ex) { + responseJson = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.error("doGet: getUserRoles: caught exception", ex); + } + } else { + logger.warn("doGet: no match found for request"); + responseJson = buildJsonResponse(false, "No match for request"); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + } + writeAndFlush(response, responseJson); + } catch (Exception ex) { + logger.error("doGet: Failed to process request", ex); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + writeAndFlush(response, buildJsonResponse(ex)); + } + } + + public String getSessionTimeOuts() throws Exception { + return PortalTimeoutHandler.gatherSessionExtensions(); + } + + public boolean timeoutSession(String portalJSessionId) throws Exception { + return PortalTimeoutHandler.invalidateSession(portalJSessionId); + } + + public boolean updateSessionTimeOuts(String sessionMap) throws Exception { + return PortalTimeoutHandler.updateSessionExtensions(sessionMap); + } + + @Override + public void pushUser(EcompUser user) throws PortalAPIException { + portalRestApiService.pushUser(user); + } + + @Override + public void editUser(String loginId, EcompUser user) throws PortalAPIException { + portalRestApiService.editUser(loginId, user); + } + + @Override + public EcompUser getUser(String loginId) throws PortalAPIException { + return portalRestApiService.getUser(loginId); + } + + @Override + public List getUsers() throws PortalAPIException { + return portalRestApiService.getUsers(); + } + + @Override + public List getAvailableRoles() throws PortalAPIException { + return portalRestApiService.getAvailableRoles(); + } + + @Override + public void pushUserRole(String loginId, List roles) throws PortalAPIException { + portalRestApiService.pushUserRole(loginId, roles); + } + + @Override + public List getUserRoles(String loginId) throws PortalAPIException { + return portalRestApiService.getUserRoles(loginId); + } + + @Override + public boolean isAppAuthenticated(HttpServletRequest request) throws PortalAPIException { + return portalRestApiService.isAppAuthenticated(request); + } + + private void writeAndFlush(HttpServletResponse response, String jsonResponse) throws IOException { + response.setContentType("application/json"); + PrintWriter out = response.getWriter(); + out.print(jsonResponse); + out.flush(); + } + + /** + * Reads the request body and closes the input stream. + * + * @param request + * @return String read from the request, the empty string if nothing is + * read. + * @throws IOException + */ + private static String readRequestBody(HttpServletRequest request) throws IOException { + + String body = null; + StringBuilder stringBuilder = new StringBuilder(); + BufferedReader bufferedReader = null; + try { + InputStream inputStream = request.getInputStream(); + if (inputStream != null) { + bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + char[] charBuffer = new char[1024]; + int bytesRead = -1; + while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { + stringBuilder.append(charBuffer, 0, bytesRead); + } + } else { + stringBuilder.append(""); + } + } finally { + if (bufferedReader != null) { + try { + bufferedReader.close(); + } catch (IOException ex) { + throw ex; + } + } + } + body = stringBuilder.toString(); + return body; + } + + /** + * Builds JSON object with status + message response body. + * + * @param success + * True to indicate success, false to signal failure. + * @param msg + * Message to include in the response object; ignored if null. + * @return + * + *
+	 * { "status" : "ok" (or "error"), "message": "some explanation" }
+	 *         
+ */ + private String buildJsonResponse(boolean success, String msg) { + PortalAPIResponse response = new PortalAPIResponse(success, msg); + String json = null; + try { + json = mapper.writeValueAsString(response); + } catch (JsonProcessingException ex) { + // Truly should never, ever happen + json = "{ \"status\": \"error\",\"message\":\"" + ex.toString() + "\" }"; + } + return json; + } + + /** + * Builds JSON object with status of error and message containing stack + * trace for the specified throwable. + * + * @param t + * Throwable with stack trace to use as message + * @return + * + *
+	 * { "status" : "error", "message": "some-big-stacktrace" }
+	 *         
+ */ + private String buildJsonResponse(Throwable t) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + t.printStackTrace(pw); + return buildJsonResponse(false, sw.toString()); + } +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutBindingListener.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutBindingListener.java new file mode 100644 index 0000000..906b7e8 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutBindingListener.java @@ -0,0 +1,52 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.crossapi; + +import java.io.Serializable; + +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionBindingEvent; +import javax.servlet.http.HttpSessionBindingListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class PortalTimeoutBindingListener implements HttpSessionBindingListener, Serializable { + + private final Log logger = LogFactory.getLog(getClass()); + + private static final long serialVersionUID = 1L; + + @Override + public void valueBound(HttpSessionBindingEvent event) { + final HttpSession session = event.getSession(); + PortalTimeoutHandler.sessionMap.put((String) session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID), + session); + } + + @Override + public void valueUnbound(HttpSessionBindingEvent event) { + final HttpSession session = event.getSession(); + String portalJSessionId = (String) session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID); + logger.debug(portalJSessionId + " getting removed"); + PortalTimeoutHandler.sessionMap.remove(portalJSessionId); + } + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutHandler.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutHandler.java new file mode 100644 index 0000000..0916679 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutHandler.java @@ -0,0 +1,419 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.crossapi; + +import java.util.Calendar; +import java.util.Hashtable; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Invoked by listeners (UserContextListener and UserSessionListener) to track + * user sessions. + */ +public class PortalTimeoutHandler { + + protected static final SessionCommInf sessionComm = new SessionComm(); + + + + public interface SessionCommInf { + public Integer fetchSessionSlotCheckInterval(String... params) throws Exception; + + public void extendSessionTimeOuts(String... sessionMap) throws Exception; + } + + public static class SessionComm implements SessionCommInf { + public Integer fetchSessionSlotCheckInterval(String... params) throws Exception { + + String ecompRestURL = params[0]; + String userName = params[1]; + String pwd = params[2]; + String uebKey = params[3]; + + String sessionSlot = SessionCommunication.getSessionSlotCheckInterval(ecompRestURL, userName, pwd, uebKey); + if(sessionSlot == null) + return null; + return Integer.parseInt(sessionSlot); + } + + public void extendSessionTimeOuts(String... params) throws Exception { + + String ecompRestURL = params[0]; + String userName = params[1]; + String pwd = params[2]; + String uebKey = params[3]; + String sessionTimeoutMap = params[4]; + + SessionCommunication.requestPortalSessionTimeoutExtension(ecompRestURL, userName, pwd, uebKey, sessionTimeoutMap); + } + } + + + + public static final Map sessionMap = new Hashtable(); + public static final Integer repeatInterval = 15 * 60; // 15 minutes + protected static final Log logger = LogFactory.getLog(PortalTimeoutHandler.class); + static ObjectMapper mapper = new ObjectMapper(); + private static PortalTimeoutHandler timeoutHandler; + + public static PortalTimeoutHandler getInstance() { + if (timeoutHandler == null) + timeoutHandler = new PortalTimeoutHandler(); + + return timeoutHandler; + } + + /** + * TODO: remove static + * + * @param portalJSessionId + * @param jSessionId + * @param session + */ + public static void sessionCreated(String portalJSessionId, String jSessionId, HttpSession session) { + + storeMaxInactiveTime(session); + + // this key is a combination of portal jsession id and app session id + String jSessionKey = jSessionKey(jSessionId, portalJSessionId); + Object jSessionKeySessionVal = session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID); + + // do not reset the attributes if the same values have already been set + // because that will cause PortalTimeoutBindingListener to unbound the value from map + if(jSessionKeySessionVal != null && jSessionKeySessionVal.equals(jSessionKey)) { + logger.debug(" Session Values already exist in te map for sessionKey " + jSessionKey); + return; + } + + session.setAttribute(PortalApiConstants.PORTAL_JSESSION_ID, jSessionKey); + + // session binding listener will add this value to the static map + // and with session replication the listener will fire in all tomcat + // instances + session.setAttribute(PortalApiConstants.PORTAL_JSESSION_BIND, new PortalTimeoutBindingListener()); + // sessionMap.put((String)session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID), + // session); + + } + + /** + * TODO: remove static + * + * @param session + */ + protected static void storeMaxInactiveTime(HttpSession session) { + if (session.getAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME) == null) + session.setAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME, session.getMaxInactiveInterval()); + } + + /** + * TODO: remove static + * + * @param session + */ + public static void sessionDestroyed(HttpSession session) { + try { + logger.info(" Session getting destroyed - id: " + session.getId()); + session.removeAttribute(PortalApiConstants.PORTAL_JSESSION_BIND); + // sessionMap.remove((String)session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID)); + } catch (Exception e) { + logger.error("Error while destroy user session" + e.getMessage()); + } + } + + /*** + * TODO: remove static + * + * @param portalJSessionId + * @return true on success, false if the session cannot be found, etc. + */ + public static boolean invalidateSession(String portalJSessionId) { + boolean result = false; + logger.debug("Session Management: request from Portal to invalidate the session: " + portalJSessionId); + for (String jSessionKey : sessionMap.keySet()) { + try { + HttpSession session = sessionMap.get(jSessionKey); + if (portalJSessionId(jSessionKey).equals(portalJSessionId)) { + session.invalidate(); + result = true; + } + } catch (Exception e) { + logger.error("Session Management: Error when invalidating session", e); + } + } + return result; + } + + /** + * TODO: remove static + * + * @return json version of the timeout map: session ID -> timeout object + */ + public static String gatherSessionExtensions() { + logger.debug("Session Management: gatherSessionExtensions"); + + Map sessionTimeoutMap = new Hashtable(); + String jsonMap = ""; + + for (String jSessionKey : sessionMap.keySet()) { + + try { + // get the expirytime in seconds + HttpSession session = sessionMap.get(jSessionKey); + + Long lastAccessedTimeMilliSec = session.getLastAccessedTime(); + Long maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000L; + // Long currentTimeMilliSec = + // Calendar.getInstance().getTimeInMillis() ; + // (maxIntervalMilliSec - (currentTimeMilliSec - + // lastAccessedTimeMilliSec) + ; + Calendar instance = Calendar.getInstance(); + instance.setTimeInMillis(session.getLastAccessedTime()); + logger.debug("Session Management: Last Accessed time for " + jSessionKey + ": " + instance.getTime()); + + Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec; + + sessionTimeoutMap.put(portalJSessionId(jSessionKey), + getSingleSessionTimeoutObj(jSessionKey, sessionTimOutMilliSec)); + logger.debug("Session Management: putting session in map " + jSessionKey + " sessionTimoutSec" + + (int) (sessionTimOutMilliSec / 1000)); + + jsonMap = mapper.writeValueAsString(sessionTimeoutMap); + + } catch (Exception e) { + logger.error("Session Management: Error during JsonSessionTimout conversion", e); + } + + } + + return jsonMap; + + } + + /** + * TODO: remove static + * + * @param sessionTimeoutMapStr + * @return true on success, false otherwise + * @throws Exception + */ + public static boolean updateSessionExtensions(String sessionTimeoutMapStr) throws Exception { + logger.debug("Session Management: updateSessionExtensions"); + // Map sessionTimeoutMap = + // mapper.readValue(sessionTimeoutMapStr, Map.class); + Map sessionTimeoutMap = null; + + try { + TypeReference> typeRef = new TypeReference>() { + }; + sessionTimeoutMap = mapper.readValue(sessionTimeoutMapStr, typeRef); + } catch (Exception e) { + logger.error("Session Management:error when try to parse the sessionTimeoutMap from portal"); + return false; + } + + boolean result = true; + for (String jPortalSessionId : sessionTimeoutMap.keySet()) { + try { + PortalTimeoutVO extendedTimeoutVO = mapper.readValue( + mapper.writeValueAsString(sessionTimeoutMap.get(jPortalSessionId)), PortalTimeoutVO.class); + HttpSession session = sessionMap.get(jSessionKey(extendedTimeoutVO.getjSessionId(), jPortalSessionId)); + + if (session == null) { + continue; + } + + Long lastAccessedTimeMilliSec = session.getLastAccessedTime(); + Long maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000L; + Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec; + + Long maxTimeoutTimeMilliSec = extendedTimeoutVO.getSessionTimOutMilliSec(); + if (maxTimeoutTimeMilliSec > sessionTimOutMilliSec) { + session.setMaxInactiveInterval((int) (maxTimeoutTimeMilliSec - lastAccessedTimeMilliSec) / 1000); + logger.debug("Session Management: extended session for :" + session.getId() + " to :" + + (int) (maxTimeoutTimeMilliSec / 1000)); + // System.out.println("!!!!!!!!!extended session for :" + + // session.getId() + " to :" + + // (int)(maxTimeoutTimeMilliSec/1000)); + } + } catch (Exception e) { + logger.error("Session Management: error while updating the sessionTimeout" + e.getMessage()); + // Signal a problem if any one of them fails + result = false; + } + + } + return result; + } + + /** + * TODO: Remove static + * + * @param request + * @param userName + * @param pwd + * @param ecompRestURL + * @param _sessionComm + */ + public static void handleSessionUpdatesNative(HttpServletRequest request, String userName, String pwd, String uebKey, + String ecompRestURL, SessionCommInf _sessionComm) { + + if (_sessionComm == null) { + _sessionComm = sessionComm; + } + try { + synchronizeSessionForLastMinuteRequests(request, ecompRestURL, userName, pwd, uebKey, _sessionComm); + } catch (Exception e) { + logger.error(e); + } + resetSessionMaxIdleTimeOut(request); + } + + /** + * TODO: remove Static + * + * @param request + * @param ecompRestURL + * @param userName + * @param pwd + * @param _sessionComm + * @throws JsonProcessingException + * @throws Exception + */ + public static void synchronizeSessionForLastMinuteRequests(HttpServletRequest request, String ecompRestURL, + String userName, String pwd, String uebKey, SessionCommInf _sessionComm) throws JsonProcessingException, Exception { + + HttpSession session = request.getSession(false); + if (session == null) + return; + + Object portalSessionSlotCheckObj = session.getServletContext() + .getAttribute(PortalApiConstants.PORTAL_SESSION_SLOT_CHECK); + Integer portalSessionSlotCheckinMilliSec = 5 * 60 * 1000; // (5 minutes) + if (portalSessionSlotCheckObj != null) { + portalSessionSlotCheckinMilliSec = Integer.valueOf(portalSessionSlotCheckObj.toString()); + } else { + portalSessionSlotCheckObj = _sessionComm + .fetchSessionSlotCheckInterval(new String[] { ecompRestURL, userName, pwd, uebKey }); + logger.debug("Fetching Portal Session Slot Object: " + portalSessionSlotCheckObj); + if (portalSessionSlotCheckObj != null) { + portalSessionSlotCheckinMilliSec = Integer.valueOf(portalSessionSlotCheckObj.toString()); + session.getServletContext().setAttribute(PortalApiConstants.PORTAL_SESSION_SLOT_CHECK, + portalSessionSlotCheckinMilliSec); + } + } + + Object previousToLastAccessTimeObj = session.getAttribute(PortalApiConstants.SESSION_PREVIOUS_ACCESS_TIME); + final long lastAccessedTimeMilliSec = session.getLastAccessedTime(); + if (previousToLastAccessTimeObj == null) { + previousToLastAccessTimeObj = lastAccessedTimeMilliSec; + session.setAttribute(PortalApiConstants.SESSION_PREVIOUS_ACCESS_TIME, previousToLastAccessTimeObj); + } else { + Long previousToLastAccessTime = (Long) previousToLastAccessTimeObj; + final int maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000; + if (maxIntervalMilliSec + - (lastAccessedTimeMilliSec - previousToLastAccessTime) <= portalSessionSlotCheckinMilliSec) { + + String jSessionKey = (String) session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID); + Map sessionTimeoutMap = new Hashtable(); + Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec; + + sessionTimeoutMap.put(PortalTimeoutHandler.portalJSessionId(jSessionKey), + PortalTimeoutHandler.getSingleSessionTimeoutObj(jSessionKey, sessionTimOutMilliSec)); + String jsonMap = mapper.writeValueAsString(sessionTimeoutMap); + logger.debug("Extension requested for all the Apps and Portal; JessionKey: " + jSessionKey + + "; SessionMap: " + sessionTimeoutMap); + _sessionComm.extendSessionTimeOuts(new String[] { ecompRestURL, userName, pwd, uebKey, jsonMap }); + } + + } + } + + /** + * TODO: remove static + * + * @param request + */ + public static void resetSessionMaxIdleTimeOut(HttpServletRequest request) { + try { + HttpSession session = request.getSession(false); + if (session == null) + return; + + final Object maxIdleAttribute = session.getAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME); + if (maxIdleAttribute != null) { + session.setMaxInactiveInterval(Integer.parseInt(maxIdleAttribute.toString())); + } + + } catch (Exception e) { + logger.error("Could not reset the session timeout", e); + } + + } + + /** + * + * @param jSessionKey + * @param sessionTimOutMilliSec + * @return + */ + private static PortalTimeoutVO getSingleSessionTimeoutObj(String jSessionKey, Long sessionTimOutMilliSec) { + return new PortalTimeoutVO(jSessionId(jSessionKey), sessionTimOutMilliSec); + } + + /** + * + * @param jSessionId + * @param portalJSessionId + * @return + */ + private static String jSessionKey(String jSessionId, String portalJSessionId) { + return portalJSessionId + "-" + jSessionId; + } + + /** + * + * @param jSessionKey + * @return + */ + private static String portalJSessionId(String jSessionKey) { + return jSessionKey.split("-")[0]; + } + + /** + * + * @param jSessionKey + * @return + */ + private static String jSessionId(String jSessionKey) { + return jSessionKey.split("-")[1]; + } + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutVO.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutVO.java new file mode 100644 index 0000000..af6eab8 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutVO.java @@ -0,0 +1,63 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.crossapi; + +public class PortalTimeoutVO implements Comparable{ + + private String jSessionId; + private Long sessionTimOutMilliSec; + + public PortalTimeoutVO(){ + + } + + public PortalTimeoutVO(String _jSessionId, Long _sessionTimOutMilliSec) { + setjSessionId(_jSessionId); + setSessionTimOutMilliSec(_sessionTimOutMilliSec); + + } + + public String getjSessionId() { + return jSessionId; + } + + public void setjSessionId(String jSessionId) { + this.jSessionId = jSessionId; + } + + public Long getSessionTimOutMilliSec() { + return sessionTimOutMilliSec; + } + + public void setSessionTimOutMilliSec(Long sessionTimOutMilliSec) { + this.sessionTimOutMilliSec = sessionTimOutMilliSec; + } + + @Override + public int compareTo(PortalTimeoutVO o) { + return sessionTimOutMilliSec.compareTo(o.sessionTimOutMilliSec); + } + + + + + + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/SessionCommunication.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/SessionCommunication.java new file mode 100644 index 0000000..4417857 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/SessionCommunication.java @@ -0,0 +1,161 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.crossapi; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class SessionCommunication { + + protected static final Log logger = LogFactory.getLog(SessionCommunication.class); + + /** + * Calls the ECOMP Portal to retrieve the session slot check interval. + * + * @param ecompRestURL + * @param userName + * application user name used for authentication at Portal + * @param password + * application password used for authentication at Portal + * @param uebKey + * application UEB key (basically application ID) used for + * authentication at Portal + * @return Content read from the remote REST endpoint + */ + public static String getSessionSlotCheckInterval(String ecompRestURL, String userName, String password, + String uebKey) { + try { + String url = ecompRestURL + "/getSessionSlotCheckInterval"; + + URL obj = new URL(url); + + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // optional default is GET + con.setRequestMethod("GET"); + con.setConnectTimeout(3000); + con.setReadTimeout(8000); + // add request header + con.setRequestProperty("username", userName); + con.setRequestProperty("password", password); + con.setRequestProperty("uebkey", uebKey); + + int responseCode = con.getResponseCode(); + if (logger.isDebugEnabled()) { + logger.debug("getSessionSlotCheckInterval: Sending 'GET' request to URL : " + url); + logger.debug("getSessionSlotCheckInterval: Response Code : " + responseCode); + } + + StringBuffer response = new StringBuffer(); + + BufferedReader in = null; + try { + in = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8")); + String inputLine; + while ((inputLine = in.readLine()) != null) + response.append(inputLine); + } finally { + in.close(); + } + return response.toString(); + } catch (Exception e) { + logger.error("getSessionSlotCheckInterval: failed to fetch the session slot check", e); + return null; + } + + } + + /** + * Calls the ECOMP Portal to request an extension of the current session. + * + * @param ecompRestURL + * @param userName + * application user name used for authentication at Portal + * @param password + * application password used for authentication at Portal + * @param uebKey + * application UEB key (basically application ID) used for + * authentication at Portal + * @param sessionTimeoutMap + * @return Content read from the remote REST endpoint + * @throws Exception + */ + public static String requestPortalSessionTimeoutExtension(String ecompRestURL, String userName, String password, + String uebKey, String sessionTimeoutMap) throws Exception { + + try { + + String url = ecompRestURL + "/extendSessionTimeOuts"; + // String decreptedPwd = + // app.appPassword;//CipherUtil.decrypt(encriptedPwdDB, + // SystemProperties.getProperty(SystemProperties.SECRET_KEY)); + + URL obj = new URL(url); + + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + con.setRequestMethod("POST"); + con.setConnectTimeout(3000); + con.setReadTimeout(15000); + + // add request header + con.setRequestProperty("username", userName); + con.setRequestProperty("password", password); + con.setRequestProperty("uebkey", uebKey); + con.setRequestProperty("sessionMap", sessionTimeoutMap); + con.setDoInput(true); + con.setDoOutput(true); + con.getOutputStream().write(sessionTimeoutMap.getBytes()); + con.getOutputStream().flush(); + con.getOutputStream().close(); + + // con.set + + int responseCode = con.getResponseCode(); + if (logger.isDebugEnabled()) { + logger.debug("requestPortalSessionTimeoutExtension: Sending 'GET' request to URL : " + url); + logger.debug("requestPortalSessionTimeoutExtension: Response Code : " + responseCode); + } + + StringBuffer response = new StringBuffer(); + BufferedReader in = null; + try { + in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + } finally { + in.close(); + } + return response.toString(); + } catch (Exception e) { + logger.error("requestPortalSessionTimeoutExtension: failed to request Portal to extend time out ", e); + return null; + } + + } + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserContextListener.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserContextListener.java new file mode 100644 index 0000000..ea346f1 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserContextListener.java @@ -0,0 +1,52 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.crossapi; + +import java.util.HashMap; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; +import javax.servlet.http.HttpSession; + +@WebListener +public class UserContextListener implements ServletContextListener{ + + public void contextInitialized(ServletContextEvent event){ + ServletContext context = event.getServletContext(); + // + // instanciate a map to store references to all the active + // sessions and bind it to context scope. + // + HashMap activeUsers = new HashMap(); + context.setAttribute(PortalApiConstants.ACTIVE_USERS_NAME, activeUsers); + } + + /** + * Needed for the ServletContextListener interface. + */ + public void contextDestroyed(ServletContextEvent event){ + // To overcome the problem with losing the session references + // during server restarts, put code here to serialize the + // activeUsers HashMap. Then put code in the contextInitialized + // method that reads and reloads it if it exists... + } +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserSessionListener.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserSessionListener.java new file mode 100644 index 0000000..b468851 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserSessionListener.java @@ -0,0 +1,84 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.crossapi; + +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.annotation.WebListener; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Listens to session-create and session-destroy events. + */ +@WebListener +public class UserSessionListener implements HttpSessionListener { + + private Log logger = LogFactory.getLog(getClass()); + + public static Map activeSessions = new Hashtable(); + + public void init(ServletConfig config) { + } + + /** + * Adds sessions to the context-scoped HashMap when they begin. + */ + public void sessionCreated(HttpSessionEvent event) { + HttpSession session = event.getSession(); + ServletContext context = session.getServletContext(); + @SuppressWarnings("unchecked") + HashMap activeUsers = (HashMap) context + .getAttribute(PortalApiConstants.ACTIVE_USERS_NAME); + if (activeUsers != null) + activeUsers.put(session.getId(), session); + context.setAttribute(PortalApiConstants.ACTIVE_USERS_NAME, activeUsers); + activeSessions.put(session.getId(), session); + session.getServletContext().setAttribute(PortalApiConstants.MAX_IDLE_TIME, session.getMaxInactiveInterval()); + } + + /** + * Removes sessions from the context-scoped HashMap when they expire or are + * invalidated. + */ + public void sessionDestroyed(HttpSessionEvent event) { + try { + HttpSession session = event.getSession(); + ServletContext context = session.getServletContext(); + @SuppressWarnings("unchecked") + HashMap activeUsers = (HashMap) context + .getAttribute(PortalApiConstants.ACTIVE_USERS_NAME); + if (activeUsers != null) + activeUsers.remove(session.getId()); + activeSessions.remove(session.getId()); + PortalTimeoutHandler.sessionDestroyed(session); + } catch (Exception e) { + logger.warn(e.getMessage(), e); + } + } +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FavoritesClient.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FavoritesClient.java new file mode 100644 index 0000000..9dce022 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FavoritesClient.java @@ -0,0 +1,51 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.rest; + +/** + * Provides a convenience method for fetching the favorites for a user from the + * ECOMP Portal. + */ +public class FavoritesClient { + + /** + * Fetches the favorites data from portal + * + * @param userId + * userId value that it should be using to fetch the + * data + * @param appName + * Application name for logging etc. + * @param requestId + * 128-bit UUID value to uniquely identify the transaction; if null, a new one is generated. + * @param appUserName + * REST API user-name + * @param appPassword + * REST API decrypted password + * @return JSON with favorites + * @throws Exception + * on any failure + */ + public static String getFavorites(String userId, String appName, String requestId, String appUserName, + String appPassword) throws Exception { + return RestWebServiceClient.getInstance().getPortalContent("/getFavorites", userId, appName, requestId, appUserName, + appPassword); + } +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FunctionalMenuClient.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FunctionalMenuClient.java new file mode 100644 index 0000000..8e12b33 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FunctionalMenuClient.java @@ -0,0 +1,54 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.rest; + +/** + * Provides a convenience method for fetching the functional menu for a user + * from the ECOMP Portal via UEB. + */ +public class FunctionalMenuClient { + + /** + * Fetches the functional menu data from the configured ECOMP Portal + * instance. + * + * @param userId + * userId for the user to whom the menu will be shown + * @param appName + * Application name for logging etc. + * @param requestId + * 128-bit UUID value to uniquely identify the transaction; if + * null, a new one is generated. + * @param appUserName + * REST API user name, used by Portal to authenticate the request + * @param appPassword + * REST API password (in the clear, not encrypted), used by + * Portal to authenticate the request + * @return JSON with functional menu + * @throws Exception + * on any failure + */ + public static String getFunctionalMenu(String userId, String appName, String requestId, String appUserName, + String appPassword) throws Exception { + return RestWebServiceClient.getInstance().getPortalContent("/functionalMenuItemsForUser", userId, appName, + requestId, appUserName, appPassword); + } + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/RestWebServiceClient.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/RestWebServiceClient.java new file mode 100644 index 0000000..fc5ce87 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/RestWebServiceClient.java @@ -0,0 +1,178 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.rest; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.UUID; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; +import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; + +public class RestWebServiceClient { + + private final Log logger = LogFactory.getLog(RestWebServiceClient.class); + + /** + * Singleton instance + */ + private static RestWebServiceClient instance = null; + + /** + * Constructor is private. Clients should obtain an instance via + * getInstance(). + */ + private RestWebServiceClient() { + } + + /** + * Gets the static instance of RestWebServiceClient; creates it if + * necessary. Synchronized to be thread safe. + * + * @return Static instance of RestWebServiceClient. + */ + public static synchronized RestWebServiceClient getInstance() { + if (instance == null) + instance = new RestWebServiceClient(); + return instance; + } + + /** + * Convenience method that fetches the URL for the Portal REST API endpoint + * and the application UEB key, then calls + * {@link #get(String, String, String, String, String, String, String)} to + * access the Portal's REST endpoint. + * + * @param restPath + * Partial path of the endpoint; e.g., "/specialRestService" + * @param userId + * userId for the user originating the request + * @param appName + * Application Name for logging. + * @param requestId + * 128-bit UUID value to uniquely identify the transaction. + * @param appUserName + * REST API user name for Portal to authenticate the request + * @param appPassword + * REST API password (in the clear, not encrypted) for Portal to + * authenticate the request + * @return Content from REST endpoint + * @throws Exception + * on any failure + */ + public String getPortalContent(String restPath, String userId, String appName, String requestId, String appUserName, + String appPassword) throws Exception { + String restURL = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REST_URL); + if (restURL == null) { + // should never happen + String msg = "getPortalContent: failed to get property " + PortalApiConstants.ECOMP_REST_URL; + logger.error(msg); + throw new Exception(msg); + } + String appUebKey = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); + if (appUebKey == null) { + // should never happen + String msg = "getPortalContent: failed to get property " + PortalApiConstants.UEB_APP_KEY; + logger.error(msg); + throw new Exception(msg); + } + final String restEndpointUrl = restURL + restPath; + return get(restEndpointUrl, userId, appName, requestId, appUebKey, appUserName, appPassword); + } + + /** + * Makes a call to a Portal REST API using the specified URL and parameters. + * + * @param url + * Complete URL of the REST endpoint. + * @param loginId + * User that it should be fetching the data + * @param appName + * Application name for logging; if null or empty, defaulted to + * Unknown. + * @param requestId + * 128-bit UUID value to uniquely identify the transaction; if + * null or empty, one is generated. + * @param appUebKey + * Unique key for the application, used by Portal to authenticate + * the request + * @param appUserName + * REST API user name, used by Portal to authenticate the request + * @param appPassword + * REST API password, used by Portal to authenticate the request + * @return Content from REST endpoint + * @throws Exception + * On any failure; e.g., unknown host. + */ + public String get(String url, String loginId, String appName, String requestId, String appUebKey, + String appUserName, String appPassword) throws Exception { + + logger.debug("RestWebServiceClient.get (" + url + ") operation is started."); + if (appName == null || appName.trim().length() == 0) + appName = "Unknown"; + if (requestId == null || requestId.trim().length() == 0) + requestId = UUID.randomUUID().toString(); + + URL obj = new URL(url); + // Create the connection object + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + con.setRequestMethod("GET"); + con.setConnectTimeout(3000); + con.setReadTimeout(8000); + + // add request header + con.setRequestProperty("uebkey", appUebKey); + con.setRequestProperty("username", appUserName); + con.setRequestProperty("password", appPassword); + con.setRequestProperty("LoginId", loginId); + con.setRequestProperty("user-agent", appName); + con.setRequestProperty("X-ECOMP-RequestID", requestId); + + int responseCode = con.getResponseCode(); + logger.debug("get: received response code '" + responseCode + "' while getting the '" + url + "' for user: " + + loginId); + + StringBuffer sb = new StringBuffer(); + BufferedReader in = null; + try { + in = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8")); + String inputLine = null; + while ((inputLine = in.readLine()) != null) + sb.append(inputLine); + } finally { + try { + if (in != null) + in.close(); + } catch (IOException ex) { + logger.error("get: failed to close reader", ex); + } + } + + final String response = sb.toString(); + if (logger.isDebugEnabled()) + logger.debug("get: url " + url + " yielded " + response); + return response; + } +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Consumer.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Consumer.java new file mode 100644 index 0000000..bb15229 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Consumer.java @@ -0,0 +1,164 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.ueb; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.LinkedList; +import java.util.UUID; +import java.util.concurrent.ConcurrentLinkedQueue; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; +import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; + +import com.att.nsa.cambria.client.CambriaClientBuilders; +import com.att.nsa.cambria.client.CambriaClientFactory; +import com.att.nsa.cambria.client.CambriaConsumer; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Provides a consumer that reads messages from a UEB topic. Intended to be + * passed to a separate thread as its runnable object. + * + */ +public class Consumer implements Runnable { + + private final Log logger = LogFactory.getLog(getClass()); + + private final LinkedList urlList = Helper.uebUrlList(); + private final ConcurrentLinkedQueue queue; + private final WaitingRequestersQueueList waitingRequestersList; + private final String consumerKey, consumerSecret, topicName, consumerGroupName; + + /** + * Accepts coordinates needed to subscribe to a UEB topic, as well as the + * queues for passing along messages that arrive. + * + * @param consumerKey + * UEB key used to subscribe to the topic + * @param consumerSecret + * UEB secret used to subscribe to the topic + * @param topicName + * UEB topic name + * @param queue + * Queue to receive UEB messages. All inbound messages are + * enqueued here; ignored if null. + * @param waitingRequestersList + * Collection of queues to receive UEB messages that arrive in + * response to requests; i.e., emulating a synchronous request + * via pub/sub. + */ + public Consumer(String consumerKey, String consumerSecret, String topicName, String consumerGroupName, + ConcurrentLinkedQueue queue, WaitingRequestersQueueList waitingRequestersList) { + this.consumerKey = consumerKey; + this.consumerSecret = consumerSecret; + this.topicName = topicName; + this.consumerGroupName = consumerGroupName; + this.queue = queue; + this.waitingRequestersList = waitingRequestersList; + } + + /** + * Subscribes to a topic using credentials as supplied to the constructor. + * Distributes messages appropriately as they arrive: + *
    + *
  • If the queue is not null, adds the message to the queue. + *
  • If the message's getMsgId() method returns non-null and the ID is + * found in the collection of waiting requesters, adds the message in that + * requester's queue. + *
+ * + * This is intended to be called in a long running thread as a listener for + * any published messages on a topic. Typical async pub/sub model. We use a + * filter of "0" to prevent collisions with P2P messages with unique filter + * ids. + */ + protected void consume() throws IOException, UebException { + final String id = UUID.randomUUID().toString(); + + CambriaConsumer cc = null; + try { + cc = new CambriaClientBuilders.ConsumerBuilder() + .usingHosts(urlList) + .authenticatedBy(consumerKey, consumerSecret) + .onTopic (topicName) + .knownAs (consumerGroupName,id) + .waitAtServer (15*1000) + .receivingAtMost (1000) + .build(); + } catch (GeneralSecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + //CambriaClientFactory.createConsumer(urlList, topicName, consumerGroupName, id, + //15 * 1000, 1000, null, consumerKey, consumerSecret); + + while (true) { + for (String msg : cc.fetch()) { + logger.debug(" <== consume from topicName " + topicName + " msg: " + msg); + UebMsg uebMsg = new ObjectMapper().readValue(msg, UebMsg.class); + if (queue != null) { + // Add to general queue allowing listeners to act on any + // incoming messages. We don't know if a listener is + // also going to be a responder to a synchronous + // request. So put all received messages on the general + // listener queue. + queue.add(uebMsg); + if (logger.isDebugEnabled()) + logger.debug("Added msg to queue " + this.queue + " queue count = " + queue.size() + " msg :" + + uebMsg.getPayload()); + } + if (waitingRequestersList != null && uebMsg.getMsgId() != null) { + // If a msgId is present, this could be a synchronous + // reply. Here we add it to the waiting requester's + // queue if we find a requester waiting for this msgId. + if (!(uebMsg.getMsgId() + .equals(PortalApiProperties.getProperty(PortalApiConstants.ECOMP_DEFAULT_MSG_ID)))) { + waitingRequestersList.addMsg(uebMsg.getMsgId(), uebMsg); + } + } + } + if (Thread.interrupted()) { + logger.warn(Thread.currentThread() + " interrupted, exiting"); + break; + } + Helper.sleep(10); + } + + } + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + try { + consume(); + } catch (Exception ex) { + Thread t = Thread.currentThread(); + t.getUncaughtExceptionHandler().uncaughtException(t, ex); + } + } + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/FunctionalMenu.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/FunctionalMenu.java new file mode 100644 index 0000000..94ca4ee --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/FunctionalMenu.java @@ -0,0 +1,61 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.ueb; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Provides a convenience method for fetching the functional menu for a user + * from the ECOMP Portal via UEB. + */ +public class FunctionalMenu { + + private static final Log logger = LogFactory.getLog(FunctionalMenu.class); + + /** + * Makes a synchronous call to ECOMP Portal to get JSON with the functional + * menu, which arrives as the payload of the returned UEB message. + * + * @param userId + * User ID as known on the ECOMP Portal for customizing the + * functional menu appropriately + * @return JSON with functional menu + * @throws UebException + */ + public static String get(String userId) throws UebException { + String returnString = null; + logger.info("Making use of UEB communication and Requesting functional menu for user " + userId); + UebMsg funcMenuUebMsg = null; + UebMsg msg = new UebMsg(); + msg.putMsgType(UebMsgTypes.UEB_MSG_TYPE_GET_FUNC_MENU); + msg.putUserId(userId); + funcMenuUebMsg = UebManager.getInstance().requestReply(msg); + if (funcMenuUebMsg != null) { + if (funcMenuUebMsg.getPayload().startsWith("Error:")) { + logger.error("getFunctionalMenu received an error in UEB msg = " + funcMenuUebMsg.getPayload()); + } else { + returnString = funcMenuUebMsg.getPayload(); + } + } + return returnString; + } + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Helper.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Helper.java new file mode 100644 index 0000000..ce94234 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Helper.java @@ -0,0 +1,64 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.ueb; + +import java.util.LinkedList; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; +import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; + +/** + * Provides utility methods. + */ +public class Helper { + + private static final Log logger = LogFactory.getLog(Helper.class); + + /** + * Parses a comma-separated list of UEB servers from properties file into a + * list. + * + * @return List of UEB server names + */ + public static LinkedList uebUrlList() { + LinkedList urlList = null; + String url = PortalApiProperties.getProperty(PortalApiConstants.UEB_URL_LIST); + if (url == null) { + logger.error("uebUrlList: failed to get property " + PortalApiConstants.UEB_URL_LIST); + return null; + } + urlList = new LinkedList(); + for (String u : url.split(",")) { + urlList.add(u.trim()); + } + return urlList; + } + + public static void sleep(int milliseconds) { + try { + Thread.sleep(milliseconds); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Publisher.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Publisher.java new file mode 100644 index 0000000..a7e914c --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Publisher.java @@ -0,0 +1,124 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.ueb; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.security.GeneralSecurityException; +import java.util.LinkedList; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; + +import com.att.nsa.cambria.client.CambriaBatchingPublisher; +import com.att.nsa.cambria.client.CambriaClientBuilders; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; + +/** + * Provides a publisher that sends messages to a UEB topic. + * + */ +public class Publisher { + + private final Log logger = LogFactory.getLog(getClass()); + + protected final LinkedList urlList = Helper.uebUrlList(); + + private final String topicName; + private final String publisherKey; + private final String publisherSecret; + + /** + * Accepts coordinates needed to publish to a UEB topic. + * + * @param publisherKey + * UEB key used to publish to the topic + * @param publisherSecret + * UEB secret used to publish to the topic + * @param topicName + * UEB topic name + */ + public Publisher(String publisherKey, String publisherSecret, String topicName) { + this.publisherKey = publisherKey; + this.publisherSecret = publisherSecret; + this.topicName = topicName; + logger.info("Publisher instantiated for topic " + topicName); + } + + /** + * Creates a publisher, subscribes to the topic, sends the specified message + * to the topic, then closes the publisher. This ensures that the single + * message goes immediately. UEB is designed for high throughput and tries + * to batch up multiple messages in each send, but this method wants the + * single message to go immediately. + * + * @param uebMsg + * Message object to send as the payload. + * @throws UebException + * If anything goes wrong, including JSON serialization of the + * specified message object. + */ + public void send(UebMsg uebMsg) throws UebException { + String msg = null; + + CambriaBatchingPublisher pub = null; + try { + pub = new CambriaClientBuilders.PublisherBuilder() + .authenticatedBy(publisherKey, publisherSecret).usingHosts(urlList).onTopic(topicName).build(); + } catch (MalformedURLException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (GeneralSecurityException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + try { + ObjectWriter mapper = new ObjectMapper().writer().withDefaultPrettyPrinter(); + msg = mapper.writeValueAsString(uebMsg); + } catch (JsonProcessingException e) { + throw new UebException(PortalApiConstants.ECOMP_UEB_INVALID_MSG, topicName, null, null); + } + + try { + logger.debug("Publishing to " + topicName + " msg: " + msg); + int NumSent = pub.send(PortalApiConstants.ECOMP_GENERAL_UEB_PARTITION, msg); + if (NumSent == 0) { + throw new UebException(PortalApiConstants.ECOMP_UEB_UNKNOWN_PUBLISH_ERROR, topicName, null, msg); + } + } catch (IOException ex) { + logger.error("Failed to publish", ex); + throw new UebException(PortalApiConstants.ECOMP_UEB_UNKNOWN_PUBLISH_ERROR, ex, topicName, null, msg); + } + + try { + // close the publisher to make sure everything's sent before exiting + pub.close(5, TimeUnit.SECONDS); + } catch (Exception ex) { + logger.error("pub.close Exception ", ex); + throw new UebException(PortalApiConstants.ECOMP_UEB_UNKNOWN_PUBLISH_ERROR, ex, topicName, null, msg); + } + + } +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/PublisherList.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/PublisherList.java new file mode 100644 index 0000000..a3a0078 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/PublisherList.java @@ -0,0 +1,77 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.ueb; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * A thin wrapper around ConcurrentHashMap that stores a queue for each + * Requester that is waiting for a Reply. When a reply is received that has a + * matching msgId, that requesters queue is populated with the reply message. + * + * Primarily for Portal core to track the remote applications that have placed + * requests; never used by those applications. + */ +public class PublisherList { + + private final Log logger = LogFactory.getLog(getClass()); + + private final Map map; + + public PublisherList() { + map = new ConcurrentHashMap<>(); + } + + public void addPublisherToMap(String topicName, Publisher publisher) { + if (this.map.containsKey(topicName)) { + logger.error("Publisher already exists for " + topicName); + } else { + this.map.put(topicName, publisher); + } + } + + public Publisher getPublisher(String topicName) { + return this.map.get(topicName); + } + + public void removePublisherFromMap(String topicName) { + this.map.remove(topicName); + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("Map contains " + this.map.size() + " Publishers."); + for (Map.Entry entry : this.map.entrySet()) { + String key = entry.getKey().toString(); + Publisher pub = entry.getValue(); + sb.append("Entry msgId, " + key + " publisher" + pub); + } + return sb.toString(); + } + + public int size() { + return this.map.size(); + } + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/TopicManager.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/TopicManager.java new file mode 100644 index 0000000..b9d730e --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/TopicManager.java @@ -0,0 +1,121 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.ueb; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.LinkedList; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.nsa.apiClient.http.HttpException; +import com.att.nsa.cambria.client.CambriaClient.CambriaApiException; +import com.att.nsa.cambria.client.CambriaClientBuilders; +import com.att.nsa.cambria.client.CambriaClientFactory; +import com.att.nsa.cambria.client.CambriaTopicManager; + +/** + * Provides methods to facilitate creating topics, and adding publishers and + * subscribers to existing topics. + * + */ +public class TopicManager { + + private final Log logger = LogFactory.getLog(getClass()); + + /** + * Creates a topic with the specified information. + * + * @param key + * Topic key + * @param secret + * Topic secret key + * @param topicName + * Topic name + * @param topicDescription + * Topic description + * @throws HttpException + * @throws CambriaApiException + * @throws IOException + */ + public void createTopic(String key, String secret, String topicName, String topicDescription) + throws HttpException, CambriaApiException, IOException { + final LinkedList urlList = Helper.uebUrlList(); + if (logger.isInfoEnabled()) { + logger.info("==> createTopic"); + logger.info("topicName: " + topicName); + logger.info("topicDescription: " + topicDescription); + } + final CambriaTopicManager tm = null; //to do for open source + //CambriaClientFactory.createTopicManager(urlList, key, secret); + tm.createTopic(topicName, topicDescription, 1, 1); + } + + /** + * Modifies the specified topic to accept a subscriber using the specified + * key. + * + * @param topicOwnerKey + * @param topicOwnerSecret + * @param subscriberKey + * @param topicName + * @throws HttpException + * @throws CambriaApiException + * @throws IOException + */ + public void addSubscriber(String topicOwnerKey, String topicOwnerSecret, String subscriberKey, String topicName) + throws HttpException, CambriaApiException, IOException { + logger.info("==> addSubscriber to topic " + topicName); + final LinkedList urlList = Helper.uebUrlList(); + CambriaTopicManager tm = null; + try { + tm = new CambriaClientBuilders.TopicManagerBuilder().usingHosts(urlList).authenticatedBy(topicOwnerKey, topicOwnerSecret).build(); + } catch (GeneralSecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + //old version num : CambriaClientFactory.createTopicManager(urlList, topicOwnerKey,topicOwnerSecret); + tm.allowConsumer(topicName, subscriberKey); + } + + /** + * Modifies the specified topic to accept a publisher using the specified + * key. + * + * @param topicOwnerKey + * @param topicOwnerSecret + * @param publisherKey + * @param topicName + * @throws HttpException + * @throws CambriaApiException + * @throws IOException + */ + + public void addPublisher(String topicOwnerKey, String topicOwnerSecret, String publisherKey, String topicName) + throws HttpException, CambriaApiException, IOException { + logger.info("==> addPublisher to topic " + topicName); + final LinkedList urlList = Helper.uebUrlList(); + final CambriaTopicManager tm = null; + //CambriaClientFactory.createTopicManager(urlList, topicOwnerKey, + //topicOwnerSecret); + tm.allowProducer(topicName, publisherKey); + } +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebException.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebException.java new file mode 100644 index 0000000..62a80dd --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebException.java @@ -0,0 +1,65 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.ueb; + +/** + * Stores UEB-specific information including topic, message ID and message body. + */ +public class UebException extends Exception { + + private static final long serialVersionUID = 1L; + private String topicName = null; + private String msgId = null; + private String msg = null; + + public UebException(String errorMsg, String topicName, String msgId, String msg) { + super(errorMsg); + this.topicName = topicName; + this.msgId = msgId; + this.msg = msg; + } + + public UebException(String errorMsg, Throwable ex, String topicName, String msgId, String msg) { + super(errorMsg, ex); + this.topicName = topicName; + this.msgId = msgId; + this.msg = msg; + } + + public UebException(String msg, Throwable ex) { + super(msg, ex); + } + + public UebException(Throwable ex) { + super(ex); + } + + public String getUebMsg() { + return this.msg; + } + + public String getTopicName() { + return this.topicName; + } + + public String getMsgId() { + return this.msgId; + } +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebManager.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebManager.java new file mode 100644 index 0000000..b38bcb7 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebManager.java @@ -0,0 +1,358 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.ueb; + +import java.io.IOException; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; +import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; + +/** + * Manages UEB interactions and provides methods for publishing requests, + * replies and others. + */ +public class UebManager { + + private final Log logger = LogFactory.getLog(getClass()); + + private WaitingRequestersQueueList waitingRequestersQueueList; + private PublisherList publisherList = new PublisherList(); + private static UebManager uebManager = null; + + private final String inTopicName; + private final String consumerGroupName; + private final String outTopicName; + private final String appUebKey; + private final String appUebSecret; + + private Publisher appPublisher; + private Thread listenerThread; + private boolean bThisIsEcompPortalServer = false; + + /** + * Constructor initializes fields and validates values obtained from + * properties. + * + * The picture below is a simplified view of the relationships among ECOMP + * Portal and applications communicating via UEB: + * + *
+	*                      ECOMP out to many.
+	*                      App out to only ECOMP.
+	*
+	*  |----------------|<---------------------------------------------   
+	*  |                |                                         | |  |
+	*  |                |---------------------------> App 1 ------  |  |
+	*  |  ECOMP Portal  |---------------------------> App 2 ---------  |
+	*  |                |                            ...               |
+	*  |                |---------------------------> App n -----------
+	*  |----------------|
+	 * 
+ * + * @throws IOException + */ + protected UebManager() throws UebException { + waitingRequestersQueueList = null; + listenerThread = null; + outTopicName = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_PORTAL_INBOX_NAME); + inTopicName = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_INBOUND_MAILBOX_NAME); + appUebKey = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); + appUebSecret = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_SECRET); + String consGrp = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_CONSUMER_GROUP_NAME); + + if (outTopicName == null || outTopicName.length() == 0) + throw new UebException("Failed to get property " + PortalApiConstants.ECOMP_PORTAL_INBOX_NAME, null, null, + null); + if (inTopicName == null || inTopicName.length() == 0) + throw new UebException("Failed to get property " + PortalApiConstants.UEB_APP_INBOUND_MAILBOX_NAME, null, + null, null); + if (consGrp == null || consGrp.length() == 0) + throw new UebException("Failed to get property " + PortalApiConstants.UEB_APP_CONSUMER_GROUP_NAME, null, + null, null); + if (appUebKey == null || appUebKey.length() == 0) + throw new UebException("Failed to get property " + PortalApiConstants.UEB_APP_KEY, null, null, null); + if (appUebSecret == null || appUebSecret.length() == 0) + throw new UebException("Failed to get property " + PortalApiConstants.UEB_APP_SECRET, null, null, null); + List uebUrlList = Helper.uebUrlList(); + if (uebUrlList == null || uebUrlList.size() == 0) + throw new UebException("Failed to get property" + PortalApiConstants.UEB_URL_LIST, null, null, null); + // A bit of magic: if consumer group is a magic token, generate one. + consumerGroupName = (PortalApiConstants.UEB_APP_CONSUMER_GROUP_NAME_GENERATOR.equals(consGrp) + ? UUID.randomUUID().toString() : consGrp); + } + + /** + * Gets the static instance, creating it if necessary. + * + * @return Instance of UebManager + * @throws IOException + */ + public static synchronized UebManager getInstance() throws UebException { + if (uebManager == null) { + uebManager = new UebManager(); + } + return uebManager; + } + + /** + * Answers whether the getInstance() method has previously been called. + * + * @return True if a static instance is available, else false. + */ + public static boolean isInstanceAvailable() { + return uebManager != null; + } + + /** + * Creates a list of waiting requesters, creates and a consumer using cached + * information, and starts a new thread to run the consumer that listens for + * messages published to the inbound topic configured in the constructor. + * + * @param inboxQueue + * Queue supplied to the consumer. If not null, the consumer will + * enqueue every message it receives. + */ + public void initListener(ConcurrentLinkedQueue inboxQueue) throws UebException { + waitingRequestersQueueList = new WaitingRequestersQueueList(); + Consumer runnable = new Consumer(appUebKey, appUebSecret, inTopicName, consumerGroupName, inboxQueue, + waitingRequestersQueueList); + this.listenerThread = new Thread(runnable, "UEBConsumerThread"); + this.listenerThread.start(); + Helper.sleep(400); // UEB functions more reliably when we give this some + // time + + logger.info("UEBManager instance starting... " + inTopicName + " listener thread " + + this.listenerThread.getName() + " state = " + this.listenerThread.getState()); + + /* + * ECOMP Portal manages a dynamic list of outbound topics and so the + * outTopicName is initialized in this logic with the same value as the + * inbound topic. The real outbound topics name will be added to the + * publisher list for ECOMP Portal. For an SDK/App instance only one + * publisher is needed, appPublisher. + */ + if (inTopicName.equalsIgnoreCase(outTopicName)) { + this.bThisIsEcompPortalServer = true; + } else { + appPublisher = new Publisher(appUebKey, appUebSecret, outTopicName); + Helper.sleep(400); + } + } + + /** + * Creates and adds a publisher to the list for the specified topic. This + * should only be called by the ECOMP Portal App, other Apps have just one + * publisher and use appPublisher + * + * @param topicName + */ + public void addPublisher(String topicName) { + logger.info("UEBManager adding publisher for " + topicName); + Publisher outBoxToAppPublisher = new Publisher(appUebKey, appUebSecret, topicName); + publisherList.addPublisherToMap(topicName, outBoxToAppPublisher); + } + + /** + * Removes a publisher from the list for the specified topic. + * + * This should only be called by the ECOMP Portal App, other Apps have just + * one publisher and use appPublisher + * + * @param topicName + */ + public void removePublisher(String topicName) { + logger.info("UEBManager removing publisher for " + topicName); + publisherList.removePublisherFromMap(topicName); + } + + /** + * Adds the default ECOMP message ID to the message and sends the message to + * the topic. + * + * @param msg + * @throws UebException + */ + public void publish(UebMsg msg) throws UebException { + msg.putMsgId(PortalApiConstants.ECOMP_DEFAULT_MSG_ID); + appPublisher.send(msg); + } + + /** + * Sends the message using the default publisher. + * + * @param msg + * @throws UebException + */ + public void publishReply(UebMsg msg) throws UebException { + // Caller populates msgId with the echoed value from the request + appPublisher.send(msg); + } + + /** + * Sends the message using the appropriate publisher for the specified + * topic. + * + * @param msg + * @param topicName + * @throws UebException + */ + public void publishEP(UebMsg msg, String topicName) throws UebException { + Publisher publisher = publisherList.getPublisher(topicName); + if (publisher != null) { + msg.putMsgId(PortalApiConstants.ECOMP_DEFAULT_MSG_ID); + publisher.send(msg); + } + } + + /** + * Publishes a reply using the appropriate publisher for the specified + * topic. + * + * @param msg + * @param topicName + * @throws UebException + */ + public void publishReplyEP(UebMsg msg, String topicName) throws UebException { + // Caller populates msgId with the echoed value from the request + Publisher publisher = publisherList.getPublisher(topicName); + if (publisher != null) { + publisher.send(msg); + } + } + + /** + * Sends the specified message using the specified publisher, and waits for + * a reply. Retransmits if no reply is received in 5 seconds; gives up after + * 3 retries. + * + * @param msg + * @param publisher + * @return Message from a remote publisher, or null if timeout happens. + * @throws UebException + */ + public UebMsg requestReplyUsingPublisher(UebMsg msg, Publisher publisher) throws UebException { + UebMsg reply = null; + if (waitingRequestersQueueList == null) { + logger.error("requestReplyUsingPublisher called but listener thread not initialized"); + } else { + // Storing a non-default message ID identifies this as a synchronous + // request + msg.putMsgId(UUID.randomUUID().toString()); + + /* + * Create a queue for this request, the consumer thread will insert + * the reply on this queue + */ + LinkedBlockingQueue replyQueue = new LinkedBlockingQueue(); + waitingRequestersQueueList.addQueueToMap(msg.getMsgId(), replyQueue); + + /* + * Send the request + */ + publisher.send(msg); + + /* + * Wait for reply up to 3 * 5 = 15 seconds + */ + int reTransmits = 0; + int maxRetransmits = 3; + int retransmitTimeMs = 5000; + long sendTimeStamp = System.currentTimeMillis(); + while (reTransmits < maxRetransmits) { + if ((reply = replyQueue.poll()) != null) + break; + + long now = System.currentTimeMillis(); + if (now - sendTimeStamp > retransmitTimeMs) { + logger.debug("Retransmitting send... msg = " + msg.getPayload() + msg.getMsgId()); + publisher.send(msg); + sendTimeStamp = System.currentTimeMillis(); + reTransmits++; + } + } + waitingRequestersQueueList.removeQueueFromMap(msg.getMsgId()); + if (reTransmits == maxRetransmits) + throw new UebException(PortalApiConstants.ECOMP_UEB_TIMEOUT_ERROR, inTopicName, null, msg.toString()); + + } + return reply; + } + + /** + * Sends the specified message using the default publisher and waits for a + * reply. + * + * @param msg + * @return Message from a remote publisher, or null if timeout happens. + * @throws UebException + */ + public UebMsg requestReply(UebMsg msg) throws UebException { + return requestReplyUsingPublisher(msg, appPublisher); + } + + /** + * Sends the specified message using the publisher appropriate for the + * specified topic name, and waits for a reply. + * + * @param msg + * @param topicName + * @return Message from a remote publisher, or null if timeout happens. + * @throws UebException + */ + public UebMsg requestReplyEP(UebMsg msg, String topicName) throws UebException { + UebMsg returnMsg = null; + Publisher publisher = publisherList.getPublisher(topicName); + if (publisher != null) { + returnMsg = requestReplyUsingPublisher(msg, publisher); + } + return returnMsg; + } + + /** + * Publishes the payload as a UEB widget-notification message on the default + * publisher. Intended for use by Apps inter widget communication, not EP + * itself. + * + * @param payload + * @param userId + */ + public void postWidgetNotification(String payload, String userId) throws UebException { + UebMsg msg = new UebMsg(); + msg.putPayload(payload); + msg.putUserId(userId); + msg.putMsgType(UebMsgTypes.UEB_MSG_TYPE_WIDGET_NOTIFICATION); + this.publish(msg); + } + + /** + * Interrupts the long-running thread that runs the consumer. + */ + public void shutdown() { + if (this.listenerThread != null) { + this.listenerThread.interrupt(); + } + } +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsg.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsg.java new file mode 100644 index 0000000..ff30840 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsg.java @@ -0,0 +1,119 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.ueb; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; +import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class UebMsg { + + private final Log logger = LogFactory.getLog(getClass()); + + private String version; + private String msgId; + private long timeStamp; + private String payload; + private String msgType; + private String userId; + private String sourceTopicName; + private String sourceIP; + private String sourceHostName; + + /** + * Creates a new object and populates the fields source IP, source topic, + * time stamp, version, and message id. + */ + public UebMsg() { + InetAddress ip; + try { + ip = InetAddress.getLocalHost(); + // Do not attempt to get name, why wait on DNS every time? + // sourceHostName = ip.getHostName(); + sourceIP = ip.getHostAddress(); + } catch (UnknownHostException e) { + sourceHostName = "unknown"; + sourceIP = "unknown"; + } + + this.timeStamp = System.currentTimeMillis(); + this.version = "1.0"; + this.msgId = PortalApiConstants.ECOMP_DEFAULT_MSG_ID; + this.payload = "empty payload content"; + this.sourceTopicName = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_INBOUND_MAILBOX_NAME); + if (this.sourceTopicName == null) + logger.error("Failed to get property " + PortalApiConstants.UEB_APP_INBOUND_MAILBOX_NAME); + } + + public void putMsgId(String msgId) { + this.msgId = msgId; + } + + public String getMsgId() { + return msgId; + } + + public void putPayload(String payload) { + this.payload = payload; + } + + public String getPayload() { + return payload; + } + + public void putMsgType(String msgType) { + this.msgType = msgType; + } + + public String getMsgType() { + return this.msgType; + } + + public void putUserId(String userId) { + this.userId = userId; + } + + public String getUserId() { + return this.userId; + } + + public void putSourceTopicName(String topic) { + this.sourceTopicName = topic; + } + + public String getSourceTopicName() { + return this.sourceTopicName; + } + + @Override + public String toString() { + return "UebMsg [version=" + version + ", msgId=" + msgId + ", timeStamp=" + timeStamp + ", msgType=" + msgType + + ", userId=" + userId + ", sourceTopicName=" + sourceTopicName + ", sourceIP=" + sourceIP + + ", sourceHostName=" + sourceHostName + "]" + System.lineSeparator() + "payload=" + payload; + } + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsgTypes.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsgTypes.java new file mode 100644 index 0000000..9e51fe5 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsgTypes.java @@ -0,0 +1,28 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.ueb; + +/** + * Publishes constants used in the UEB package. + */ +public interface UebMsgTypes { + public static final String UEB_MSG_TYPE_GET_FUNC_MENU = "uebMsgTypeGetFuncMenu"; + public static final String UEB_MSG_TYPE_WIDGET_NOTIFICATION = "uebMsgTypeWidgetNotification"; +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/WaitingRequestersQueueList.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/WaitingRequestersQueueList.java new file mode 100644 index 0000000..d406360 --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/WaitingRequestersQueueList.java @@ -0,0 +1,73 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.onboarding.ueb; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingQueue; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * A thin wrapper around ConcurrentHashMap that stores a queue for each + * Requester that is waiting for a Reply. When a reply is received that has a + * matching msgId, that requesters queue is populated with the reply message. + * + * Primarily for the UebManager to track requests while it waits for responses. + */ +public class WaitingRequestersQueueList { + private final Log logger = LogFactory.getLog(getClass()); + + private final Map> map; + + public WaitingRequestersQueueList() { + map = new ConcurrentHashMap<>(); + } + + public void addQueueToMap(String msgId, LinkedBlockingQueue queue) { + this.map.put(msgId, queue); + } + + public void addMsg(String msgId, UebMsg message) { + LinkedBlockingQueue queue = this.map.get(msgId); + if (queue != null) { + queue.add(message); + } else { + logger.warn("Did not find entry in WaitingRequestersQueueList for msgId " + msgId); + } + } + + public void removeQueueFromMap(String msgId) { + this.map.remove(msgId); + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("Map contains " + this.map.size() + " Publishers."); + for (Map.Entry> entry : this.map.entrySet()) { + String key = entry.getKey().toString(); + LinkedBlockingQueue queue = entry.getValue(); + sb.append("Entry msgId, " + key + " queue " + queue); + } + return sb.toString(); + } + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompRole.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompRole.java new file mode 100644 index 0000000..a65d16f --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompRole.java @@ -0,0 +1,87 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.restful.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * This bean holds the information for a role in the role and user management + * REST API. + */ + +@JsonIgnoreProperties(ignoreUnknown = true) +public class EcompRole implements Comparable{ + + protected Long id; + private String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + EcompRole other = (EcompRole) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + + @Override + public String toString() { + String s = "@EcompRole[id: " + id + "; name: " + name + "]"; + return s; + } + + @Override + public int compareTo(EcompRole o) { + return this.id.compareTo(o.id); + } + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompUser.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompUser.java new file mode 100644 index 0000000..732878e --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompUser.java @@ -0,0 +1,197 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.restful.domain; + +import java.util.Set; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * This bean holds the information for a user in the role and user management + * REST API. + */ + +@JsonIgnoreProperties(ignoreUnknown = true) +public class EcompUser implements Comparable{ + + private Long orgId; + private String managerId; + private String firstName; + private String middleInitial; + private String lastName; + private String phone; + private String email; + private String hrid; + private String orgUserId; + private String orgCode; + private String orgManagerUserId; + private String jobTitle; + private String loginId; + private boolean active; + + + private Set roles; + + public Long getOrgId() { + return orgId; + } + + public void setOrgId(Long orgId) { + this.orgId = orgId; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getMiddleInitial() { + return middleInitial; + } + + public void setMiddleInitial(String middleInitial) { + this.middleInitial = middleInitial; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getHrid() { + return hrid; + } + + public void setHrid(String hrid) { + this.hrid = hrid; + } + + public String getOrgUserId() { + return orgUserId; + } + + public void setOrgUserId(String orgUserId) { + this.orgUserId = orgUserId; + } + + public String getOrgCode() { + return orgCode; + } + + public void setOrgCode(String orgCode) { + this.orgCode = orgCode; + } + + public String getOrgManagerUserId() { + return orgManagerUserId; + } + + public void setOrgManagerUserId(String orgManagerUserId) { + this.orgManagerUserId = orgManagerUserId; + } + + public String getJobTitle() { + return jobTitle; + } + + public void setJobTitle(String jobTitle) { + this.jobTitle = jobTitle; + } + + public String getLoginId() { + return loginId; + } + + public void setLoginId(String loginId) { + this.loginId = loginId; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + + public Set getRoles() { + return roles; + } + + public void setRoles(Set roles) { + this.roles = roles; + } + + public String getManagerId() { + return managerId; + } + + public void setManagerId(String managerId) { + this.managerId = managerId; + } + + @Override + public String toString() { + String s = "@EcompUser[orgId: " + orgId // + + ", firstName: " + firstName // + + ", mi: " + middleInitial // + + ", lastName: " + lastName // + + ", phone: " + phone // + + ", email: " + email // + + ", hrid: " + hrid // + + ", orgUserId: " + orgUserId // + + ", orgCode: " + orgCode // + + ", orgManagerUserId: " + orgManagerUserId // + + ", jobTitle: " + jobTitle // + + ", loginId: " + loginId // + + ", active:" + active // + + "]"; + return s; + } + + @Override + public int compareTo(EcompUser o) { + return this.loginId.compareTo(o.loginId); + } + + +} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/SharedContext.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/SharedContext.java new file mode 100644 index 0000000..4eeb12f --- /dev/null +++ b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/SharedContext.java @@ -0,0 +1,300 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + * ================================================================================ + */ +package org.openecomp.portalsdk.core.restful.domain; + +/** + * Bean that represents shared-context data transferred in JSON objects. This is + * a minimum example: + * + *
+ * {
+ *   "context_id": "abc123",
+ *   "ckey": "myKey",
+ *   "cvalue": "my context value to share"
+ * }
+ * 
+ */ +public class SharedContext { + + // Response field indicates nothing else is present + private String response; + // Required fields when data is present + private String context_id, ckey, cvalue; + private Long id, create_time; + // Additional database fields from the DomainVO object. + private String created, modified, createdId, modifiedId, auditUserId, auditTrail, rowNum; + + /** + * Gets the response field. + * + * @return response + */ + public String getResponse() { + return response; + } + + /** + * Sets the response field. + * + * @param response + * The response to set + */ + public void setResponse(final String response) { + this.response = response; + } + + /** + * Gets the database row ID. + * + * @return Database row ID + */ + public Long getId() { + return id; + } + + /** + * Sets the database row ID. + * + * @param id + */ + public void setId(final Long id) { + this.id = id; + } + + /** + * Gets the creation time + * + * @return Creation time as a Long + */ + public Long getCreate_time() { + return create_time; + } + + /** + * Sets the creation time + * + * @param create_time + */ + public void setCreate_time(final Long create_time) { + this.create_time = create_time; + } + + /** + * Gets the context ID + * + * @return Context ID + */ + public String getContext_id() { + return context_id; + } + + /** + * Sets the context ID + * + * @param context_id + */ + public void setContext_id(final String context_id) { + this.context_id = context_id; + } + + /** + * Gets the key of the key-value pair. Called ckey because "key" is a + * reserved word in Mysql. + * + * @return The key + */ + public String getCkey() { + return ckey; + } + + /** + * Sets the key of the key-value pair. + * + * @param ckey + */ + public void setCkey(final String ckey) { + this.ckey = ckey; + } + + /** + * Gets the value of the key-value pair. Called cvalue because "value" is a + * reserved word in Mysql. + * + * @return Value of the key-value pair. + */ + public String getCvalue() { + return cvalue; + } + + /** + * Sets the value of the key-value pair. + * + * @param cvalue + */ + public void setCvalue(final String cvalue) { + this.cvalue = cvalue; + } + + /** + * Gets the created value. + * + * @return Created info from database + */ + public String getCreated() { + return created; + } + + /** + * Sets the created value. + * + * @param created + */ + public void setCreated(String created) { + this.created = created; + } + + /** + * Gets the modified value. + * + * @return Modified info from database + */ + public String getModified() { + return modified; + } + + /** + * Sets the modified value. + * + * @param modified + */ + public void setModified(String modified) { + this.modified = modified; + } + + /** + * Gets the createdId value. + * + * @return CreatedId info from database + */ + public String getCreatedId() { + return createdId; + } + + /** + * Sets the createdId value. + * + * @param createdId + */ + public void setCreatedId(String createdId) { + this.createdId = createdId; + } + + /** + * Gets the modifiedId value. + * + * @return ModifiedId info from database + */ + public String getModifiedId() { + return modifiedId; + } + + /** + * Sets the modifiedId value. + * + * @param modifiedId + */ + public void setModifiedId(String modifiedId) { + this.modifiedId = modifiedId; + } + + /** + * Gets the audit user ID value. + * + * @return AuditUserId from database + */ + public String getAuditUserId() { + return auditUserId; + } + + /** + * Sets the audit user ID value. + * + * @param auditUserId + */ + public void setAuditUserId(String auditUserId) { + this.auditUserId = auditUserId; + } + + /** + * Gets the audit trail value. + * + * @return AuditTrail from database. + */ + public String getAuditTrail() { + return auditTrail; + } + + /** + * Sets the audit trail value. + * + * @param auditTrail + */ + public void setAuditTrail(String auditTrail) { + this.auditTrail = auditTrail; + } + + /** + * Gets the row num value. + * + * @return rowNum from database. + */ + public String getRowNum() { + return rowNum; + } + + /** + * Sets the row num value. + * + * @param rowNum + */ + public void setRowNum(String rowNum) { + this.rowNum = rowNum; + } + + @Override + public boolean equals(Object obj) { + SharedContext other = (SharedContext) obj; + return this.id == other.id && this.context_id.equals(other.context_id) && this.ckey.equals(other.ckey) + && this.cvalue.equals(other.cvalue); + } + + @Override + public int hashCode() { + return (int) (id + context_id.hashCode() + ckey.hashCode() + cvalue.hashCode()); + } + + @Override + public String toString() { + String s = "@SharedContext[id: " + id + "; context_id: " + context_id + "; ckey: " + ckey + "; cvalue: " + + cvalue + "]"; + return s; + } + +} -- cgit 1.2.3-korg