mirror of
https://github.com/datahub-project/datahub.git
synced 2025-11-15 19:03:43 +00:00
feat(gms): Merge MAE, MCE consumers into GMS (#2690)
This commit is contained in:
parent
7591c8994a
commit
cc95916201
@ -20,11 +20,11 @@ dependencies:
|
|||||||
- name: datahub-mae-consumer
|
- name: datahub-mae-consumer
|
||||||
version: 0.2.1
|
version: 0.2.1
|
||||||
repository: file://./charts/datahub-mae-consumer
|
repository: file://./charts/datahub-mae-consumer
|
||||||
condition: datahub-mae-consumer.enabled
|
condition: global.datahub_standalone_consumers_enabled
|
||||||
- name: datahub-mce-consumer
|
- name: datahub-mce-consumer
|
||||||
version: 0.2.1
|
version: 0.2.1
|
||||||
repository: file://./charts/datahub-mce-consumer
|
repository: file://./charts/datahub-mce-consumer
|
||||||
condition: datahub-mce-consumer.enabled
|
condition: global.datahub_standalone_consumers_enabled
|
||||||
- name: datahub-ingestion-cron
|
- name: datahub-ingestion-cron
|
||||||
version: 0.2.1
|
version: 0.2.1
|
||||||
repository: file://./charts/datahub-ingestion-cron
|
repository: file://./charts/datahub-ingestion-cron
|
||||||
|
|||||||
@ -73,6 +73,14 @@ spec:
|
|||||||
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
|
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
|
||||||
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
|
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
|
||||||
env:
|
env:
|
||||||
|
{{- if not .Values.global.datahub_standalone_consumers_enabled }}
|
||||||
|
- name: MCE_CONSUMER_ENABLED
|
||||||
|
value: "true"
|
||||||
|
- name: MAE_CONSUMER_ENABLED
|
||||||
|
value: "true"
|
||||||
|
{{- end }}
|
||||||
|
- name: DATAHUB_ANALYTICS_ENABLED
|
||||||
|
value: "{{ .Values.global.datahub_analytics_enabled }}"
|
||||||
- name: EBEAN_DATASOURCE_USERNAME
|
- name: EBEAN_DATASOURCE_USERNAME
|
||||||
value: "{{ .Values.global.sql.datasource.username }}"
|
value: "{{ .Values.global.sql.datasource.username }}"
|
||||||
- name: EBEAN_DATASOURCE_PASSWORD
|
- name: EBEAN_DATASOURCE_PASSWORD
|
||||||
|
|||||||
@ -146,6 +146,8 @@ readinessProbe:
|
|||||||
#This section is useful if we are installing this chart separately for testing
|
#This section is useful if we are installing this chart separately for testing
|
||||||
# helm install datahub-gms datahub-gms/
|
# helm install datahub-gms datahub-gms/
|
||||||
global:
|
global:
|
||||||
|
datahub_analytics_enabled: true
|
||||||
|
|
||||||
elasticsearch:
|
elasticsearch:
|
||||||
host: "elasticsearch"
|
host: "elasticsearch"
|
||||||
port: "9200"
|
port: "9200"
|
||||||
|
|||||||
@ -73,6 +73,8 @@ spec:
|
|||||||
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
|
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
|
||||||
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
|
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
|
||||||
env:
|
env:
|
||||||
|
- name: MAE_CONSUMER_ENABLED
|
||||||
|
value: "true"
|
||||||
- name: GMS_HOST
|
- name: GMS_HOST
|
||||||
value: {{ printf "%s-%s" .Release.Name "datahub-gms" }}
|
value: {{ printf "%s-%s" .Release.Name "datahub-gms" }}
|
||||||
- name: GMS_PORT
|
- name: GMS_PORT
|
||||||
|
|||||||
@ -69,6 +69,8 @@ spec:
|
|||||||
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
|
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
|
||||||
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
|
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
|
||||||
env:
|
env:
|
||||||
|
- name: MCE_CONSUMER_ENABLED
|
||||||
|
value: "true"
|
||||||
- name: KAFKA_BOOTSTRAP_SERVER
|
- name: KAFKA_BOOTSTRAP_SERVER
|
||||||
value: "{{ .Values.global.kafka.bootstrap.server }}"
|
value: "{{ .Values.global.kafka.bootstrap.server }}"
|
||||||
- name: KAFKA_SCHEMAREGISTRY_URL
|
- name: KAFKA_SCHEMAREGISTRY_URL
|
||||||
|
|||||||
@ -15,18 +15,6 @@ datahub-frontend:
|
|||||||
ingress:
|
ingress:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
datahub-mae-consumer:
|
|
||||||
enabled: true
|
|
||||||
image:
|
|
||||||
repository: linkedin/datahub-mae-consumer
|
|
||||||
tag: "v0.8.1"
|
|
||||||
|
|
||||||
datahub-mce-consumer:
|
|
||||||
enabled: true
|
|
||||||
image:
|
|
||||||
repository: linkedin/datahub-mce-consumer
|
|
||||||
tag: "v0.8.1"
|
|
||||||
|
|
||||||
elasticsearchSetupJob:
|
elasticsearchSetupJob:
|
||||||
enabled: true
|
enabled: true
|
||||||
image:
|
image:
|
||||||
|
|||||||
@ -58,7 +58,9 @@ datahubUpgrade:
|
|||||||
tag: "v0.8.1"
|
tag: "v0.8.1"
|
||||||
|
|
||||||
global:
|
global:
|
||||||
|
|
||||||
datahub_analytics_enabled: true
|
datahub_analytics_enabled: true
|
||||||
|
datahub_standalone_consumers_enabled: false
|
||||||
|
|
||||||
elasticsearch:
|
elasticsearch:
|
||||||
host: "elasticsearch-master"
|
host: "elasticsearch-master"
|
||||||
|
|||||||
@ -1,87 +0,0 @@
|
|||||||
package com.linkedin.datahub.upgrade.nocode;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.linkedin.datahub.upgrade.UpgradeContext;
|
|
||||||
import com.linkedin.datahub.upgrade.UpgradeStep;
|
|
||||||
import com.linkedin.datahub.upgrade.UpgradeStepResult;
|
|
||||||
import com.linkedin.datahub.upgrade.impl.DefaultUpgradeStepResult;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
|
|
||||||
public class MAEQualificationStep implements UpgradeStep {
|
|
||||||
|
|
||||||
private static String convertStreamToString(InputStream is) {
|
|
||||||
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
|
|
||||||
String line = null;
|
|
||||||
try {
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
sb.append(line + "\n");
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
is.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
MAEQualificationStep() { }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String id() {
|
|
||||||
return "MAEQualificationStep";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int retryCount() {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Function<UpgradeContext, UpgradeStepResult> executable() {
|
|
||||||
return (context) -> {
|
|
||||||
String maeHost = System.getenv("DATAHUB_MAE_CONSUMER_HOST") == null ? "localhost" : System.getenv("DATAHUB_MAE_CONSUMER_HOST");
|
|
||||||
String maePort = System.getenv("DATAHUB_MAE_CONSUMER_PORT") == null ? "9091" : System.getenv("DATAHUB_MAE_CONSUMER_PORT");
|
|
||||||
try {
|
|
||||||
String spec = String.format("http://%s:%s/config", maeHost, maePort);
|
|
||||||
|
|
||||||
URLConnection gmsConnection = new URL(spec).openConnection();
|
|
||||||
InputStream response = gmsConnection.getInputStream();
|
|
||||||
String responseString = convertStreamToString(response);
|
|
||||||
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
|
||||||
JsonNode configJson = mapper.readTree(responseString);
|
|
||||||
if (configJson.get("noCode").asBoolean()) {
|
|
||||||
context.report().addLine("MAE Consumer is running and up to date. Proceeding with upgrade...");
|
|
||||||
return new DefaultUpgradeStepResult(id(), UpgradeStepResult.Result.SUCCEEDED);
|
|
||||||
} else {
|
|
||||||
context.report().addLine(String.format("Failed to qualify MAE Consumer. It is not running on the latest version."
|
|
||||||
+ "Re-run MAE Consumer on the latest datahub release"));
|
|
||||||
return new DefaultUpgradeStepResult(id(), UpgradeStepResult.Result.FAILED);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
context.report().addLine(String.format(
|
|
||||||
"ERROR: Cannot connect to MAE Consumer"
|
|
||||||
+ "at host %s port %s. Make sure MAE Consumer is on the latest version "
|
|
||||||
+ "and is running at that host before starting the migration.",
|
|
||||||
maeHost, maePort));
|
|
||||||
return new DefaultUpgradeStepResult(id(), UpgradeStepResult.Result.FAILED);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -58,7 +58,6 @@ public class NoCodeUpgrade implements Upgrade {
|
|||||||
final List<UpgradeStep> steps = new ArrayList<>();
|
final List<UpgradeStep> steps = new ArrayList<>();
|
||||||
steps.add(new RemoveAspectV2TableStep(server));
|
steps.add(new RemoveAspectV2TableStep(server));
|
||||||
steps.add(new GMSQualificationStep());
|
steps.add(new GMSQualificationStep());
|
||||||
steps.add(new MAEQualificationStep());
|
|
||||||
steps.add(new UpgradeQualificationStep(server));
|
steps.add(new UpgradeQualificationStep(server));
|
||||||
steps.add(new CreateAspectTableStep(server));
|
steps.add(new CreateAspectTableStep(server));
|
||||||
steps.add(new IngestDataPlatformsStep(entityService));
|
steps.add(new IngestDataPlatformsStep(entityService));
|
||||||
|
|||||||
6
docker/datahub-gms/env/docker.env
vendored
6
docker/datahub-gms/env/docker.env
vendored
@ -13,6 +13,12 @@ NEO4J_URI=bolt://neo4j
|
|||||||
NEO4J_USERNAME=neo4j
|
NEO4J_USERNAME=neo4j
|
||||||
NEO4J_PASSWORD=datahub
|
NEO4J_PASSWORD=datahub
|
||||||
|
|
||||||
|
MAE_CONSUMER_ENABLED=true
|
||||||
|
MCE_CONSUMER_ENABLED=true
|
||||||
|
|
||||||
|
# Uncomment to disable persistence of client-side analytics events
|
||||||
|
# DATAHUB_ANALYTICS_ENABLED=false
|
||||||
|
|
||||||
# Uncomment to configure kafka topic names
|
# Uncomment to configure kafka topic names
|
||||||
# Make sure these names are consistent across the whole deployment
|
# Make sure these names are consistent across the whole deployment
|
||||||
# METADATA_AUDIT_EVENT_NAME=MetadataAuditEvent_v4
|
# METADATA_AUDIT_EVENT_NAME=MetadataAuditEvent_v4
|
||||||
|
|||||||
2
docker/datahub-gms/env/docker.mariadb.env
vendored
2
docker/datahub-gms/env/docker.mariadb.env
vendored
@ -11,3 +11,5 @@ NEO4J_HOST=http://neo4j:7474
|
|||||||
NEO4J_URI=bolt://neo4j
|
NEO4J_URI=bolt://neo4j
|
||||||
NEO4J_USERNAME=neo4j
|
NEO4J_USERNAME=neo4j
|
||||||
NEO4J_PASSWORD=datahub
|
NEO4J_PASSWORD=datahub
|
||||||
|
MAE_CONSUMER_ENABLED=true
|
||||||
|
MCE_CONSUMER_ENABLED=true
|
||||||
|
|||||||
3
docker/datahub-gms/env/docker.postgres.env
vendored
3
docker/datahub-gms/env/docker.postgres.env
vendored
@ -11,3 +11,6 @@ NEO4J_HOST=http://neo4j:7474
|
|||||||
NEO4J_URI=bolt://neo4j
|
NEO4J_URI=bolt://neo4j
|
||||||
NEO4J_USERNAME=neo4j
|
NEO4J_USERNAME=neo4j
|
||||||
NEO4J_PASSWORD=datahub
|
NEO4J_PASSWORD=datahub
|
||||||
|
MAE_CONSUMER_ENABLED=true
|
||||||
|
MCE_CONSUMER_ENABLED=true
|
||||||
|
|
||||||
|
|||||||
1
docker/datahub-mae-consumer/env/docker.env
vendored
1
docker/datahub-mae-consumer/env/docker.env
vendored
@ -1,3 +1,4 @@
|
|||||||
|
MAE_CONSUMER_ENABLED=true
|
||||||
KAFKA_BOOTSTRAP_SERVER=broker:29092
|
KAFKA_BOOTSTRAP_SERVER=broker:29092
|
||||||
KAFKA_SCHEMAREGISTRY_URL=http://schema-registry:8081
|
KAFKA_SCHEMAREGISTRY_URL=http://schema-registry:8081
|
||||||
ELASTICSEARCH_HOST=elasticsearch
|
ELASTICSEARCH_HOST=elasticsearch
|
||||||
|
|||||||
1
docker/datahub-mce-consumer/env/docker.env
vendored
1
docker/datahub-mce-consumer/env/docker.env
vendored
@ -1,3 +1,4 @@
|
|||||||
|
MCE_CONSUMER_ENABLED=true
|
||||||
KAFKA_BOOTSTRAP_SERVER=broker:29092
|
KAFKA_BOOTSTRAP_SERVER=broker:29092
|
||||||
KAFKA_SCHEMAREGISTRY_URL=http://schema-registry:8081
|
KAFKA_SCHEMAREGISTRY_URL=http://schema-registry:8081
|
||||||
GMS_HOST=datahub-gms
|
GMS_HOST=datahub-gms
|
||||||
|
|||||||
23
docker/docker-compose.consumers.dev.yml
Normal file
23
docker/docker-compose.consumers.dev.yml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
datahub-mae-consumer:
|
||||||
|
image: linkedin/datahub-mae-consumer:debug
|
||||||
|
build:
|
||||||
|
context: datahub-mae-consumer
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
args:
|
||||||
|
APP_ENV: dev
|
||||||
|
volumes:
|
||||||
|
- ./datahub-mae-consumer/start.sh:/datahub/datahub-mae-consumer/scripts/start.sh
|
||||||
|
- ../metadata-jobs/mae-consumer-job/build/libs/:/datahub/datahub-mae-consumer/bin/
|
||||||
|
|
||||||
|
datahub-mce-consumer:
|
||||||
|
image: linkedin/datahub-mce-consumer:debug
|
||||||
|
build:
|
||||||
|
context: datahub-mce-consumer
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
args:
|
||||||
|
APP_ENV: dev
|
||||||
|
volumes:
|
||||||
|
- ./datahub-mce-consumer/start.sh:/datahub/datahub-mce-consumer/scripts/start.sh
|
||||||
|
- ../metadata-jobs/mce-consumer-job/build/libs/:/datahub/datahub-mce-consumer/bin
|
||||||
31
docker/docker-compose.consumers.yml
Normal file
31
docker/docker-compose.consumers.yml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Service definitions for standalone Kafka consumer containers.
|
||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
datahub-mae-consumer:
|
||||||
|
build:
|
||||||
|
context: ../
|
||||||
|
dockerfile: docker/datahub-mae-consumer/Dockerfile
|
||||||
|
image: linkedin/datahub-mae-consumer:${DATAHUB_VERSION:-latest}
|
||||||
|
env_file: datahub-mae-consumer/env/docker.env
|
||||||
|
hostname: datahub-mae-consumer
|
||||||
|
container_name: datahub-mae-consumer
|
||||||
|
ports:
|
||||||
|
- "9091:9091"
|
||||||
|
depends_on:
|
||||||
|
- kafka-setup
|
||||||
|
- elasticsearch-setup
|
||||||
|
- neo4j
|
||||||
|
|
||||||
|
datahub-mce-consumer:
|
||||||
|
build:
|
||||||
|
context: ../
|
||||||
|
dockerfile: docker/datahub-mce-consumer/Dockerfile
|
||||||
|
image: linkedin/datahub-mce-consumer:${DATAHUB_VERSION:-latest}
|
||||||
|
env_file: datahub-mce-consumer/env/docker.env
|
||||||
|
hostname: datahub-mce-consumer
|
||||||
|
container_name: datahub-mce-consumer
|
||||||
|
ports:
|
||||||
|
- "9090:9090"
|
||||||
|
depends_on:
|
||||||
|
- kafka-setup
|
||||||
|
- datahub-gms
|
||||||
@ -50,25 +50,3 @@ services:
|
|||||||
APP_ENV: dev
|
APP_ENV: dev
|
||||||
volumes:
|
volumes:
|
||||||
- ../datahub-frontend/build/stage/datahub-frontend:/datahub-frontend
|
- ../datahub-frontend/build/stage/datahub-frontend:/datahub-frontend
|
||||||
|
|
||||||
datahub-mae-consumer:
|
|
||||||
image: linkedin/datahub-mae-consumer:debug
|
|
||||||
build:
|
|
||||||
context: datahub-mae-consumer
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
args:
|
|
||||||
APP_ENV: dev
|
|
||||||
volumes:
|
|
||||||
- ./datahub-mae-consumer/start.sh:/datahub/datahub-mae-consumer/scripts/start.sh
|
|
||||||
- ../metadata-jobs/mae-consumer-job/build/libs/:/datahub/datahub-mae-consumer/bin/
|
|
||||||
|
|
||||||
datahub-mce-consumer:
|
|
||||||
image: linkedin/datahub-mce-consumer:debug
|
|
||||||
build:
|
|
||||||
context: datahub-mce-consumer
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
args:
|
|
||||||
APP_ENV: dev
|
|
||||||
volumes:
|
|
||||||
- ./datahub-mce-consumer/start.sh:/datahub/datahub-mce-consumer/scripts/start.sh
|
|
||||||
- ../metadata-jobs/mce-consumer-job/build/libs/:/datahub/datahub-mce-consumer/bin
|
|
||||||
|
|||||||
@ -160,35 +160,6 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- datahub-gms
|
- datahub-gms
|
||||||
|
|
||||||
datahub-mae-consumer:
|
|
||||||
build:
|
|
||||||
context: ../
|
|
||||||
dockerfile: docker/datahub-mae-consumer/Dockerfile
|
|
||||||
image: linkedin/datahub-mae-consumer:${DATAHUB_VERSION:-latest}
|
|
||||||
env_file: datahub-mae-consumer/env/docker.env
|
|
||||||
hostname: datahub-mae-consumer
|
|
||||||
container_name: datahub-mae-consumer
|
|
||||||
ports:
|
|
||||||
- "9091:9091"
|
|
||||||
depends_on:
|
|
||||||
- kafka-setup
|
|
||||||
- elasticsearch-setup
|
|
||||||
- neo4j
|
|
||||||
|
|
||||||
datahub-mce-consumer:
|
|
||||||
build:
|
|
||||||
context: ../
|
|
||||||
dockerfile: docker/datahub-mce-consumer/Dockerfile
|
|
||||||
image: linkedin/datahub-mce-consumer:${DATAHUB_VERSION:-latest}
|
|
||||||
env_file: datahub-mce-consumer/env/docker.env
|
|
||||||
hostname: datahub-mce-consumer
|
|
||||||
container_name: datahub-mce-consumer
|
|
||||||
ports:
|
|
||||||
- "9090:9090"
|
|
||||||
depends_on:
|
|
||||||
- kafka-setup
|
|
||||||
- datahub-gms
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
default:
|
default:
|
||||||
name: datahub_network
|
name: datahub_network
|
||||||
|
|||||||
@ -55,48 +55,13 @@ services:
|
|||||||
- NEO4J_URI=bolt://neo4j
|
- NEO4J_URI=bolt://neo4j
|
||||||
- NEO4J_USERNAME=neo4j
|
- NEO4J_USERNAME=neo4j
|
||||||
- NEO4J_PASSWORD=datahub
|
- NEO4J_PASSWORD=datahub
|
||||||
|
- MAE_CONSUMER_ENABLED=true
|
||||||
|
- MCE_CONSUMER_ENABLED=true
|
||||||
hostname: datahub-gms
|
hostname: datahub-gms
|
||||||
image: linkedin/datahub-gms:${DATAHUB_VERSION:-latest}
|
image: linkedin/datahub-gms:${DATAHUB_VERSION:-latest}
|
||||||
mem_limit: 850m
|
mem_limit: 850m
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 8080:8080
|
||||||
datahub-mae-consumer:
|
|
||||||
container_name: datahub-mae-consumer
|
|
||||||
depends_on:
|
|
||||||
- kafka-setup
|
|
||||||
- elasticsearch-setup
|
|
||||||
- neo4j
|
|
||||||
environment:
|
|
||||||
- KAFKA_BOOTSTRAP_SERVER=broker:29092
|
|
||||||
- KAFKA_SCHEMAREGISTRY_URL=http://schema-registry:8081
|
|
||||||
- ELASTICSEARCH_HOST=elasticsearch
|
|
||||||
- ELASTICSEARCH_PORT=9200
|
|
||||||
- NEO4J_HOST=http://neo4j:7474
|
|
||||||
- NEO4J_URI=bolt://neo4j
|
|
||||||
- NEO4J_USERNAME=neo4j
|
|
||||||
- NEO4J_PASSWORD=datahub
|
|
||||||
- GMS_HOST=datahub-gms
|
|
||||||
- GMS_PORT=8080
|
|
||||||
hostname: datahub-mae-consumer
|
|
||||||
image: linkedin/datahub-mae-consumer:${DATAHUB_VERSION:-latest}
|
|
||||||
mem_limit: 256m
|
|
||||||
ports:
|
|
||||||
- 9091:9091
|
|
||||||
datahub-mce-consumer:
|
|
||||||
container_name: datahub-mce-consumer
|
|
||||||
depends_on:
|
|
||||||
- kafka-setup
|
|
||||||
- datahub-gms
|
|
||||||
environment:
|
|
||||||
- KAFKA_BOOTSTRAP_SERVER=broker:29092
|
|
||||||
- KAFKA_SCHEMAREGISTRY_URL=http://schema-registry:8081
|
|
||||||
- GMS_HOST=datahub-gms
|
|
||||||
- GMS_PORT=8080
|
|
||||||
hostname: datahub-mce-consumer
|
|
||||||
image: linkedin/datahub-mce-consumer:${DATAHUB_VERSION:-latest}
|
|
||||||
mem_limit: 384m
|
|
||||||
ports:
|
|
||||||
- 9090:9090
|
|
||||||
elasticsearch:
|
elasticsearch:
|
||||||
container_name: elasticsearch
|
container_name: elasticsearch
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
@ -4,6 +4,8 @@ ext.apiProject = project(':gms:api')
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
runtime project(':gms:factories')
|
runtime project(':gms:factories')
|
||||||
|
runtime project(':metadata-jobs:mce-consumer')
|
||||||
|
runtime project(':metadata-jobs:mae-consumer')
|
||||||
|
|
||||||
runtime externalDependency.h2
|
runtime externalDependency.h2
|
||||||
runtime externalDependency.logbackClassic
|
runtime externalDependency.logbackClassic
|
||||||
|
|||||||
@ -7,9 +7,7 @@ REQUIRED_CONTAINERS = [
|
|||||||
"elasticsearch-setup",
|
"elasticsearch-setup",
|
||||||
"elasticsearch",
|
"elasticsearch",
|
||||||
"datahub-gms",
|
"datahub-gms",
|
||||||
"datahub-mce-consumer",
|
|
||||||
"datahub-frontend-react",
|
"datahub-frontend-react",
|
||||||
"datahub-mae-consumer",
|
|
||||||
"kafka-setup",
|
"kafka-setup",
|
||||||
"schema-registry",
|
"schema-registry",
|
||||||
"broker",
|
"broker",
|
||||||
@ -21,6 +19,8 @@ REQUIRED_CONTAINERS = [
|
|||||||
# "schema-registry-ui",
|
# "schema-registry-ui",
|
||||||
# "kibana",
|
# "kibana",
|
||||||
# "kafka-rest-proxy",
|
# "kafka-rest-proxy",
|
||||||
|
# "datahub-mce-consumer",
|
||||||
|
# "datahub-mae-consumer"
|
||||||
]
|
]
|
||||||
|
|
||||||
ENSURE_EXIT_SUCCESS = [
|
ENSURE_EXIT_SUCCESS = [
|
||||||
|
|||||||
@ -3,64 +3,15 @@ plugins {
|
|||||||
id 'java'
|
id 'java'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'pegasus'
|
|
||||||
|
|
||||||
configurations {
|
|
||||||
avro
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
avro project(path: ':metadata-models', configuration: 'avroSchema')
|
compile project(':metadata-jobs:mae-consumer')
|
||||||
|
compile(externalDependency.springBootStarterWeb) {
|
||||||
compile project(':li-utils')
|
|
||||||
compile (project(':gms:factories')) {
|
|
||||||
exclude group: 'org.neo4j.test'
|
|
||||||
}
|
|
||||||
compile project(':metadata-utils')
|
|
||||||
compile project(":entity-registry")
|
|
||||||
compile project(':metadata-builders')
|
|
||||||
compile project(':metadata-dao-impl:restli-dao')
|
|
||||||
compile project(':metadata-events:mxe-schemas')
|
|
||||||
compile project(':metadata-events:mxe-avro-1.7')
|
|
||||||
compile project(':metadata-events:mxe-registration')
|
|
||||||
compile project(':metadata-events:mxe-utils-avro-1.7')
|
|
||||||
|
|
||||||
compile externalDependency.elasticSearchRest
|
|
||||||
compile externalDependency.gmaDaoApi
|
|
||||||
compile externalDependency.gmaNeo4jDao
|
|
||||||
compile externalDependency.kafkaAvroSerde
|
|
||||||
compile externalDependency.neo4jJavaDriver
|
|
||||||
|
|
||||||
compile (externalDependency.springBootStarterWeb) {
|
|
||||||
exclude module: "spring-boot-starter-tomcat"
|
exclude module: "spring-boot-starter-tomcat"
|
||||||
}
|
}
|
||||||
compile externalDependency.springBootStarterJetty
|
compile externalDependency.springBootStarterJetty
|
||||||
compile externalDependency.springKafka
|
compile externalDependency.springKafka
|
||||||
compile externalDependency.springActuator
|
|
||||||
|
|
||||||
compileOnly externalDependency.lombok
|
|
||||||
|
|
||||||
annotationProcessor externalDependency.lombok
|
|
||||||
|
|
||||||
runtime externalDependency.logbackClassic
|
|
||||||
}
|
|
||||||
|
|
||||||
task avroSchemaSources(type: Copy) {
|
|
||||||
dependsOn configurations.avro
|
|
||||||
|
|
||||||
from { // use of closure defers evaluation until execution time
|
|
||||||
configurations.avro.collect { zipTree(it) }
|
|
||||||
}
|
|
||||||
into("src/main/resources/")
|
|
||||||
include("avro/com/linkedin/mxe/")
|
|
||||||
}
|
|
||||||
|
|
||||||
compileJava.dependsOn avroSchemaSources
|
|
||||||
|
|
||||||
clean {
|
|
||||||
project.delete("src/main/resources/avro")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bootJar {
|
bootJar {
|
||||||
mainClassName = 'com.linkedin.metadata.kafka.MaeConsumerApplication'
|
mainClassName = 'com.linkedin.metadata.kafka.MaeConsumerApplication'
|
||||||
}
|
}
|
||||||
@ -8,8 +8,8 @@ import org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientAutoC
|
|||||||
@SpringBootApplication(exclude = {RestClientAutoConfiguration.class})
|
@SpringBootApplication(exclude = {RestClientAutoConfiguration.class})
|
||||||
public class MaeConsumerApplication {
|
public class MaeConsumerApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Class<?>[] primarySources = {MaeConsumerApplication.class, MaeConsumerConfig.class};
|
Class<?>[] primarySources = {MaeConsumerApplication.class, com.linkedin.metadata.kafka.MaeConsumerConfig.class};
|
||||||
SpringApplication.run(primarySources, args);
|
SpringApplication.run(primarySources, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
57
metadata-jobs/mae-consumer/build.gradle
Normal file
57
metadata-jobs/mae-consumer/build.gradle
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'pegasus'
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
avro
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
avro project(path: ':metadata-models', configuration: 'avroSchema')
|
||||||
|
|
||||||
|
compile project(':li-utils')
|
||||||
|
compile (project(':gms:factories')) {
|
||||||
|
exclude group: 'org.neo4j.test'
|
||||||
|
}
|
||||||
|
compile project(':metadata-utils')
|
||||||
|
compile project(":entity-registry")
|
||||||
|
compile project(':metadata-builders')
|
||||||
|
compile project(':metadata-dao-impl:restli-dao')
|
||||||
|
compile project(':metadata-events:mxe-schemas')
|
||||||
|
compile project(':metadata-events:mxe-avro-1.7')
|
||||||
|
compile project(':metadata-events:mxe-registration')
|
||||||
|
compile project(':metadata-events:mxe-utils-avro-1.7')
|
||||||
|
|
||||||
|
compile externalDependency.elasticSearchRest
|
||||||
|
compile externalDependency.gmaDaoApi
|
||||||
|
compile externalDependency.gmaNeo4jDao
|
||||||
|
compile externalDependency.kafkaAvroSerde
|
||||||
|
compile externalDependency.neo4jJavaDriver
|
||||||
|
|
||||||
|
compile externalDependency.springKafka
|
||||||
|
compile externalDependency.springActuator
|
||||||
|
|
||||||
|
compileOnly externalDependency.lombok
|
||||||
|
|
||||||
|
annotationProcessor externalDependency.lombok
|
||||||
|
|
||||||
|
runtime externalDependency.logbackClassic
|
||||||
|
}
|
||||||
|
|
||||||
|
task avroSchemaSources(type: Copy) {
|
||||||
|
dependsOn configurations.avro
|
||||||
|
|
||||||
|
from { // use of closure defers evaluation until execution time
|
||||||
|
configurations.avro.collect { zipTree(it) }
|
||||||
|
}
|
||||||
|
into("src/main/resources/")
|
||||||
|
include("avro/com/linkedin/mxe/")
|
||||||
|
}
|
||||||
|
|
||||||
|
compileJava.dependsOn avroSchemaSources
|
||||||
|
|
||||||
|
clean {
|
||||||
|
project.delete("src/main/resources/avro")
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
package com.linkedin.metadata.kafka;
|
package com.linkedin.metadata.kafka;
|
||||||
|
|
||||||
import com.linkedin.events.metadata.ChangeType;
|
import com.linkedin.events.metadata.ChangeType;
|
||||||
|
import com.linkedin.metadata.kafka.config.DataHubUsageEventsProcessorCondition;
|
||||||
import com.linkedin.metadata.kafka.elasticsearch.ElasticsearchConnector;
|
import com.linkedin.metadata.kafka.elasticsearch.ElasticsearchConnector;
|
||||||
import com.linkedin.metadata.kafka.elasticsearch.JsonElasticEvent;
|
import com.linkedin.metadata.kafka.elasticsearch.JsonElasticEvent;
|
||||||
import com.linkedin.metadata.kafka.transformer.DataHubUsageEventTransformer;
|
import com.linkedin.metadata.kafka.transformer.DataHubUsageEventTransformer;
|
||||||
@ -11,7 +12,7 @@ import java.net.URLEncoder;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.context.annotation.Conditional;
|
||||||
import org.springframework.kafka.annotation.EnableKafka;
|
import org.springframework.kafka.annotation.EnableKafka;
|
||||||
import org.springframework.kafka.annotation.KafkaListener;
|
import org.springframework.kafka.annotation.KafkaListener;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -19,16 +20,18 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@ConditionalOnProperty(value = "DATAHUB_ANALYTICS_ENABLED", havingValue = "true", matchIfMissing = true)
|
|
||||||
@EnableKafka
|
@EnableKafka
|
||||||
|
@Conditional(DataHubUsageEventsProcessorCondition.class)
|
||||||
public class DataHubUsageEventsProcessor {
|
public class DataHubUsageEventsProcessor {
|
||||||
|
|
||||||
private final ElasticsearchConnector elasticSearchConnector;
|
private final ElasticsearchConnector elasticSearchConnector;
|
||||||
private final DataHubUsageEventTransformer dataHubUsageEventTransformer;
|
private final DataHubUsageEventTransformer dataHubUsageEventTransformer;
|
||||||
private final String indexName;
|
private final String indexName;
|
||||||
|
|
||||||
public DataHubUsageEventsProcessor(ElasticsearchConnector elasticSearchConnector,
|
public DataHubUsageEventsProcessor(
|
||||||
DataHubUsageEventTransformer dataHubUsageEventTransformer, IndexConvention indexConvention) {
|
ElasticsearchConnector elasticSearchConnector,
|
||||||
|
DataHubUsageEventTransformer dataHubUsageEventTransformer,
|
||||||
|
IndexConvention indexConvention) {
|
||||||
this.elasticSearchConnector = elasticSearchConnector;
|
this.elasticSearchConnector = elasticSearchConnector;
|
||||||
this.dataHubUsageEventTransformer = dataHubUsageEventTransformer;
|
this.dataHubUsageEventTransformer = dataHubUsageEventTransformer;
|
||||||
this.indexName = indexConvention.getIndexName("datahub_usage_event");
|
this.indexName = indexConvention.getIndexName("datahub_usage_event");
|
||||||
@ -10,6 +10,7 @@ import com.linkedin.metadata.dao.utils.RecordUtils;
|
|||||||
import com.linkedin.metadata.extractor.FieldExtractor;
|
import com.linkedin.metadata.extractor.FieldExtractor;
|
||||||
import com.linkedin.metadata.graph.Edge;
|
import com.linkedin.metadata.graph.Edge;
|
||||||
import com.linkedin.metadata.graph.GraphService;
|
import com.linkedin.metadata.graph.GraphService;
|
||||||
|
import com.linkedin.metadata.kafka.config.MetadataAuditEventsProcessorCondition;
|
||||||
import com.linkedin.metadata.models.EntitySpec;
|
import com.linkedin.metadata.models.EntitySpec;
|
||||||
import com.linkedin.metadata.models.RelationshipFieldSpec;
|
import com.linkedin.metadata.models.RelationshipFieldSpec;
|
||||||
import com.linkedin.metadata.models.registry.SnapshotEntityRegistry;
|
import com.linkedin.metadata.models.registry.SnapshotEntityRegistry;
|
||||||
@ -34,6 +35,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.apache.avro.generic.GenericRecord;
|
import org.apache.avro.generic.GenericRecord;
|
||||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Conditional;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.kafka.annotation.EnableKafka;
|
import org.springframework.kafka.annotation.EnableKafka;
|
||||||
import org.springframework.kafka.annotation.KafkaListener;
|
import org.springframework.kafka.annotation.KafkaListener;
|
||||||
@ -44,6 +46,7 @@ import static com.linkedin.metadata.dao.Neo4jUtil.createRelationshipFilter;
|
|||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
|
@Conditional(MetadataAuditEventsProcessorCondition.class)
|
||||||
@Import({GraphServiceFactory.class, SearchServiceFactory.class})
|
@Import({GraphServiceFactory.class, SearchServiceFactory.class})
|
||||||
@EnableKafka
|
@EnableKafka
|
||||||
public class MetadataAuditEventsProcessor {
|
public class MetadataAuditEventsProcessor {
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package com.linkedin.metadata.kafka.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Condition;
|
||||||
|
import org.springframework.context.annotation.ConditionContext;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||||
|
|
||||||
|
|
||||||
|
public class DataHubUsageEventsProcessorCondition implements Condition {
|
||||||
|
@Override
|
||||||
|
public boolean matches(
|
||||||
|
ConditionContext context,
|
||||||
|
AnnotatedTypeMetadata metadata) {
|
||||||
|
Environment env = context.getEnvironment();
|
||||||
|
return "true".equals(env.getProperty("MAE_CONSUMER_ENABLED")) && (
|
||||||
|
env.getProperty("DATAHUB_ANALYTICS_ENABLED") == null
|
||||||
|
|| "true".equals(env.getProperty("DATAHUB_ANALYTICS_ENABLED")));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,8 +15,6 @@ import com.linkedin.metadata.builders.search.TagIndexBuilder;
|
|||||||
import com.linkedin.metadata.builders.search.GlossaryTermInfoIndexBuilder;
|
import com.linkedin.metadata.builders.search.GlossaryTermInfoIndexBuilder;
|
||||||
import com.linkedin.metadata.builders.search.GlossaryNodeInfoIndexBuilder;
|
import com.linkedin.metadata.builders.search.GlossaryNodeInfoIndexBuilder;
|
||||||
import com.linkedin.metadata.restli.DefaultRestliClientFactory;
|
import com.linkedin.metadata.restli.DefaultRestliClientFactory;
|
||||||
import com.linkedin.metadata.utils.elasticsearch.IndexConvention;
|
|
||||||
import com.linkedin.metadata.utils.elasticsearch.IndexConventionImpl;
|
|
||||||
import com.linkedin.restli.client.Client;
|
import com.linkedin.restli.client.Client;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -71,12 +69,4 @@ public class IndexBuildersConfig {
|
|||||||
public Client restliClient() {
|
public Client restliClient() {
|
||||||
return DefaultRestliClientFactory.getRestLiClient(gmsHost, gmsPort);
|
return DefaultRestliClientFactory.getRestLiClient(gmsHost, gmsPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Convention for naming search indices
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public IndexConvention indexConvention() {
|
|
||||||
return new IndexConventionImpl(indexPrefix);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -20,7 +20,7 @@ import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
|
|||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Configuration
|
@Configuration
|
||||||
public class KafkaConfig {
|
public class MaeKafkaConfig {
|
||||||
@Value("${KAFKA_BOOTSTRAP_SERVER:http://localhost:9092}")
|
@Value("${KAFKA_BOOTSTRAP_SERVER:http://localhost:9092}")
|
||||||
private String kafkaBootstrapServer;
|
private String kafkaBootstrapServer;
|
||||||
@Value("${KAFKA_SCHEMAREGISTRY_URL:http://localhost:8081}")
|
@Value("${KAFKA_SCHEMAREGISTRY_URL:http://localhost:8081}")
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.linkedin.metadata.kafka.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Condition;
|
||||||
|
import org.springframework.context.annotation.ConditionContext;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||||
|
|
||||||
|
|
||||||
|
public class MetadataAuditEventsProcessorCondition implements Condition {
|
||||||
|
@Override
|
||||||
|
public boolean matches(
|
||||||
|
ConditionContext context,
|
||||||
|
AnnotatedTypeMetadata metadata) {
|
||||||
|
Environment env = context.getEnvironment();
|
||||||
|
return "true".equals(env.getProperty("MAE_CONSUMER_ENABLED"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -21,7 +21,7 @@ public class ElasticsearchConnectorFactory {
|
|||||||
|
|
||||||
@Bean(name = "elasticsearchConnector")
|
@Bean(name = "elasticsearchConnector")
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public ElasticsearchConnector createInstance(RestHighLevelClient elasticSearchRestHighLevelClient) {
|
public ElasticsearchConnector createInstance(@Nonnull RestHighLevelClient elasticSearchRestHighLevelClient) {
|
||||||
return new ElasticsearchConnector(elasticSearchRestHighLevelClient, bulkRequestsLimit, bulkFlushPeriod);
|
return new ElasticsearchConnector(elasticSearchRestHighLevelClient, bulkRequestsLimit, bulkFlushPeriod);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9,6 +9,7 @@ import com.linkedin.metadata.snapshot.ChartSnapshot;
|
|||||||
import com.linkedin.restli.client.Client;
|
import com.linkedin.restli.client.Client;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ public class ChartHydrator implements Hydrator {
|
|||||||
private static final String DASHBOARD_TOOL = "dashboardTool";
|
private static final String DASHBOARD_TOOL = "dashboardTool";
|
||||||
private static final String TITLE = "title";
|
private static final String TITLE = "title";
|
||||||
|
|
||||||
public ChartHydrator(Client restliClient) {
|
public ChartHydrator(@Nonnull Client restliClient) {
|
||||||
_restliClient = restliClient;
|
_restliClient = restliClient;
|
||||||
_remoteDAO = new RestliRemoteDAO<>(ChartSnapshot.class, ChartAspect.class, _restliClient);
|
_remoteDAO = new RestliRemoteDAO<>(ChartSnapshot.class, ChartAspect.class, _restliClient);
|
||||||
}
|
}
|
||||||
@ -9,6 +9,7 @@ import com.linkedin.metadata.snapshot.CorpUserSnapshot;
|
|||||||
import com.linkedin.restli.client.Client;
|
import com.linkedin.restli.client.Client;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ public class CorpUserHydrator implements Hydrator {
|
|||||||
private static final String USER_NAME = "username";
|
private static final String USER_NAME = "username";
|
||||||
private static final String NAME = "name";
|
private static final String NAME = "name";
|
||||||
|
|
||||||
public CorpUserHydrator(Client restliClient) {
|
public CorpUserHydrator(@Nonnull Client restliClient) {
|
||||||
_restliClient = restliClient;
|
_restliClient = restliClient;
|
||||||
_remoteDAO = new RestliRemoteDAO<>(CorpUserSnapshot.class, CorpUserAspect.class, _restliClient);
|
_remoteDAO = new RestliRemoteDAO<>(CorpUserSnapshot.class, CorpUserAspect.class, _restliClient);
|
||||||
}
|
}
|
||||||
@ -9,6 +9,7 @@ import com.linkedin.metadata.snapshot.DashboardSnapshot;
|
|||||||
import com.linkedin.restli.client.Client;
|
import com.linkedin.restli.client.Client;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ public class DashboardHydrator implements Hydrator {
|
|||||||
private static final String DASHBOARD_TOOL = "dashboardTool";
|
private static final String DASHBOARD_TOOL = "dashboardTool";
|
||||||
private static final String TITLE = "title";
|
private static final String TITLE = "title";
|
||||||
|
|
||||||
public DashboardHydrator(Client restliClient) {
|
public DashboardHydrator(@Nonnull Client restliClient) {
|
||||||
_restliClient = restliClient;
|
_restliClient = restliClient;
|
||||||
_remoteDAO = new RestliRemoteDAO<>(DashboardSnapshot.class, DashboardAspect.class, _restliClient);
|
_remoteDAO = new RestliRemoteDAO<>(DashboardSnapshot.class, DashboardAspect.class, _restliClient);
|
||||||
}
|
}
|
||||||
@ -9,6 +9,7 @@ import com.linkedin.metadata.snapshot.DataFlowSnapshot;
|
|||||||
import com.linkedin.restli.client.Client;
|
import com.linkedin.restli.client.Client;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ public class DataFlowHydrator implements Hydrator {
|
|||||||
private static final String ORCHESTRATOR = "orchestrator";
|
private static final String ORCHESTRATOR = "orchestrator";
|
||||||
private static final String NAME = "name";
|
private static final String NAME = "name";
|
||||||
|
|
||||||
public DataFlowHydrator(Client restliClient) {
|
public DataFlowHydrator(@Nonnull Client restliClient) {
|
||||||
_restliClient = restliClient;
|
_restliClient = restliClient;
|
||||||
_remoteDAO = new RestliRemoteDAO<>(DataFlowSnapshot.class, DataFlowAspect.class, _restliClient);
|
_remoteDAO = new RestliRemoteDAO<>(DataFlowSnapshot.class, DataFlowAspect.class, _restliClient);
|
||||||
}
|
}
|
||||||
@ -9,6 +9,7 @@ import com.linkedin.metadata.snapshot.DataJobSnapshot;
|
|||||||
import com.linkedin.restli.client.Client;
|
import com.linkedin.restli.client.Client;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ public class DataJobHydrator implements Hydrator {
|
|||||||
private static final String ORCHESTRATOR = "orchestrator";
|
private static final String ORCHESTRATOR = "orchestrator";
|
||||||
private static final String NAME = "name";
|
private static final String NAME = "name";
|
||||||
|
|
||||||
public DataJobHydrator(Client restliClient) {
|
public DataJobHydrator(@Nonnull Client restliClient) {
|
||||||
_restliClient = restliClient;
|
_restliClient = restliClient;
|
||||||
_remoteDAO = new RestliRemoteDAO<>(DataJobSnapshot.class, DataJobAspect.class, _restliClient);
|
_remoteDAO = new RestliRemoteDAO<>(DataJobSnapshot.class, DataJobAspect.class, _restliClient);
|
||||||
}
|
}
|
||||||
@ -6,6 +6,7 @@ import com.linkedin.restli.client.Client;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
|
||||||
public class HydratorFactory {
|
public class HydratorFactory {
|
||||||
@ -14,7 +15,7 @@ public class HydratorFactory {
|
|||||||
|
|
||||||
public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||||
|
|
||||||
public HydratorFactory(Client restliClient) {
|
public HydratorFactory(@Nonnull Client restliClient) {
|
||||||
_restliClient = restliClient;
|
_restliClient = restliClient;
|
||||||
_hydratorMap = new HashMap<>();
|
_hydratorMap = new HashMap<>();
|
||||||
_hydratorMap.put(EntityType.DATASET, new DatasetHydrator());
|
_hydratorMap.put(EntityType.DATASET, new DatasetHydrator());
|
||||||
@ -9,6 +9,7 @@ import com.linkedin.metadata.kafka.hydrator.EntityType;
|
|||||||
import com.linkedin.metadata.kafka.hydrator.HydratorFactory;
|
import com.linkedin.metadata.kafka.hydrator.HydratorFactory;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -36,7 +37,7 @@ public class DataHubUsageEventTransformer {
|
|||||||
String document;
|
String document;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataHubUsageEventTransformer(HydratorFactory hydratorFactory) {
|
public DataHubUsageEventTransformer(@Nonnull HydratorFactory hydratorFactory) {
|
||||||
this.hydratorFactory = hydratorFactory;
|
this.hydratorFactory = hydratorFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3,59 +3,15 @@ plugins {
|
|||||||
id 'java'
|
id 'java'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'pegasus'
|
|
||||||
|
|
||||||
configurations {
|
|
||||||
avro
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
avro project(path: ':metadata-models', configuration: 'avroSchema')
|
compile project(':metadata-jobs:mce-consumer')
|
||||||
|
compile(externalDependency.springBootStarterWeb) {
|
||||||
compile project(':li-utils')
|
|
||||||
compile project(':metadata-utils')
|
|
||||||
compile project(':metadata-builders')
|
|
||||||
compile project(':metadata-events:mxe-schemas')
|
|
||||||
compile project(':metadata-events:mxe-avro-1.7')
|
|
||||||
compile project(':metadata-events:mxe-registration')
|
|
||||||
compile project(':metadata-events:mxe-utils-avro-1.7')
|
|
||||||
compile project(':metadata-dao-impl:restli-dao')
|
|
||||||
compile project(':metadata-io')
|
|
||||||
compile project(':gms:client')
|
|
||||||
compile spec.product.pegasus.restliClient
|
|
||||||
compile spec.product.pegasus.restliCommon
|
|
||||||
compile externalDependency.elasticSearchRest
|
|
||||||
compile externalDependency.kafkaAvroSerde
|
|
||||||
compile (externalDependency.springBootStarterWeb) {
|
|
||||||
exclude module: "spring-boot-starter-tomcat"
|
exclude module: "spring-boot-starter-tomcat"
|
||||||
}
|
}
|
||||||
compile externalDependency.springBootStarterJetty
|
compile externalDependency.springBootStarterJetty
|
||||||
compile externalDependency.springKafka
|
compile externalDependency.springKafka
|
||||||
|
|
||||||
compile externalDependency.springActuator
|
|
||||||
|
|
||||||
compileOnly externalDependency.lombok
|
|
||||||
|
|
||||||
annotationProcessor externalDependency.lombok
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
task avroSchemaSources(type: Copy) {
|
|
||||||
dependsOn configurations.avro
|
|
||||||
|
|
||||||
from { // use of closure defers evaluation until execution time
|
|
||||||
configurations.avro.collect { zipTree(it) }
|
|
||||||
}
|
|
||||||
into("src/main/resources/")
|
|
||||||
include("avro/com/linkedin/mxe/")
|
|
||||||
}
|
|
||||||
|
|
||||||
compileJava.dependsOn avroSchemaSources
|
|
||||||
|
|
||||||
clean {
|
|
||||||
project.delete("src/main/resources/avro")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bootJar {
|
bootJar {
|
||||||
mainClassName = 'com.linkedin.metadata.kafka.MceConsumerApplication'
|
mainClassName = 'com.linkedin.metadata.kafka.MceConsumerApplication'
|
||||||
}
|
}
|
||||||
@ -12,4 +12,4 @@ public class MceConsumerApplication {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(MceConsumerApplication.class, args);
|
SpringApplication.run(MceConsumerApplication.class, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
52
metadata-jobs/mce-consumer/build.gradle
Normal file
52
metadata-jobs/mce-consumer/build.gradle
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'pegasus'
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
avro
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
avro project(path: ':metadata-models', configuration: 'avroSchema')
|
||||||
|
|
||||||
|
compile project(':li-utils')
|
||||||
|
compile project(':metadata-utils')
|
||||||
|
compile project(':metadata-builders')
|
||||||
|
compile project(':metadata-events:mxe-schemas')
|
||||||
|
compile project(':metadata-events:mxe-avro-1.7')
|
||||||
|
compile project(':metadata-events:mxe-registration')
|
||||||
|
compile project(':metadata-events:mxe-utils-avro-1.7')
|
||||||
|
compile project(':metadata-dao-impl:restli-dao')
|
||||||
|
compile project(':metadata-io')
|
||||||
|
compile project(':gms:client')
|
||||||
|
compile spec.product.pegasus.restliClient
|
||||||
|
compile spec.product.pegasus.restliCommon
|
||||||
|
compile externalDependency.elasticSearchRest
|
||||||
|
compile externalDependency.kafkaAvroSerde
|
||||||
|
|
||||||
|
compile externalDependency.springKafka
|
||||||
|
compile externalDependency.springActuator
|
||||||
|
|
||||||
|
compileOnly externalDependency.lombok
|
||||||
|
|
||||||
|
annotationProcessor externalDependency.lombok
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
task avroSchemaSources(type: Copy) {
|
||||||
|
dependsOn configurations.avro
|
||||||
|
|
||||||
|
from { // use of closure defers evaluation until execution time
|
||||||
|
configurations.avro.collect { zipTree(it) }
|
||||||
|
}
|
||||||
|
into("src/main/resources/")
|
||||||
|
include("avro/com/linkedin/mxe/")
|
||||||
|
}
|
||||||
|
|
||||||
|
compileJava.dependsOn avroSchemaSources
|
||||||
|
|
||||||
|
clean {
|
||||||
|
project.delete("src/main/resources/avro")
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@ package com.linkedin.metadata.kafka;
|
|||||||
import com.linkedin.entity.client.EntityClient;
|
import com.linkedin.entity.client.EntityClient;
|
||||||
import com.linkedin.entity.Entity;
|
import com.linkedin.entity.Entity;
|
||||||
import com.linkedin.metadata.EventUtils;
|
import com.linkedin.metadata.EventUtils;
|
||||||
|
import com.linkedin.metadata.kafka.config.MetadataChangeEventsProcessorCondition;
|
||||||
import com.linkedin.metadata.snapshot.Snapshot;
|
import com.linkedin.metadata.snapshot.Snapshot;
|
||||||
import com.linkedin.mxe.FailedMetadataChangeEvent;
|
import com.linkedin.mxe.FailedMetadataChangeEvent;
|
||||||
import com.linkedin.mxe.MetadataChangeEvent;
|
import com.linkedin.mxe.MetadataChangeEvent;
|
||||||
@ -15,6 +16,7 @@ import org.apache.avro.generic.GenericRecord;
|
|||||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Conditional;
|
||||||
import org.springframework.kafka.annotation.EnableKafka;
|
import org.springframework.kafka.annotation.EnableKafka;
|
||||||
import org.springframework.kafka.annotation.KafkaListener;
|
import org.springframework.kafka.annotation.KafkaListener;
|
||||||
import org.springframework.kafka.core.KafkaTemplate;
|
import org.springframework.kafka.core.KafkaTemplate;
|
||||||
@ -23,6 +25,7 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
|
@Conditional(MetadataChangeEventsProcessorCondition.class)
|
||||||
@EnableKafka
|
@EnableKafka
|
||||||
public class MetadataChangeEventsProcessor {
|
public class MetadataChangeEventsProcessor {
|
||||||
|
|
||||||
@ -40,7 +43,7 @@ public class MetadataChangeEventsProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@KafkaListener(id = "${KAFKA_CONSUMER_GROUP_ID:mce-consumer-job-client}", topics = "${KAFKA_MCE_TOPIC_NAME:"
|
@KafkaListener(id = "${KAFKA_CONSUMER_GROUP_ID:mce-consumer-job-client}", topics = "${KAFKA_MCE_TOPIC_NAME:"
|
||||||
+ Topics.METADATA_CHANGE_EVENT + "}")
|
+ Topics.METADATA_CHANGE_EVENT + "}", containerFactory = "mceKafkaContainerFactory")
|
||||||
public void consume(final ConsumerRecord<String, GenericRecord> consumerRecord) {
|
public void consume(final ConsumerRecord<String, GenericRecord> consumerRecord) {
|
||||||
final GenericRecord record = consumerRecord.value();
|
final GenericRecord record = consumerRecord.value();
|
||||||
log.debug("Record ", record);
|
log.debug("Record ", record);
|
||||||
@ -24,13 +24,14 @@ import org.springframework.kafka.listener.ErrorHandler;
|
|||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Configuration
|
@Configuration
|
||||||
public class KafkaConfig {
|
public class MceKafkaConfig {
|
||||||
|
|
||||||
@Value("${KAFKA_BOOTSTRAP_SERVER:http://localhost:9092}")
|
@Value("${KAFKA_BOOTSTRAP_SERVER:http://localhost:9092}")
|
||||||
private String kafkaBootstrapServers;
|
private String kafkaBootstrapServers;
|
||||||
@Value("${KAFKA_SCHEMAREGISTRY_URL:http://localhost:8081}")
|
@Value("${KAFKA_SCHEMAREGISTRY_URL:http://localhost:8081}")
|
||||||
private String kafkaSchemaRegistryUrl;
|
private String kafkaSchemaRegistryUrl;
|
||||||
|
|
||||||
@Bean
|
@Bean(name = "mceKafkaContainerFactory")
|
||||||
public KafkaListenerContainerFactory<?> kafkaListenerContainerFactory(KafkaProperties properties) {
|
public KafkaListenerContainerFactory<?> kafkaListenerContainerFactory(KafkaProperties properties) {
|
||||||
KafkaProperties.Consumer consumerProps = properties.getConsumer();
|
KafkaProperties.Consumer consumerProps = properties.getConsumer();
|
||||||
|
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.linkedin.metadata.kafka.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Condition;
|
||||||
|
import org.springframework.context.annotation.ConditionContext;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||||
|
|
||||||
|
|
||||||
|
public class MetadataChangeEventsProcessorCondition implements Condition {
|
||||||
|
@Override
|
||||||
|
public boolean matches(
|
||||||
|
ConditionContext context,
|
||||||
|
AnnotatedTypeMetadata metadata) {
|
||||||
|
Environment env = context.getEnvironment();
|
||||||
|
return "true".equals(env.getProperty("MCE_CONSUMER_ENABLED"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -21,6 +21,8 @@ include 'metadata-ingestion'
|
|||||||
include 'metadata-ingestion-examples:common'
|
include 'metadata-ingestion-examples:common'
|
||||||
include 'metadata-ingestion-examples:kafka-etl'
|
include 'metadata-ingestion-examples:kafka-etl'
|
||||||
include 'metadata-ingestion-examples:mce-cli'
|
include 'metadata-ingestion-examples:mce-cli'
|
||||||
|
include 'metadata-jobs:mae-consumer'
|
||||||
|
include 'metadata-jobs:mce-consumer'
|
||||||
include 'metadata-jobs:mae-consumer-job'
|
include 'metadata-jobs:mae-consumer-job'
|
||||||
include 'metadata-jobs:mce-consumer-job'
|
include 'metadata-jobs:mce-consumer-job'
|
||||||
include 'metadata-models'
|
include 'metadata-models'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user