Skip to content

Commit

Permalink
feat(forms) Add java SDK for form entity PATCH + CRUD examples (#10822)
Browse files Browse the repository at this point in the history
  • Loading branch information
chriscollins3456 authored and yoonhyejin committed Jul 16, 2024
1 parent d755cca commit af2be82
Show file tree
Hide file tree
Showing 4 changed files with 350 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package com.linkedin.metadata.aspect.patch.builder;

import static com.fasterxml.jackson.databind.node.JsonNodeFactory.instance;
import static com.linkedin.metadata.Constants.*;

import com.datahub.util.RecordUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.linkedin.form.FormPrompt;
import com.linkedin.form.FormType;
import com.linkedin.metadata.aspect.patch.PatchOperationType;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.ImmutableTriple;

public class FormInfoPatchBuilder extends AbstractMultiFieldPatchBuilder<FormInfoPatchBuilder> {

public static final String PATH_DELIM = "/";
public static final String NAME_FIELD = "name";
public static final String DESCRIPTION_FIELD = "description";
public static final String TYPE_FIELD = "type";
public static final String PROMPTS_FIELD = "prompts";
public static final String ACTORS_FIELD = "actors";
public static final String OWNERS_FIELD = "owners";
public static final String USERS_FIELD = "users";
public static final String GROUPS_FIELD = "groups";

public FormInfoPatchBuilder setName(@Nonnull String name) {
this.pathValues.add(
ImmutableTriple.of(
PatchOperationType.ADD.getValue(), PATH_DELIM + NAME_FIELD, instance.textNode(name)));
return this;
}

public FormInfoPatchBuilder setDescription(@Nullable String description) {
if (description == null) {
this.pathValues.add(
ImmutableTriple.of(
PatchOperationType.REMOVE.getValue(), PATH_DELIM + DESCRIPTION_FIELD, null));
} else {
this.pathValues.add(
ImmutableTriple.of(
PatchOperationType.ADD.getValue(),
PATH_DELIM + DESCRIPTION_FIELD,
instance.textNode(description)));
}
return this;
}

public FormInfoPatchBuilder setType(@Nonnull FormType formType) {
this.pathValues.add(
ImmutableTriple.of(
PatchOperationType.ADD.getValue(),
PATH_DELIM + TYPE_FIELD,
instance.textNode(formType.toString())));
return this;
}

public FormInfoPatchBuilder addPrompt(@Nonnull FormPrompt prompt) {
try {
ObjectNode promptNode =
(ObjectNode) new ObjectMapper().readTree(RecordUtils.toJsonString(prompt));
pathValues.add(
ImmutableTriple.of(
PatchOperationType.ADD.getValue(),
PATH_DELIM + PROMPTS_FIELD + PATH_DELIM + prompt.getId(),
promptNode));
return this;
} catch (JsonProcessingException e) {
throw new IllegalArgumentException(
"Failed to add prompt, failed to parse provided aspect json.", e);
}
}

public FormInfoPatchBuilder addPrompts(@Nonnull List<FormPrompt> prompts) {
try {
prompts.forEach(this::addPrompt);
return this;
} catch (Exception e) {
throw new IllegalArgumentException("Failed to add prompts.", e);
}
}

public FormInfoPatchBuilder removePrompt(@Nonnull String promptId) {
this.pathValues.add(
ImmutableTriple.of(
PatchOperationType.REMOVE.getValue(),
PATH_DELIM + PROMPTS_FIELD + PATH_DELIM + promptId,
null));
return this;
}

public FormInfoPatchBuilder removePrompts(@Nonnull List<String> promptIds) {
promptIds.forEach(this::removePrompt);
return this;
}

public FormInfoPatchBuilder setOwnershipForm(boolean isOwnershipForm) {
this.pathValues.add(
ImmutableTriple.of(
PatchOperationType.ADD.getValue(),
PATH_DELIM + ACTORS_FIELD + PATH_DELIM + OWNERS_FIELD,
instance.booleanNode(isOwnershipForm)));
return this;
}

public FormInfoPatchBuilder addAssignedUser(@Nonnull String userUrn) {
this.pathValues.add(
ImmutableTriple.of(
PatchOperationType.ADD.getValue(),
PATH_DELIM + ACTORS_FIELD + PATH_DELIM + USERS_FIELD + PATH_DELIM + userUrn,
instance.textNode(userUrn)));
return this;
}

public FormInfoPatchBuilder removeAssignedUser(@Nonnull String userUrn) {
this.pathValues.add(
ImmutableTriple.of(
PatchOperationType.REMOVE.getValue(),
PATH_DELIM + ACTORS_FIELD + PATH_DELIM + USERS_FIELD + PATH_DELIM + userUrn,
instance.textNode(userUrn)));
return this;
}

public FormInfoPatchBuilder addAssignedGroup(@Nonnull String groupUrn) {
this.pathValues.add(
ImmutableTriple.of(
PatchOperationType.ADD.getValue(),
PATH_DELIM + ACTORS_FIELD + PATH_DELIM + GROUPS_FIELD + PATH_DELIM + groupUrn,
instance.textNode(groupUrn)));
return this;
}

public FormInfoPatchBuilder removeAssignedGroup(@Nonnull String groupUrn) {
this.pathValues.add(
ImmutableTriple.of(
PatchOperationType.REMOVE.getValue(),
PATH_DELIM + ACTORS_FIELD + PATH_DELIM + GROUPS_FIELD + PATH_DELIM + groupUrn,
instance.textNode(groupUrn)));
return this;
}

@Override
protected String getAspectName() {
return FORM_INFO_ASPECT_NAME;
}

@Override
protected String getEntityType() {
return FORM_ENTITY_NAME;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@
import com.linkedin.common.urn.Urn;
import com.linkedin.common.urn.UrnUtils;
import com.linkedin.dataset.DatasetLineageType;
import com.linkedin.form.FormPrompt;
import com.linkedin.form.FormPromptType;
import com.linkedin.form.StructuredPropertyParams;
import com.linkedin.metadata.aspect.patch.builder.ChartInfoPatchBuilder;
import com.linkedin.metadata.aspect.patch.builder.DashboardInfoPatchBuilder;
import com.linkedin.metadata.aspect.patch.builder.DataFlowInfoPatchBuilder;
import com.linkedin.metadata.aspect.patch.builder.DataJobInfoPatchBuilder;
import com.linkedin.metadata.aspect.patch.builder.DataJobInputOutputPatchBuilder;
import com.linkedin.metadata.aspect.patch.builder.DatasetPropertiesPatchBuilder;
import com.linkedin.metadata.aspect.patch.builder.EditableSchemaMetadataPatchBuilder;
import com.linkedin.metadata.aspect.patch.builder.FormInfoPatchBuilder;
import com.linkedin.metadata.aspect.patch.builder.OwnershipPatchBuilder;
import com.linkedin.metadata.aspect.patch.builder.UpstreamLineagePatchBuilder;
import com.linkedin.metadata.graph.LineageDirection;
Expand All @@ -37,6 +41,7 @@
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.junit.Ignore;
Expand Down Expand Up @@ -641,4 +646,70 @@ public void testLocalDashboardInfoRemove() {
System.out.println(Arrays.asList(e.getStackTrace()));
}
}

@Test
@Ignore
public void testLocalFormInfoAdd() {
RestEmitter restEmitter = new RestEmitter(RestEmitterConfig.builder().build());
try {
FormPrompt newPrompt =
new FormPrompt()
.setId("1234")
.setTitle("First Prompt")
.setType(FormPromptType.STRUCTURED_PROPERTY)
.setRequired(true)
.setStructuredPropertyParams(
new StructuredPropertyParams()
.setUrn(UrnUtils.getUrn("urn:li:structuredProperty:property1")));
FormPrompt newPrompt2 =
new FormPrompt()
.setId("abcd")
.setTitle("Second Prompt")
.setType(FormPromptType.FIELDS_STRUCTURED_PROPERTY)
.setRequired(false)
.setStructuredPropertyParams(
new StructuredPropertyParams()
.setUrn(UrnUtils.getUrn("urn:li:structuredProperty:property1")));

MetadataChangeProposal formInfoPatch =
new FormInfoPatchBuilder()
.urn(UrnUtils.getUrn("urn:li:form:123456"))
.addPrompts(List.of(newPrompt, newPrompt2))
.setName("Metadata Initiative 2024 (edited)")
.setDescription("Edited description")
.setOwnershipForm(true)
.addAssignedUser("urn:li:corpuser:admin")
.addAssignedGroup("urn:li:corpGroup:jdoe")
.build();
Future<MetadataWriteResponse> response = restEmitter.emit(formInfoPatch);

System.out.println(response.get().getResponseContent());

} catch (IOException | ExecutionException | InterruptedException e) {
System.out.println(Arrays.asList(e.getStackTrace()));
}
}

@Test
@Ignore
public void testLocalFormInfoRemove() {
RestEmitter restEmitter = new RestEmitter(RestEmitterConfig.builder().build());
try {
MetadataChangeProposal formInfoPatch =
new FormInfoPatchBuilder()
.urn(UrnUtils.getUrn("urn:li:form:123456"))
.removePrompts(List.of("1234", "abcd"))
.setName("Metadata Initiative 2024 (edited - again)")
.setDescription(null)
.removeAssignedUser("urn:li:corpuser:admin")
.removeAssignedGroup("urn:li:corpGroup:jdoe")
.build();
Future<MetadataWriteResponse> response = restEmitter.emit(formInfoPatch);

System.out.println(response.get().getResponseContent());

} catch (IOException | ExecutionException | InterruptedException e) {
System.out.println(Arrays.asList(e.getStackTrace()));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package io.datahubproject.examples;

import com.linkedin.common.urn.UrnUtils;
import com.linkedin.form.FormActorAssignment;
import com.linkedin.form.FormInfo;
import com.linkedin.form.FormPrompt;
import com.linkedin.form.FormPromptArray;
import com.linkedin.form.FormPromptType;
import com.linkedin.form.FormType;
import com.linkedin.form.StructuredPropertyParams;
import datahub.client.MetadataWriteResponse;
import datahub.client.rest.RestEmitter;
import datahub.event.MetadataChangeProposalWrapper;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

public class FormCreate {

private FormCreate() {}

public static void main(String[] args)
throws IOException, ExecutionException, InterruptedException {
FormPromptArray prompts = new FormPromptArray();
FormPrompt prompt1 =
new FormPrompt()
.setId("1")
.setTitle("First Prompt")
.setType(FormPromptType.STRUCTURED_PROPERTY)
.setRequired(true)
.setStructuredPropertyParams(
new StructuredPropertyParams()
.setUrn(UrnUtils.getUrn("urn:li:structuredProperty:property1")));
FormPrompt prompt2 =
new FormPrompt()
.setId("2")
.setTitle("Second Prompt")
.setType(FormPromptType.FIELDS_STRUCTURED_PROPERTY)
.setRequired(false)
.setStructuredPropertyParams(
new StructuredPropertyParams()
.setUrn(UrnUtils.getUrn("urn:li:structuredProperty:property1")));
prompts.add(prompt1);
prompts.add(prompt2);

FormInfo formInfo =
new FormInfo()
.setName("Metadata Initiative 2024")
.setDescription("Please respond to this form for metadata compliance purposes.")
.setType(FormType.VERIFICATION)
.setPrompts(prompts)
.setActors(new FormActorAssignment().setOwners(true));

MetadataChangeProposalWrapper mcpw =
MetadataChangeProposalWrapper.builder()
.entityType("form")
.entityUrn("urn:li:form:metadata_initiative_1")
.upsert()
.aspect(formInfo)
.aspectName("formInfo")
.build();

String token = "";
RestEmitter emitter = RestEmitter.create(b -> b.server("http://localhost:8080").token(token));
Future<MetadataWriteResponse> response = emitter.emit(mcpw, null);
System.out.println(response.get().getResponseContent());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package io.datahubproject.examples;

import com.linkedin.common.urn.Urn;
import com.linkedin.common.urn.UrnUtils;
import com.linkedin.form.FormPrompt;
import com.linkedin.form.FormPromptType;
import com.linkedin.form.StructuredPropertyParams;
import com.linkedin.metadata.aspect.patch.builder.FormInfoPatchBuilder;
import com.linkedin.mxe.MetadataChangeProposal;
import datahub.client.MetadataWriteResponse;
import datahub.client.rest.RestEmitter;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

public class FormUpdate {

private FormUpdate() {}

public static void main(String[] args)
throws IOException, ExecutionException, InterruptedException {
FormPrompt newPrompt =
new FormPrompt()
.setId("1234")
.setTitle("First Prompt")
.setType(FormPromptType.STRUCTURED_PROPERTY)
.setRequired(true)
.setStructuredPropertyParams(
new StructuredPropertyParams()
.setUrn(UrnUtils.getUrn("urn:li:structuredProperty:property1")));
FormPrompt newPrompt2 =
new FormPrompt()
.setId("abcd")
.setTitle("Second Prompt")
.setType(FormPromptType.FIELDS_STRUCTURED_PROPERTY)
.setRequired(false)
.setStructuredPropertyParams(
new StructuredPropertyParams()
.setUrn(UrnUtils.getUrn("urn:li:structuredProperty:property1")));

Urn formUrn = UrnUtils.getUrn("urn:li:form:metadata_initiative_1");
FormInfoPatchBuilder formInfoPatchBuilder =
new FormInfoPatchBuilder()
.urn(formUrn)
.addPrompts(List.of(newPrompt, newPrompt2))
.setName("Metadata Initiative 2024 (edited)")
.setDescription("Edited description")
.setOwnershipForm(true);
MetadataChangeProposal mcp = formInfoPatchBuilder.build();

String token = "";
RestEmitter emitter = RestEmitter.create(b -> b.server("http://localhost:8080").token(token));
Future<MetadataWriteResponse> response = emitter.emit(mcp, null);
System.out.println(response.get().getResponseContent());
}
}

0 comments on commit af2be82

Please sign in to comment.