feat(urn): add AzkabanFlow and AzkabanJob urn (#1677)

* feat(urn): add AzkabanFlow and AzkabanJob urn

Add AzkabanFlow urn to represent an azkaban flow defined on a specific cluster
and inside a project.

Add AzkabanJob urn to represent an azkaban job defined as part of an azkaban
flow.

For more details on Azkaban flow and job see - https://azkaban.readthedocs.io/en/latest/
This commit is contained in:
Harsh Shah 2020-05-21 11:25:46 -07:00 committed by GitHub
parent 1283dd3ff4
commit 37d9ebfdea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 196 additions and 0 deletions

View File

@ -0,0 +1,65 @@
package com.linkedin.common.urn;
import com.linkedin.data.template.Custom;
import com.linkedin.data.template.DirectCoercer;
import com.linkedin.data.template.TemplateOutputCastException;
import java.net.URISyntaxException;
public final class AzkabanFlowUrn extends Urn {
public static final String ENTITY_TYPE = "azkabanFlow";
private static final String CONTENT_FORMAT = "(%s,%s,%s)";
private final String clusterEntity;
private final String projectEntity;
private final String flowIdEntity;
public AzkabanFlowUrn(String cluster, String project, String flowId) {
super(ENTITY_TYPE, String.format(CONTENT_FORMAT, cluster, project, flowId));
this.clusterEntity = cluster;
this.projectEntity = project;
this.flowIdEntity = flowId;
}
public String getClusterEntity() {
return clusterEntity;
}
public String getProjectEntity() {
return projectEntity;
}
public String getFlowIdEntity() {
return flowIdEntity;
}
public static AzkabanFlowUrn createFromString(String rawUrn) throws URISyntaxException {
String content = new Urn(rawUrn).getContent();
String[] parts = content.substring(1, content.length() - 1).split(",");
return new AzkabanFlowUrn(parts[0], parts[1], parts[2]);
}
public static AzkabanFlowUrn deserialize(String rawUrn) throws URISyntaxException {
return createFromString(rawUrn);
}
static {
Custom.registerCoercer(new DirectCoercer<AzkabanFlowUrn>() {
public Object coerceInput(AzkabanFlowUrn object) throws ClassCastException {
return object.toString();
}
public AzkabanFlowUrn coerceOutput(Object object) throws TemplateOutputCastException {
try {
return AzkabanFlowUrn.createFromString((String) object);
} catch (URISyntaxException e) {
throw new TemplateOutputCastException("Invalid URN syntax: " + e.getMessage(), e);
}
}
}, AzkabanFlowUrn.class);
}
}

View File

@ -0,0 +1,59 @@
package com.linkedin.common.urn;
import com.linkedin.data.template.Custom;
import com.linkedin.data.template.DirectCoercer;
import com.linkedin.data.template.TemplateOutputCastException;
import java.net.URISyntaxException;
public final class AzkabanJobUrn extends Urn {
public static final String ENTITY_TYPE = "azkabanJob";
private static final String CONTENT_FORMAT = "(%s,%s)";
private final AzkabanFlowUrn flowEntity;
private final String jobIdEntity;
public AzkabanJobUrn(AzkabanFlowUrn flow, String jobId) {
super(ENTITY_TYPE, String.format(CONTENT_FORMAT, flow.toString(), jobId));
this.flowEntity = flow;
this.jobIdEntity = jobId;
}
public AzkabanFlowUrn getFlowEntity() {
return flowEntity;
}
public String getJobIdEntity() {
return jobIdEntity;
}
public static AzkabanJobUrn createFromString(String rawUrn) throws URISyntaxException {
String content = new Urn(rawUrn).getContent();
String flowParts = content.substring(1, content.lastIndexOf(",") + 1);
String[] parts = content.substring(1, content.length() - 1).split(",");
return new AzkabanJobUrn(AzkabanFlowUrn.createFromString(flowParts), parts[3]);
}
public static AzkabanJobUrn deserialize(String rawUrn) throws URISyntaxException {
return createFromString(rawUrn);
}
static {
Custom.registerCoercer(new DirectCoercer<AzkabanJobUrn>() {
public Object coerceInput(AzkabanJobUrn object) throws ClassCastException {
return object.toString();
}
public AzkabanJobUrn coerceOutput(Object object) throws TemplateOutputCastException {
try {
return AzkabanJobUrn.createFromString((String) object);
} catch (URISyntaxException e) {
throw new TemplateOutputCastException("Invalid URN syntax: " + e.getMessage(), e);
}
}
}, AzkabanJobUrn.class);
}
}

View File

@ -0,0 +1,39 @@
{
"ref" : "string",
"java" : {
"class" : "com.linkedin.common.urn.AzkabanFlowUrn"
},
"name" : "AzkabanFlowUrn",
"namespace" : "com.linkedin.common",
"doc" : "Standardized azkaban flow identifier.",
"type" : "typeref",
"validate" : {
"com.linkedin.common.validator.TypedUrnValidator" : {
"accessible" : true,
"entityType" : "azkabanFlow",
"owningTeam" : "urn:li:internalTeam:datahub",
"constructable" : true,
"name" : "AzkabanFlow",
"namespace" : "li",
"doc" : "Standardized azkaban flow identifier.",
"owners" : [ "urn:li:corpuser:fbar", "urn:li:corpuser:bfoo" ],
"fields" : [ {
"name" : "cluster",
"doc" : "Cluster on which the azkaban flow is deployed",
"type" : "string",
"maxLength" : 20
}, {
"name" : "project",
"doc" : "Azkaban project name which is unique per cluster",
"type" : "string",
"maxLength" : 100
}, {
"name" : "flowId",
"doc" : "Id or name of the azkaban flow",
"type" : "string",
"maxLength" : 100
} ],
"maxLength" : 243
}
}
}

View File

@ -0,0 +1,33 @@
{
"ref" : "string",
"java" : {
"class" : "com.linkedin.common.urn.AzkabanJobUrn"
},
"name" : "AzkabanJobUrn",
"namespace" : "com.linkedin.common",
"doc" : "Standardized azkaban job identifier.",
"type" : "typeref",
"validate" : {
"com.linkedin.common.validator.TypedUrnValidator" : {
"accessible" : true,
"entityType" : "azkabanJob",
"owningTeam" : "urn:li:internalTeam:datahub",
"constructable" : true,
"name" : "AzkabanJob",
"namespace" : "li",
"doc" : "Standardized azkaban job identifier.",
"owners" : [ "urn:li:corpuser:fbar", "urn:li:corpuser:bfoo" ],
"fields" : [ {
"name" : "flow",
"doc" : "Standardized azkaban flow urn representing the flow for the job",
"type" : "com.linkedin.common.urn.AzkabanFlowUrn"
}, {
"name" : "jobID",
"doc" : "Id or name of the azkaban job",
"type" : "string",
"maxLength" : 200
} ],
"maxLength" : 464
}
}
}