diff --git a/li-utils/src/main/java/com/linkedin/common/urn/AzkabanFlowUrn.java b/li-utils/src/main/java/com/linkedin/common/urn/AzkabanFlowUrn.java new file mode 100644 index 0000000000..811b79deac --- /dev/null +++ b/li-utils/src/main/java/com/linkedin/common/urn/AzkabanFlowUrn.java @@ -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() { + 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); + } +} diff --git a/li-utils/src/main/java/com/linkedin/common/urn/AzkabanJobUrn.java b/li-utils/src/main/java/com/linkedin/common/urn/AzkabanJobUrn.java new file mode 100644 index 0000000000..bd95370756 --- /dev/null +++ b/li-utils/src/main/java/com/linkedin/common/urn/AzkabanJobUrn.java @@ -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() { + 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); + } +} diff --git a/li-utils/src/main/pegasus/com/linkedin/common/AzkabanFlowUrn.pdsc b/li-utils/src/main/pegasus/com/linkedin/common/AzkabanFlowUrn.pdsc new file mode 100644 index 0000000000..a8998c97d7 --- /dev/null +++ b/li-utils/src/main/pegasus/com/linkedin/common/AzkabanFlowUrn.pdsc @@ -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 + } + } +} \ No newline at end of file diff --git a/li-utils/src/main/pegasus/com/linkedin/common/AzkabanJobUrn.pdsc b/li-utils/src/main/pegasus/com/linkedin/common/AzkabanJobUrn.pdsc new file mode 100644 index 0000000000..9b37d98a7d --- /dev/null +++ b/li-utils/src/main/pegasus/com/linkedin/common/AzkabanJobUrn.pdsc @@ -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 + } + } +} \ No newline at end of file