diff --git a/catalog-rest-service/pom.xml b/catalog-rest-service/pom.xml
index 920ee44ab86..92094719a27 100644
--- a/catalog-rest-service/pom.xml
+++ b/catalog-rest-service/pom.xml
@@ -390,6 +390,21 @@
org.jeasy
easy-rules-core
+
+ io.socket
+ socket.io-server
+ 4.0.1
+
+
+ io.socket
+ engine.io-server-jetty
+ 6.2.1
+
+
+ org.eclipse.jetty.websocket
+ websocket-server
+ 9.4.46.v20220331
+
diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/CatalogApplication.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/CatalogApplication.java
index 131617be50c..a80b48ae193 100644
--- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/CatalogApplication.java
+++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/CatalogApplication.java
@@ -32,6 +32,8 @@ import io.federecio.dropwizard.swagger.SwaggerBundleConfiguration;
import io.github.maksymdolgykh.dropwizard.micrometer.MicrometerBundle;
import io.github.maksymdolgykh.dropwizard.micrometer.MicrometerHttpFilter;
import io.github.maksymdolgykh.dropwizard.micrometer.MicrometerJdbiTimingCollector;
+import io.socket.engineio.server.EngineIoServerOptions;
+import io.socket.engineio.server.JettyWebSocketHandler;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.time.temporal.ChronoUnit;
@@ -39,13 +41,18 @@ import java.util.EnumSet;
import java.util.Optional;
import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
+import javax.servlet.ServletException;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.Response;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jetty.http.pathmap.ServletPathSpec;
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ServerProperties;
import org.jdbi.v3.core.Jdbi;
@@ -74,12 +81,17 @@ import org.openmetadata.catalog.security.policyevaluator.PolicyEvaluator;
import org.openmetadata.catalog.security.policyevaluator.RoleEvaluator;
import org.openmetadata.catalog.slack.SlackPublisherConfiguration;
import org.openmetadata.catalog.slack.SlackWebhookEventPublisher;
+import org.openmetadata.catalog.socket.FeedServlet;
+import org.openmetadata.catalog.socket.SocketAddressFilter;
+import org.openmetadata.catalog.socket.WebSocketManager;
/** Main catalog application */
@Slf4j
public class CatalogApplication extends Application {
private Authorizer authorizer;
+ private SocketAddressFilter socketAddressFilter = null;
+
@Override
public void run(CatalogApplicationConfig catalogConfig, Environment environment)
throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException,
@@ -151,6 +163,7 @@ public class CatalogApplication extends Application {
FilterRegistration.Dynamic micrometerFilter =
environment.servlets().addFilter("MicrometerHttpFilter", new MicrometerHttpFilter());
micrometerFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");
+ intializeWebsockets(environment);
}
@SneakyThrows
@@ -201,7 +214,11 @@ public class CatalogApplication extends Application {
InstantiationException {
AuthorizerConfiguration authorizerConf = catalogConfig.getAuthorizerConfiguration();
AuthenticationConfiguration authenticationConfiguration = catalogConfig.getAuthenticationConfiguration();
+ // to authenticate request while opening websocket connections
if (authorizerConf != null) {
+ if (authorizerConf.getEnableSecureSocketConnection()) {
+ socketAddressFilter = new SocketAddressFilter(authenticationConfiguration, authorizerConf);
+ }
authorizer =
Class.forName(authorizerConf.getClassName()).asSubclass(Authorizer.class).getConstructor().newInstance();
String filterClazzName = authorizerConf.getContainerRequestFilter();
@@ -261,6 +278,29 @@ public class CatalogApplication extends Application {
environment.getApplicationContext().setErrorHandler(eph);
}
+ private void intializeWebsockets(Environment environment) {
+ EngineIoServerOptions eioOptions = EngineIoServerOptions.newFromDefault();
+ eioOptions.setAllowedCorsOrigins(null);
+ WebSocketManager.WebSocketManagerBuilder.build(eioOptions);
+ environment.getApplicationContext().setContextPath("/");
+ if (socketAddressFilter != null)
+ environment
+ .getApplicationContext()
+ .addFilter(new FilterHolder(socketAddressFilter), "/api/v1/push/feed/*", EnumSet.of(DispatcherType.REQUEST));
+ environment.getApplicationContext().addServlet(new ServletHolder(new FeedServlet()), "/api/v1/push/feed/*");
+ // Upgrade connection to websocket from Http
+ try {
+ WebSocketUpgradeFilter webSocketUpgradeFilter =
+ WebSocketUpgradeFilter.configureContext(environment.getApplicationContext());
+ webSocketUpgradeFilter.addMapping(
+ new ServletPathSpec("/api/v1/push/feed/*"),
+ (servletUpgradeRequest, servletUpgradeResponse) ->
+ new JettyWebSocketHandler(WebSocketManager.getInstance().getEngineIoServer()));
+ } catch (ServletException ex) {
+ LOG.error("Websocket Upgrade Filter error : ", ex.getMessage());
+ }
+ }
+
public static void main(String[] args) throws Exception {
CatalogApplication catalogApplication = new CatalogApplication();
catalogApplication.run(args);
diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/events/ChangeEventHandler.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/events/ChangeEventHandler.java
index 6831db26314..328f0b1c72b 100644
--- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/events/ChangeEventHandler.java
+++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/events/ChangeEventHandler.java
@@ -18,6 +18,7 @@ import static org.openmetadata.catalog.type.EventType.ENTITY_SOFT_DELETED;
import static org.openmetadata.catalog.type.EventType.ENTITY_UPDATED;
import static org.openmetadata.common.utils.CommonUtil.listOrEmpty;
+import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -36,6 +37,7 @@ import org.openmetadata.catalog.entity.feed.Thread;
import org.openmetadata.catalog.jdbi3.CollectionDAO;
import org.openmetadata.catalog.jdbi3.FeedRepository;
import org.openmetadata.catalog.resources.feeds.MessageParser.EntityLink;
+import org.openmetadata.catalog.socket.WebSocketManager;
import org.openmetadata.catalog.type.ChangeDescription;
import org.openmetadata.catalog.type.ChangeEvent;
import org.openmetadata.catalog.type.EntityReference;
@@ -48,10 +50,12 @@ import org.openmetadata.catalog.util.RestUtil;
public class ChangeEventHandler implements EventHandler {
private CollectionDAO dao;
private FeedRepository feedDao;
+ private ObjectMapper mapper;
public void init(CatalogApplicationConfig config, Jdbi jdbi) {
this.dao = jdbi.onDemand(CollectionDAO.class);
this.feedDao = new FeedRepository(dao);
+ this.mapper = new ObjectMapper();
}
public Void process(ContainerRequestContext requestContext, ContainerResponseContext responseContext) {
@@ -100,6 +104,8 @@ public class ChangeEventHandler implements EventHandler {
}
EntityLink about = EntityLink.parse(thread.getAbout());
feedDao.create(thread, entity.getId(), owner, about);
+ String json = mapper.writeValueAsString(thread);
+ WebSocketManager.getInstance().broadCastMessageToClients(json);
}
}
}
diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthorizerConfiguration.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthorizerConfiguration.java
index 25b61b73c4f..0492f72924d 100644
--- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthorizerConfiguration.java
+++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthorizerConfiguration.java
@@ -25,6 +25,7 @@ public class AuthorizerConfiguration {
@NotEmpty @Getter @Setter private Set botPrincipals;
@NotEmpty @Getter @Setter private String principalDomain;
@NotEmpty @Getter @Setter private Boolean enforcePrincipalDomain;
+ @NotEmpty @Getter @Setter private Boolean enableSecureSocketConnection;
@Override
public String toString() {
diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/JwtFilter.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/JwtFilter.java
index 9f1918023f3..80b828adb1b 100644
--- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/JwtFilter.java
+++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/JwtFilter.java
@@ -56,7 +56,6 @@ public class JwtFilter implements ContainerRequestFilter {
public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String TOKEN_PREFIX = "Bearer";
public static final String BOT_CLAIM = "isBot";
-
private List jwtPrincipalClaims;
private JwkProvider jwkProvider;
private String principalDomain;
@@ -104,10 +103,33 @@ public class JwtFilter implements ContainerRequestFilter {
String tokenFromHeader = extractToken(headers);
LOG.debug("Token from header:{}", tokenFromHeader);
+ DecodedJWT jwt = validateAndReturnDecodedJwtToken(tokenFromHeader);
+
+ Map claims = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+ claims.putAll(jwt.getClaims());
+
+ String userName = validateAndReturnUsername(claims);
+
+ // validate bot token
+ if (claims.containsKey(BOT_CLAIM) && claims.get(BOT_CLAIM).asBoolean()) {
+ validateBotToken(tokenFromHeader, userName);
+ }
+
+ // Setting Security Context
+ CatalogPrincipal catalogPrincipal = new CatalogPrincipal(userName);
+ String scheme = requestContext.getUriInfo().getRequestUri().getScheme();
+ CatalogSecurityContext catalogSecurityContext =
+ new CatalogSecurityContext(catalogPrincipal, scheme, SecurityContext.DIGEST_AUTH);
+ LOG.debug("SecurityContext {}", catalogSecurityContext);
+ requestContext.setSecurityContext(catalogSecurityContext);
+ }
+
+ @SneakyThrows
+ public DecodedJWT validateAndReturnDecodedJwtToken(String token) {
// Decode JWT Token
DecodedJWT jwt;
try {
- jwt = JWT.decode(tokenFromHeader);
+ jwt = JWT.decode(token);
} catch (JWTDecodeException e) {
throw new AuthenticationException("Invalid token", e);
}
@@ -127,10 +149,12 @@ public class JwtFilter implements ContainerRequestFilter {
} catch (RuntimeException runtimeException) {
throw new AuthenticationException("Invalid token");
}
+ return jwt;
+ }
+ @SneakyThrows
+ public String validateAndReturnUsername(Map claims) {
// Get username from JWT token
- Map claims = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
- claims.putAll(jwt.getClaims());
String jwtClaim =
jwtPrincipalClaims.stream()
.filter(claims::containsKey)
@@ -141,6 +165,7 @@ public class JwtFilter implements ContainerRequestFilter {
() ->
new AuthenticationException(
"Invalid JWT token, none of the following claims are present " + jwtPrincipalClaims));
+
String userName;
String domain;
if (jwtClaim.contains("@")) {
@@ -158,18 +183,7 @@ public class JwtFilter implements ContainerRequestFilter {
String.format("Not Authorized! Email does not match the principal domain %s", principalDomain));
}
}
-
- // validate bot token
- if (claims.containsKey(BOT_CLAIM) && claims.get(BOT_CLAIM).asBoolean()) {
- validateBotToken(tokenFromHeader, userName);
- }
- // Setting Security Context
- CatalogPrincipal catalogPrincipal = new CatalogPrincipal(userName);
- String scheme = requestContext.getUriInfo().getRequestUri().getScheme();
- CatalogSecurityContext catalogSecurityContext =
- new CatalogSecurityContext(catalogPrincipal, scheme, SecurityContext.DIGEST_AUTH);
- LOG.debug("SecurityContext {}", catalogSecurityContext);
- requestContext.setSecurityContext(catalogSecurityContext);
+ return userName;
}
protected static String extractToken(MultivaluedMap headers) {
@@ -185,6 +199,18 @@ public class JwtFilter implements ContainerRequestFilter {
throw new AuthenticationException("Not Authorized! Token not present");
}
+ public static String extractToken(String tokenFromHeader) {
+ LOG.debug("Request Token:{}", tokenFromHeader);
+ if (Strings.isNullOrEmpty(tokenFromHeader)) {
+ throw new AuthenticationException("Not Authorized! Token not present");
+ }
+ // Extract the bearer token
+ if (tokenFromHeader.startsWith(TOKEN_PREFIX)) {
+ return tokenFromHeader.substring(TOKEN_PREFIX.length() + 1);
+ }
+ throw new AuthenticationException("Not Authorized! Token not present");
+ }
+
private void validateBotToken(String tokenFromHeader, String userName) throws IOException {
EntityRepository userRepository = Entity.getEntityRepository(Entity.USER);
User user = userRepository.getByName(null, userName, new EntityUtil.Fields(List.of("authenticationMechanism")));
diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/FeedServlet.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/FeedServlet.java
new file mode 100644
index 00000000000..3428abbc201
--- /dev/null
+++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/FeedServlet.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 Collate
+ * 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.openmetadata.catalog.socket;
+
+import java.io.IOException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+
+@WebServlet("/api/v1/push/feed/*")
+public class FeedServlet extends HttpServlet {
+ public FeedServlet() {}
+
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ WebSocketManager.getInstance()
+ .getEngineIoServer()
+ .handleRequest(
+ new HttpServletRequestWrapper(request) {
+ @Override
+ public boolean isAsyncSupported() {
+ return true;
+ }
+ },
+ response);
+ }
+}
diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/HeaderRequestWrapper.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/HeaderRequestWrapper.java
new file mode 100644
index 00000000000..62f1e217392
--- /dev/null
+++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/HeaderRequestWrapper.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2021 Collate
+ * 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.openmetadata.catalog.socket;
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+public class HeaderRequestWrapper extends HttpServletRequestWrapper {
+
+ public HeaderRequestWrapper(HttpServletRequest request) {
+ super(request);
+ }
+
+ private Map headerMap = new HashMap<>();
+
+ public void addHeader(String name, String value) {
+ headerMap.put(name, value);
+ }
+
+ @Override
+ public String getHeader(String name) {
+ String headerValue = super.getHeader(name);
+ if (headerMap.containsKey(name)) {
+ headerValue = headerMap.get(name);
+ }
+ return headerValue;
+ }
+
+ @Override
+ public Enumeration getHeaderNames() {
+ List names = Collections.list(super.getHeaderNames());
+ names.addAll(headerMap.keySet());
+ return Collections.enumeration(names);
+ }
+
+ @Override
+ public Enumeration getHeaders(String name) {
+ List values = Collections.list(super.getHeaders(name));
+ if (headerMap.containsKey(name)) {
+ values.add(headerMap.get(name));
+ }
+ return Collections.enumeration(values);
+ }
+}
diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/SocketAddressFilter.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/SocketAddressFilter.java
new file mode 100644
index 00000000000..352d4dfe2d1
--- /dev/null
+++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/SocketAddressFilter.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2021 Collate
+ * 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.openmetadata.catalog.socket;
+
+import com.auth0.jwt.interfaces.Claim;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import java.io.IOException;
+import java.util.Map;
+import java.util.TreeMap;
+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.http.HttpServletRequest;
+import org.openmetadata.catalog.security.AuthenticationConfiguration;
+import org.openmetadata.catalog.security.AuthorizerConfiguration;
+import org.openmetadata.catalog.security.JwtFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SocketAddressFilter implements Filter {
+ private static final Logger LOG = LoggerFactory.getLogger(SocketAddressFilter.class);
+ private JwtFilter jwtFilter;
+
+ public SocketAddressFilter(
+ AuthenticationConfiguration authenticationConfiguration, AuthorizerConfiguration authorizerConf) {
+ jwtFilter = new JwtFilter(authenticationConfiguration, authorizerConf);
+ }
+
+ @Override
+ public void destroy() {}
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException {
+ HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+ String tokenWithType = httpServletRequest.getHeader("Authorization");
+
+ HeaderRequestWrapper requestWrapper = new HeaderRequestWrapper(httpServletRequest);
+ requestWrapper.addHeader("RemoteAddress", request.getRemoteAddr());
+ requestWrapper.addHeader("Authorization", tokenWithType);
+
+ String token = JwtFilter.extractToken(tokenWithType);
+ // validate token
+ DecodedJWT jwt = jwtFilter.validateAndReturnDecodedJwtToken(token);
+ // validate Domain and Username
+ Map claims = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+ claims.putAll(jwt.getClaims());
+ jwtFilter.validateAndReturnUsername(claims);
+ // Goes to default servlet.
+ chain.doFilter(requestWrapper, response);
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {}
+}
diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/WebSocketManager.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/WebSocketManager.java
new file mode 100644
index 00000000000..4dd260e6e9d
--- /dev/null
+++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/WebSocketManager.java
@@ -0,0 +1,71 @@
+package org.openmetadata.catalog.socket;
+
+import io.socket.engineio.server.EngineIoServer;
+import io.socket.engineio.server.EngineIoServerOptions;
+import io.socket.socketio.server.SocketIoNamespace;
+import io.socket.socketio.server.SocketIoServer;
+import io.socket.socketio.server.SocketIoSocket;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WebSocketManager {
+ private static final Logger LOG = LoggerFactory.getLogger(WebSocketManager.class);
+ private static WebSocketManager INSTANCE;
+ private final EngineIoServer mEngineIoServer;
+ private final SocketIoServer mSocketIoServer;
+ private final String feedBroadcastChannel = "activityFeed";
+ private final Map activityFeedEndpoints = new ConcurrentHashMap<>();
+
+ private WebSocketManager(EngineIoServerOptions eiOptions) {
+ mEngineIoServer = new EngineIoServer(eiOptions);
+ mSocketIoServer = new SocketIoServer(mEngineIoServer);
+ intilizateHandlers();
+ }
+
+ private void intilizateHandlers() {
+ SocketIoNamespace ns = mSocketIoServer.namespace("/");
+ // On Connection
+ ns.on(
+ "connection",
+ args -> {
+ SocketIoSocket socket = (SocketIoSocket) args[0];
+ LOG.info(
+ "Client :"
+ + socket.getId()
+ + "with Remote Address :"
+ + socket.getInitialHeaders().get("RemoteAddress")
+ + "connected.");
+ activityFeedEndpoints.put(socket.getId(), socket);
+ });
+ }
+
+ public static WebSocketManager getInstance() {
+ return INSTANCE;
+ }
+
+ public SocketIoServer getSocketIoServer() {
+ return mSocketIoServer;
+ }
+
+ public EngineIoServer getEngineIoServer() {
+ return mEngineIoServer;
+ }
+
+ public Map getActivityFeedEndpoints() {
+ return activityFeedEndpoints;
+ }
+
+ public void broadCastMessageToClients(String message) {
+ for (Map.Entry endpoints : activityFeedEndpoints.entrySet()) {
+ endpoints.getValue().send(feedBroadcastChannel, message);
+ }
+ }
+
+ public static class WebSocketManagerBuilder {
+ public static void build(EngineIoServerOptions eiOptions) {
+ INSTANCE = new WebSocketManager(eiOptions);
+ }
+ }
+}
diff --git a/catalog-rest-service/src/test/resources/openmetadata-secure-test.yaml b/catalog-rest-service/src/test/resources/openmetadata-secure-test.yaml
index 5038292a1d8..b6284da3633 100644
--- a/catalog-rest-service/src/test/resources/openmetadata-secure-test.yaml
+++ b/catalog-rest-service/src/test/resources/openmetadata-secure-test.yaml
@@ -129,6 +129,8 @@ authorizerConfiguration:
botPrincipals:
- "ingestion-bot"
principalDomain: "open-metadata.org"
+ enforcePrincipalDomain: false
+ enableSecureSocketConnection: false
authenticationConfiguration:
provider: "openID"
diff --git a/conf/openmetadata.yaml b/conf/openmetadata.yaml
index 906973ead23..91de4a51df3 100644
--- a/conf/openmetadata.yaml
+++ b/conf/openmetadata.yaml
@@ -133,6 +133,7 @@ authorizerConfiguration:
botPrincipals: ${AUTHORIZER_INGESTION_PRINCIPALS:-[ingestion-bot]}
principalDomain: ${AUTHORIZER_PRINCIPAL_DOMAIN:-"openmetadata.org"}
enforcePrincipalDomain: ${AUTHORIZER_ENFORCE_PRINCIPAL_DOMAIN:-false}
+ enableSecureSocketConnection : ${AUTHORIZER_ENABLE_SECURE_SOCKET:-false}
authenticationConfiguration:
provider: ${AUTHENTICATION_PROVIDER:-no-auth}
diff --git a/docker/local-metadata/docker-compose.yml b/docker/local-metadata/docker-compose.yml
index 93539736364..4527fc39422 100644
--- a/docker/local-metadata/docker-compose.yml
+++ b/docker/local-metadata/docker-compose.yml
@@ -65,6 +65,7 @@ services:
AUTHORIZER_INGESTION_PRINCIPALS: ${AUTHORIZER_INGESTION_PRINCIPALS:-[ingestion-bot]}
AUTHORIZER_PRINCIPAL_DOMAIN: ${AUTHORIZER_PRINCIPAL_DOMAIN:-""}
AUTHORIZER_ENFORCE_PRINCIPAL_DOMAIN: ${AUTHORIZER_ENFORCE_PRINCIPAL_DOMAIN:-false}
+ AUTHORIZER_ENABLE_SECURE_SOCKET: ${AUTHORIZER_ENABLE_SECURE_SOCKET:-false}
AUTHENTICATION_PROVIDER: ${AUTHENTICATION_PROVIDER:-no-auth}
CUSTOM_OIDC_AUTHENTICATION_PROVIDER_NAME: ${CUSTOM_OIDC_AUTHENTICATION_PROVIDER_NAME:-""}
AUTHENTICATION_PUBLIC_KEYS: ${AUTHENTICATION_PUBLIC_KEY:-[https://www.googleapis.com/oauth2/v3/certs]}
diff --git a/docker/metadata/docker-compose.yml b/docker/metadata/docker-compose.yml
index 4e16de01798..e4e0432cd16 100644
--- a/docker/metadata/docker-compose.yml
+++ b/docker/metadata/docker-compose.yml
@@ -54,6 +54,7 @@ services:
AUTHORIZER_INGESTION_PRINCIPALS: ${AUTHORIZER_INGESTION_PRINCIPAL:-[ingestion-bot]}
AUTHORIZER_PRINCIPAL_DOMAIN: ${AUTHORIZER_PRINCIPAL_DOMAIN:-""}
AUTHORIZER_ENFORCE_PRINCIPAL_DOMAIN: ${AUTHORIZER_ENFORCE_PRINCIPAL_DOMAIN:-false}
+ AUTHORIZER_ENABLE_SECURE_SOCKET: ${AUTHORIZER_ENABLE_SECURE_SOCKET:-false}
AUTHENTICATION_PROVIDER: ${AUTHENTICATION_PROVIDER:-no-auth}
CUSTOM_OIDC_AUTHENTICATION_PROVIDER_NAME: ${CUSTOM_OIDC_AUTHENTICATION_PROVIDER_NAME:-""}
AUTHENTICATION_PUBLIC_KEYS: ${AUTHENTICATION_PUBLIC_KEY:-[https://www.googleapis.com/oauth2/v3/certs]}