Skip to content

Commit

Permalink
refactor(restli): set threads based on cpu cores
Browse files Browse the repository at this point in the history
feat(mce-consumers): hit local restli endpoint
  • Loading branch information
david-leifker committed Dec 13, 2022
1 parent 2734fd3 commit 549453d
Show file tree
Hide file tree
Showing 31 changed files with 543 additions and 153 deletions.
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
buildscript {
ext.junitJupiterVersion = '5.6.1'
ext.pegasusVersion = '29.22.16'
// Releases: https://github.com/linkedin/rest.li/blob/master/CHANGELOG.md
ext.pegasusVersion = '29.40.14'
ext.mavenVersion = '3.6.3'
ext.springVersion = '5.3.20'
ext.springBootVersion = '2.5.12'
Expand Down
1 change: 1 addition & 0 deletions datahub-frontend/play.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ dependencies {

testImplementation externalDependency.mockito
testImplementation externalDependency.playTest
testImplementation 'org.awaitility:awaitility:4.2.0'
testImplementation 'no.nav.security:mock-oauth2-server:0.3.1'
testImplementation 'org.junit-pioneer:junit-pioneer:1.9.1'
testImplementation externalDependency.junitJupiterApi
Expand Down
5 changes: 4 additions & 1 deletion datahub-frontend/test/app/ApplicationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import no.nav.security.mock.oauth2.token.DefaultOAuth2TokenCallback;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.awaitility.Awaitility;
import org.awaitility.Durations;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -93,7 +95,8 @@ public void init() throws IOException, InterruptedException {

startServer();
createBrowser();
Thread.sleep(5000);

Awaitility.await().timeout(Durations.TEN_SECONDS).until(() -> app != null);
}

@AfterAll
Expand Down
3 changes: 2 additions & 1 deletion docker/datahub-mce-consumer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ RUN apk --no-cache --update-cache --available upgrade \
&& apk --no-cache add openjdk8 openjdk11 perl

COPY . datahub-src
RUN cd datahub-src && ./gradlew :metadata-jobs:mce-consumer-job:build
RUN cd datahub-src && ./gradlew :metadata-jobs:mce-consumer-job:build --stacktrace
RUN cd datahub-src && cp metadata-jobs/mce-consumer-job/build/libs/mce-consumer-job.jar ../mce-consumer-job.jar

FROM base as prod-install
COPY --from=prod-build /mce-consumer-job.jar /datahub/datahub-mce-consumer/bin/
COPY --from=prod-build /datahub-src/metadata-models/src/main/resources/entity-registry.yml /datahub/datahub-mce-consumer/resources/entity-registry.yml
COPY --from=prod-build /datahub-src/docker/datahub-mce-consumer/start.sh /datahub/datahub-mce-consumer/scripts/
COPY --from=prod-build /datahub-src/docker/monitoring/client-prometheus-config.yaml /datahub/datahub-mce-consumer/scripts/prometheus-config.yaml
RUN chmod +x /datahub/datahub-mce-consumer/scripts/start.sh
Expand Down
34 changes: 27 additions & 7 deletions docker/datahub-mce-consumer/env/docker.env
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
MCE_CONSUMER_ENABLED=true
EBEAN_DATASOURCE_USERNAME=datahub
EBEAN_DATASOURCE_PASSWORD=datahub
EBEAN_DATASOURCE_HOST=mysql:3306
EBEAN_DATASOURCE_URL=jdbc:mysql://mysql:3306/datahub?verifyServerCertificate=false&useSSL=true&useUnicode=yes&characterEncoding=UTF-8
EBEAN_DATASOURCE_DRIVER=com.mysql.jdbc.Driver
KAFKA_BOOTSTRAP_SERVER=broker:29092
KAFKA_SCHEMAREGISTRY_URL=http://schema-registry:8081
DATAHUB_GMS_HOST=datahub-gms
DATAHUB_GMS_PORT=8080
ELASTICSEARCH_HOST=elasticsearch
ELASTICSEARCH_PORT=9200
ES_BULK_REFRESH_POLICY=WAIT_UNTIL
GRAPH_SERVICE_DIFF_MODE_ENABLED=true
GRAPH_SERVICE_IMPL=elasticsearch
JAVA_OPTS=-Xms1g -Xmx1g
ENTITY_REGISTRY_CONFIG_PATH=/datahub/datahub-mce-consumer/resources/entity-registry.yml

# Uncomment to configure kafka topic names
# Make sure these names are consistent across the whole deployment
Expand All @@ -12,8 +22,18 @@ DATAHUB_GMS_PORT=8080
# METADATA_CHANGE_EVENT_NAME=MetadataChangeEvent_v4
# FAILED_METADATA_CHANGE_EVENT_NAME=FailedMetadataChangeEvent_v4

# Uncomment and set these to support SSL connection to GMS
# NOTE: Currently GMS itself does not offer SSL support, these settings are intended for when there is a proxy in front
# of GMS that handles SSL, such as an EC2 Load Balancer.
#GMS_USE_SSL=true
#GMS_SSL_PROTOCOL=
# Uncomment and set these to support SSL connection to Elasticsearch
# ELASTICSEARCH_USE_SSL=true
# ELASTICSEARCH_SSL_PROTOCOL=TLSv1.2
# ELASTICSEARCH_SSL_SECURE_RANDOM_IMPL=
# ELASTICSEARCH_SSL_TRUSTSTORE_FILE=
# ELASTICSEARCH_SSL_TRUSTSTORE_TYPE=
# ELASTICSEARCH_SSL_TRUSTSTORE_PASSWORD=
# ELASTICSEARCH_SSL_KEYSTORE_FILE=
# ELASTICSEARCH_SSL_KEYSTORE_TYPE=
# ELASTICSEARCH_SSL_KEYSTORE_PASSWORD=

# To use simple username/password authentication to Elasticsearch over HTTPS
# set ELASTICSEARCH_USE_SSL=true and uncomment:
# ELASTICSEARCH_USERNAME=
# ELASTICSEARCH_PASSWORD=
3 changes: 2 additions & 1 deletion docker/docker-compose.consumers-without-neo4j.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ services:
- "9090:9090"
depends_on:
- kafka-setup
- datahub-gms
- elasticsearch-setup
- mysql-setup
3 changes: 2 additions & 1 deletion docker/docker-compose.consumers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ services:
- "9090:9090"
depends_on:
- kafka-setup
- datahub-gms
- elasticsearch-setup
- mysql-setup
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,30 @@ services:
container_name: datahub-mce-consumer
depends_on:
- kafka-setup
- datahub-gms
- elasticsearch-setup
- mysql-setup
environment:
- MCE_CONSUMER_ENABLED=true
- KAFKA_BOOTSTRAP_SERVER=broker:29092
- KAFKA_SCHEMAREGISTRY_URL=http://schema-registry:8081
- DATAHUB_GMS_HOST=datahub-gms
- DATAHUB_GMS_PORT=8080
- DATAHUB_SERVER_TYPE=${DATAHUB_SERVER_TYPE:-quickstart}
- DATAHUB_TELEMETRY_ENABLED=${DATAHUB_TELEMETRY_ENABLED:-true}
- EBEAN_DATASOURCE_USERNAME=datahub
- EBEAN_DATASOURCE_PASSWORD=datahub
- EBEAN_DATASOURCE_HOST=mysql:3306
- EBEAN_DATASOURCE_URL=jdbc:mysql://mysql:3306/datahub?verifyServerCertificate=false&useSSL=true&useUnicode=yes&characterEncoding=UTF-8
- EBEAN_DATASOURCE_DRIVER=com.mysql.jdbc.Driver
- ELASTICSEARCH_HOST=elasticsearch
- ELASTICSEARCH_PORT=9200
- ES_BULK_REFRESH_POLICY=WAIT_UNTIL
- GRAPH_SERVICE_DIFF_MODE_ENABLED=true
- GRAPH_SERVICE_IMPL=elasticsearch
- JAVA_OPTS=-Xms1g -Xmx1g
- ENTITY_REGISTRY_CONFIG_PATH=/datahub/datahub-mce-consumer/resources/entity-registry.yml
- ENTITY_SERVICE_ENABLE_RETENTION=true
- MAE_CONSUMER_ENABLED=false
- PE_CONSUMER_ENABLED=false
- UI_INGESTION_ENABLED=false
hostname: datahub-mce-consumer
image: ${DATAHUB_MCE_CONSUMER_IMAGE:-linkedin/datahub-mce-consumer}:${DATAHUB_VERSION:-head}
ports:
Expand Down
27 changes: 24 additions & 3 deletions docker/quickstart/docker-compose.consumers.quickstart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,34 @@ services:
container_name: datahub-mce-consumer
depends_on:
- kafka-setup
- datahub-gms
- elasticsearch-setup
- mysql-setup
environment:
- MCE_CONSUMER_ENABLED=true
- KAFKA_BOOTSTRAP_SERVER=broker:29092
- KAFKA_SCHEMAREGISTRY_URL=http://schema-registry:8081
- DATAHUB_GMS_HOST=datahub-gms
- DATAHUB_GMS_PORT=8080
- DATAHUB_SERVER_TYPE=${DATAHUB_SERVER_TYPE:-quickstart}
- DATAHUB_TELEMETRY_ENABLED=${DATAHUB_TELEMETRY_ENABLED:-true}
- EBEAN_DATASOURCE_USERNAME=datahub
- EBEAN_DATASOURCE_PASSWORD=datahub
- EBEAN_DATASOURCE_HOST=mysql:3306
- EBEAN_DATASOURCE_URL=jdbc:mysql://mysql:3306/datahub?verifyServerCertificate=false&useSSL=true&useUnicode=yes&characterEncoding=UTF-8&enabledTLSProtocols=TLSv1.2
- EBEAN_DATASOURCE_DRIVER=com.mysql.jdbc.Driver
- ELASTICSEARCH_HOST=elasticsearch
- ELASTICSEARCH_PORT=9200
- ES_BULK_REFRESH_POLICY=WAIT_UNTIL
- NEO4J_HOST=http://neo4j:7474
- NEO4J_URI=bolt://neo4j
- NEO4J_USERNAME=neo4j
- NEO4J_PASSWORD=datahub
- JAVA_OPTS=-Xms1g -Xmx1g
- GRAPH_SERVICE_DIFF_MODE_ENABLED=true
- GRAPH_SERVICE_IMPL=neo4j
- ENTITY_REGISTRY_CONFIG_PATH=/datahub/datahub-mce-consumer/resources/entity-registry.yml
- ENTITY_SERVICE_ENABLE_RETENTION=true
- MAE_CONSUMER_ENABLED=false
- PE_CONSUMER_ENABLED=false
- UI_INGESTION_ENABLED=false
hostname: datahub-mce-consumer
image: ${DATAHUB_MCE_CONSUMER_IMAGE:-linkedin/datahub-mce-consumer}:${DATAHUB_VERSION:-head}
ports:
Expand Down
4 changes: 4 additions & 0 deletions metadata-auth/auth-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ test {
useJUnit()
}

jar {
archiveName = "$project.name-lib.jar"
}

shadowJar {
zip64 true
classifier = null
Expand Down
28 changes: 24 additions & 4 deletions metadata-jobs/mce-consumer-job/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,34 @@ plugins {
}

dependencies {
compile project(':metadata-jobs:mce-consumer')
compile(externalDependency.springBootStarterWeb) {
implementation project(':metadata-service:factories')
implementation project(':metadata-jobs:mce-consumer')
implementation project(':entity-registry')

implementation(externalDependency.springBootStarterWeb) {
exclude module: "spring-boot-starter-tomcat"
}
compile externalDependency.springBootStarterJetty
compile externalDependency.springKafka
implementation externalDependency.springBootStarterJetty
implementation externalDependency.springKafka
implementation spec.product.pegasus.restliDocgen
implementation spec.product.pegasus.restliSpringBridge
implementation externalDependency.slf4jApi
implementation externalDependency.log4j2Api
compileOnly externalDependency.lombok
implementation externalDependency.logbackClassic

runtime externalDependency.mariadbConnector
runtime externalDependency.mysqlConnector
runtime externalDependency.postgresql

annotationProcessor externalDependency.lombok

testImplementation externalDependency.springBootTest
testCompile externalDependency.mockito
testCompile externalDependency.testng
}

bootJar {
mainClassName = 'com.linkedin.metadata.kafka.MceConsumerApplication'
requiresUnpack '**/restli-servlet-impl.jar'
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.linkedin.metadata.kafka;

import com.linkedin.gms.factory.entity.RestliEntityClientFactory;
import com.linkedin.gms.factory.spring.YamlPropertySourceFactory;
import com.linkedin.gms.factory.telemetry.ScheduledAnalyticsFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.solr.SolrHealthContributorAutoConfiguration;
Expand All @@ -8,13 +10,32 @@
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.PropertySource;


@SuppressWarnings("checkstyle:HideUtilityClassConstructor")
@SpringBootApplication(exclude = {ElasticsearchRestClientAutoConfiguration.class, CassandraAutoConfiguration.class,
SolrHealthContributorAutoConfiguration.class})
@ComponentScan(excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ScheduledAnalyticsFactory.class)})
@SpringBootApplication(exclude = {
ElasticsearchRestClientAutoConfiguration.class,
CassandraAutoConfiguration.class,
SolrHealthContributorAutoConfiguration.class
})
@ComponentScan(basePackages = {
"com.linkedin.gms.factory.common",
"com.linkedin.gms.factory.config",
"com.linkedin.gms.factory.entity",
"com.linkedin.gms.factory.entityregistry",
"com.linkedin.gms.factory.kafka",
"com.linkedin.gms.factory.search",
"com.linkedin.gms.factory.timeseries",
"com.linkedin.restli.server",
"com.linkedin.metadata.restli"
}, excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {
ScheduledAnalyticsFactory.class,
RestliEntityClientFactory.class
})
})
@PropertySource(value = "classpath:/application.yml", factory = YamlPropertySourceFactory.class)
public class MceConsumerApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.linkedin.metadata.restli;

import io.ebean.datasource.DataSourceConfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.util.HashMap;
import java.util.Map;

import static com.linkedin.gms.factory.common.LocalEbeanServerConfigFactory.getListenerToTrackCounts;

@Configuration
public class EbeanServerConfig {
@Value("${ebean.username}")
private String ebeanDatasourceUsername;

@Value("${ebean.password}")
private String ebeanDatasourcePassword;

@Value("${ebean.driver}")
private String ebeanDatasourceDriver;

@Value("${ebean.minConnections:1}")
private Integer ebeanMinConnections;

@Value("${ebean.maxInactiveTimeSeconds:120}")
private Integer ebeanMaxInactiveTimeSecs;

@Value("${ebean.maxAgeMinutes:120}")
private Integer ebeanMaxAgeMinutes;

@Value("${ebean.leakTimeMinutes:15}")
private Integer ebeanLeakTimeMinutes;

@Value("${ebean.waitTimeoutMillis:1000}")
private Integer ebeanWaitTimeoutMillis;

@Value("${ebean.autoCreateDdl:false}")
private Boolean ebeanAutoCreate;

@Value("${ebean.postgresUseIamAuth:false}")
private Boolean postgresUseIamAuth;


@Bean("ebeanDataSourceConfig")
@Primary
public DataSourceConfig buildDataSourceConfig(
@Value("${ebean.url}") String dataSourceUrl,
@Qualifier("parseqEngineThreads") int ebeanMaxConnections
) {
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setUsername(ebeanDatasourceUsername);
dataSourceConfig.setPassword(ebeanDatasourcePassword);
dataSourceConfig.setUrl(dataSourceUrl);
dataSourceConfig.setDriver(ebeanDatasourceDriver);
dataSourceConfig.setMinConnections(ebeanMinConnections);
dataSourceConfig.setMaxConnections(ebeanMaxConnections);
dataSourceConfig.setMaxInactiveTimeSecs(ebeanMaxInactiveTimeSecs);
dataSourceConfig.setMaxAgeMinutes(ebeanMaxAgeMinutes);
dataSourceConfig.setLeakTimeMinutes(ebeanLeakTimeMinutes);
dataSourceConfig.setWaitTimeoutMillis(ebeanWaitTimeoutMillis);
dataSourceConfig.setListener(getListenerToTrackCounts("mce-consumer"));
// Adding IAM auth access for AWS Postgres
if (postgresUseIamAuth) {
Map<String, String> custom = new HashMap<>();
custom.put("wrapperPlugins", "iam");
dataSourceConfig.setCustomProperties(custom);
}
return dataSourceConfig;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.linkedin.metadata.restli;

import com.linkedin.entity.client.RestliEntityClient;
import com.linkedin.restli.client.Client;
import com.linkedin.restli.server.RestliHandlerServlet;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.net.URI;

@Configuration
public class RestliServletConfig {
@Value("${server.port}")
private int configuredPort;

@Bean("restliEntityClient")
@Primary
public RestliEntityClient restliEntityClient() {
String selfUri = String.format("http://localhost:%s/gms/", configuredPort);
final Client restClient = DefaultRestliClientFactory.getRestLiClient(URI.create(selfUri), null);
return new RestliEntityClient(restClient);
}

@Bean
public ServletRegistrationBean<RestliHandlerServlet> servletRegistrationBean(
@Qualifier("restliHandlerServlet") RestliHandlerServlet servlet) {
return new ServletRegistrationBean<>(servlet, "/gms/*");
}

@Bean
public RestliHandlerServlet restliHandlerServlet() {
return new RestliHandlerServlet();
}
}
Loading

0 comments on commit 549453d

Please sign in to comment.