diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/ui/HubspotChat.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/ui/HubspotChat.java
new file mode 100644
index 0000000000..728176e1db
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/ui/HubspotChat.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
+ *
+ * Entgra (Pvt) Ltd. licenses this file to you 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.wso2.carbon.device.mgt.core.config.ui;
+
+import javax.xml.bind.annotation.XmlElement;
+
+public class HubspotChat {
+ private boolean isEnableHubspot;
+ private String trackingUrl;
+ private String accessToken;
+ private String senderActorId;
+ private long channelAccountId;
+
+ @XmlElement(name = "EnableHubspot")
+ public boolean isEnableHubspot() {
+ return isEnableHubspot;
+ }
+
+ public void setEnableHubspot(boolean enableHubspot) {
+ isEnableHubspot = enableHubspot;
+ }
+
+ @XmlElement(name = "TrackingUrl")
+ public String getTrackingUrl() {
+ return trackingUrl;
+ }
+
+ public void setTrackingUrl(String trackingUrl) {
+ this.trackingUrl = trackingUrl;
+ }
+
+ @XmlElement(name = "AccessToken")
+ public String getAccessToken() {
+ return accessToken;
+ }
+
+ public void setAccessToken(String accessToken) {
+ this.accessToken = accessToken;
+ }
+ @XmlElement(name = "SenderActorId")
+ public String getSenderActorId() {
+ return senderActorId;
+ }
+
+ public void setSenderActorId(String senderActorId) {
+ this.senderActorId = senderActorId;
+ }
+ @XmlElement(name = "ChannelAccountId")
+ public long getChannelAccountId() {
+ return channelAccountId;
+ }
+
+ public void setChannelAccountId(long channelAccountId) {
+ this.channelAccountId = channelAccountId;
+ }
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/ui/UIConfiguration.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/ui/UIConfiguration.java
index 551c1558ea..dca4a76a6b 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/ui/UIConfiguration.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/ui/UIConfiguration.java
@@ -34,6 +34,7 @@ public class UIConfiguration {
private int sessionTimeOut;
private int loginCacheCapacity;
private Billing billing;
+ private HubspotChat hubspotChat;
@XmlElement(name = "AppRegistration", required=true)
public AppRegistration getAppRegistration() {
@@ -63,6 +64,14 @@ public class UIConfiguration {
isSsoEnable = ssoEnable;
}
+ @XmlElement(name = "HubspotChat", required = true)
+ public HubspotChat getHubspotChat() {
+ return hubspotChat;
+ }
+
+ public void setHubspotChat(HubspotChat hubspotChat) {
+ this.hubspotChat = hubspotChat;
+ }
@XmlElement(name = "Billing", required=true)
public Billing getBilling() {
return billing;
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/metadata/mgt/MetadataManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/metadata/mgt/MetadataManagementServiceImpl.java
index 7d7fd1d7c0..455a583520 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/metadata/mgt/MetadataManagementServiceImpl.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/metadata/mgt/MetadataManagementServiceImpl.java
@@ -20,6 +20,7 @@ package org.wso2.carbon.device.mgt.core.metadata.mgt;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
@@ -91,8 +92,14 @@ public class MetadataManagementServiceImpl implements MetadataManagementService
}
try {
MetadataManagementDAOFactory.openConnection();
- return metadataDAO.getMetadata(
- PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true), metaKey);
+ int tenantId;
+ if (metaKey.equals("EVALUATE_TENANTS")){
+ // for getting evaluate tenant list to provide the live chat feature
+ tenantId = MultitenantConstants.SUPER_TENANT_ID;
+ } else {
+ tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
+ }
+ return metadataDAO.getMetadata(tenantId, metaKey);
} catch (MetadataManagementDAOException e) {
String msg = "Error occurred while retrieving the metadata entry for metaKey:" + metaKey;
log.error(msg, e);
diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/HubspotHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/HubspotHandler.java
new file mode 100644
index 0000000000..b649d341fe
--- /dev/null
+++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/HubspotHandler.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
+ *
+ * Entgra (Pvt) Ltd. licenses this file to you 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 io.entgra.ui.request.interceptor;
+
+import com.google.gson.JsonObject;
+import io.entgra.ui.request.interceptor.beans.ProxyResponse;
+import io.entgra.ui.request.interceptor.util.HandlerConstants;
+import io.entgra.ui.request.interceptor.util.HandlerUtil;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+
+import javax.servlet.annotation.MultipartConfig;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+
+@MultipartConfig
+@WebServlet(
+ name = "HubspotRequestHandlerServlet",
+ description = "",
+ urlPatterns = {
+ "/hubspot/*"
+ }
+)
+public class HubspotHandler extends HttpServlet {
+
+ private static final Log log = LogFactory.getLog(HubspotHandler.class);
+ private HttpSession httpSession;
+ private static String hubspotEndpoint;
+ private static String chatConfig;
+ private JsonObject uiConfigJsonObject;
+ private static String gatewayUrl;
+ private static String iotsCoreUrl;
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
+ try {
+ if (validateRequest(req, resp)) {
+ HttpPost postRequest = new HttpPost(HandlerUtil.generateBackendRequestURL(req, hubspotEndpoint));
+ HandlerUtil.generateChatRequestEntity(req, postRequest);
+ postRequest.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
+ postRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BEARER + chatConfig);
+ ProxyResponse proxyResponse = HandlerUtil.execute(postRequest);
+ HandlerUtil.handleSuccess(resp, proxyResponse);
+ }
+ } catch (IOException e) {
+ log.error("Error occurred when processing POST request.", e);
+ }
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
+ try {
+ if (validateRequest(req, resp)) {
+ HttpGet getRequest = new HttpGet(HandlerUtil.generateBackendRequestURL(req,hubspotEndpoint));
+ getRequest.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
+ getRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BEARER + chatConfig);
+ ProxyResponse proxyResponse = HandlerUtil.execute(getRequest);
+ HandlerUtil.handleSuccess(resp, proxyResponse);
+ }
+ } catch (IOException e) {
+ log.error("Error occurred when processing GET request.", e);
+ }
+ }
+
+ /***
+ * Validates the hubspot's incoming request.
+ *
+ * @param req {@link HttpServletRequest}
+ * @param resp {@link HttpServletResponse}
+ * @return If request is a valid one, returns TRUE, otherwise return FALSE
+ * @throws IOException If and error occurs while witting error response to client side
+ */
+ private boolean validateRequest(HttpServletRequest req, HttpServletResponse resp)
+ throws IOException {
+ httpSession = req.getSession(false);
+ if (httpSession == null) {
+ log.error("Unauthorized, You are not logged in. Please log in to the portal");
+ HandlerUtil.handleError(resp, HttpStatus.SC_UNAUTHORIZED);
+ return false;
+ }
+ if (req.getMethod() == null) {
+ log.error("Bad Request, Request method is empty");
+ HandlerUtil.handleError(resp, HttpStatus.SC_BAD_REQUEST);
+ return false;
+ }
+ gatewayUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_GW_HOST_ENV_VAR)
+ + HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme());
+ iotsCoreUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
+ + HandlerConstants.COLON + HandlerUtil.getCorePort(req.getScheme());
+ String uiConfigUrl = iotsCoreUrl + HandlerConstants.UI_CONFIG_ENDPOINT;
+ uiConfigJsonObject = HandlerUtil.getUIConfigAndPersistInSession(uiConfigUrl, gatewayUrl, httpSession, resp);
+ chatConfig = uiConfigJsonObject.get("hubspotChat").getAsJsonObject().get("accessToken").getAsString();
+ hubspotEndpoint = HandlerConstants.HTTPS_PROTOCOL + HandlerConstants.SCHEME_SEPARATOR + HandlerConstants.HUBSPOT_CHAT_URL;
+ return true;
+ }
+}
diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java
index bf9947a9af..27d6afaadc 100644
--- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java
+++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java
@@ -105,4 +105,5 @@ public class HandlerConstants {
public static final String IOT_GW_HTTPS_PORT_ENV_VAR = "iot.gateway.https.port";
public static final String IOT_REPORTING_WEBAPP_HOST_ENV_VAR = "iot.reporting.webapp.host";
public static final String USER_SCOPES = "userScopes";
+ public static final String HUBSPOT_CHAT_URL = "api.hubapi.com";
}
diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java
index fb565bf59b..b7376abddc 100644
--- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java
+++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java
@@ -435,6 +435,23 @@ public class HandlerUtil {
}
}
+ /**
+ * Generate te request entity for POST requests from the hubspot's incoming request.
+ *
+ * @param req incoming {@link HttpServletRequest}.
+ * @param proxyRequest proxy request instance.
+ * @throws IOException If error occurred while generating the request body.
+ */
+ public static void generateChatRequestEntity(HttpServletRequest req, HttpEntityEnclosingRequestBase proxyRequest)
+ throws IOException {
+ if (StringUtils.isNotEmpty(req.getHeader(HttpHeaders.CONTENT_LENGTH)) ||
+ StringUtils.isNotEmpty(req.getHeader(HttpHeaders.TRANSFER_ENCODING))) {
+ InputStreamEntity entity = new InputStreamEntity(req.getInputStream(),
+ Long.parseLong(req.getHeader(HttpHeaders.CONTENT_LENGTH)));
+ proxyRequest.setEntity(new BufferedHttpEntity(entity));
+ }
+ }
+
/***
* Constructs the application registration payload for DCR.
*
diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml
index d36e26a3cc..d30f414885 100644
--- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml
+++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml
@@ -24,6 +24,15 @@
3600
10000
+
+
+ false
+ tracking_url
+
+ access_token
+ sender_actorId
+ channel_AccountId
+
false
true