Skip to content

Commit 050235b

Browse files
committed
java client supports udf ops and add ITs
1 parent cc9af59 commit 050235b

File tree

8 files changed

+1579
-3
lines changed

8 files changed

+1579
-3
lines changed

catalogs/catalog-hive/src/test/java/org/apache/gravitino/catalog/hive/integration/test/CatalogHive2IT.java

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,18 @@
6666
import org.apache.gravitino.client.GravitinoMetalake;
6767
import org.apache.gravitino.connector.BaseCatalog;
6868
import org.apache.gravitino.exceptions.NoSuchCatalogException;
69+
import org.apache.gravitino.exceptions.NoSuchFunctionException;
6970
import org.apache.gravitino.exceptions.NoSuchMetalakeException;
7071
import org.apache.gravitino.exceptions.NoSuchPartitionException;
7172
import org.apache.gravitino.exceptions.NoSuchSchemaException;
7273
import org.apache.gravitino.exceptions.NoSuchTableException;
74+
import org.apache.gravitino.function.Function;
75+
import org.apache.gravitino.function.FunctionChange;
76+
import org.apache.gravitino.function.FunctionDefinitions;
77+
import org.apache.gravitino.function.FunctionImpl;
78+
import org.apache.gravitino.function.FunctionImpls;
79+
import org.apache.gravitino.function.FunctionParams;
80+
import org.apache.gravitino.function.FunctionType;
7381
import org.apache.gravitino.hive.HiveClientPool;
7482
import org.apache.gravitino.hive.HivePartition;
7583
import org.apache.gravitino.hive.HiveSchema;
@@ -78,6 +86,7 @@
7886
import org.apache.gravitino.integration.test.container.HiveContainer;
7987
import org.apache.gravitino.integration.test.util.BaseIT;
8088
import org.apache.gravitino.integration.test.util.GravitinoITUtils;
89+
import org.apache.gravitino.meta.AuditInfo;
8190
import org.apache.gravitino.rel.Column;
8291
import org.apache.gravitino.rel.Table;
8392
import org.apache.gravitino.rel.TableCatalog;
@@ -762,6 +771,71 @@ public void testListTables() {
762771
Assertions.assertEquals(1, tables.length);
763772
}
764773

774+
@Test
775+
public void testFunctions() throws InterruptedException {
776+
// test list functions in a schema which not created by Gravitino
777+
String schemaName1 = GravitinoITUtils.genRandomName(SCHEMA_PREFIX);
778+
hiveClientPool.run(
779+
client -> {
780+
client.createDatabase(
781+
HiveSchema.builder()
782+
.withName(schemaName1)
783+
.withCatalogName(hmsCatalog)
784+
.withAuditInfo(AuditInfo.EMPTY)
785+
.build());
786+
return null;
787+
});
788+
NameIdentifier[] functionIdents =
789+
catalog.asFunctionCatalog().listFunctions(Namespace.of(schemaName1));
790+
Assertions.assertEquals(0, functionIdents.length);
791+
792+
// test register functions in a schema which not created by Gravitino
793+
String schemaName2 = GravitinoITUtils.genRandomName(SCHEMA_PREFIX);
794+
hiveClientPool.run(
795+
client -> {
796+
client.createDatabase(
797+
HiveSchema.builder()
798+
.withName(schemaName2)
799+
.withCatalogName(hmsCatalog)
800+
.withAuditInfo(AuditInfo.EMPTY)
801+
.build());
802+
return null;
803+
});
804+
Function function =
805+
catalog
806+
.asFunctionCatalog()
807+
.registerFunction(
808+
NameIdentifier.of(schemaName2, "test_func"),
809+
"test comment",
810+
FunctionType.SCALAR,
811+
true,
812+
Types.StringType.get(),
813+
FunctionDefinitions.of(
814+
FunctionDefinitions.of(
815+
FunctionParams.of(FunctionParams.of("input", Types.StringType.get())),
816+
FunctionImpls.of(
817+
FunctionImpls.ofJava(
818+
FunctionImpl.RuntimeType.SPARK, "mock.udf.class.name")))));
819+
Assertions.assertEquals("test_func", function.name());
820+
821+
// test alter a non-existing function under a schema which not created by Gravitino
822+
String schemaName3 = GravitinoITUtils.genRandomName(SCHEMA_PREFIX);
823+
NameIdentifier id = NameIdentifier.of(schemaName3, "test_func");
824+
NoSuchFunctionException exception =
825+
assertThrows(
826+
NoSuchFunctionException.class,
827+
() ->
828+
catalog
829+
.asFunctionCatalog()
830+
.alterFunction(id, FunctionChange.updateComment("new comment")));
831+
Assertions.assertTrue(exception.getMessage().contains("does not exist"));
832+
833+
// test drop a non-existing function under a chema which not created by Gravitino
834+
String schemaName4 = GravitinoITUtils.genRandomName(SCHEMA_PREFIX);
835+
NameIdentifier id2 = NameIdentifier.of(schemaName4, "test_func");
836+
Assertions.assertFalse(catalog.asFunctionCatalog().dropFunction(id2));
837+
}
838+
765839
@Test
766840
public void testHiveSchemaProperties() throws TException, InterruptedException {
767841
Assumptions.assumeTrue(enableSparkTest);

catalogs/hive-metastore-common/src/main/java/org/apache/gravitino/hive/converter/HiveDatabaseConverter.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public static HiveSchema fromHiveDB(Database db) {
5858
.build();
5959
return hiveSchema;
6060
}
61+
6162
/**
6263
* Add a comment on lines L57 to L65Add diff commentMarkdown input: edit mode
6364
* selected.WritePreviewHeadingBoldItalicQuoteCodeLinkUnordered listNumbered listTask
@@ -78,14 +79,17 @@ public static Database toHiveDb(HiveSchema hiveSchema) {
7879
Database hiveDb = new Database();
7980

8081
hiveDb.setName(hiveSchema.name());
81-
Optional.ofNullable(hiveSchema.properties().get(LOCATION)).ifPresent(hiveDb::setLocationUri);
82+
Optional.ofNullable(hiveSchema.properties())
83+
.map(props -> props.get(LOCATION))
84+
.ifPresent(hiveDb::setLocationUri);
8285
Optional.ofNullable(hiveSchema.comment()).ifPresent(hiveDb::setDescription);
8386

8487
// TODO: Add more privilege info to Hive's Database object after Gravitino supports privilege.
8588
hiveDb.setOwnerName(hiveSchema.auditInfo().creator());
8689
hiveDb.setOwnerType(PrincipalType.USER);
8790

88-
Map<String, String> parameters = new HashMap<>(hiveSchema.properties());
91+
Map<String, String> parameters =
92+
Optional.ofNullable(hiveSchema.properties()).map(HashMap::new).orElseGet(HashMap::new);
8993
parameters.remove(LOCATION);
9094
hiveDb.setParameters(parameters);
9195

clients/client-java/src/main/java/org/apache/gravitino/client/BaseSchemaCatalog.java

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@
4646
import org.apache.gravitino.exceptions.NonEmptySchemaException;
4747
import org.apache.gravitino.exceptions.PolicyAlreadyAssociatedException;
4848
import org.apache.gravitino.exceptions.SchemaAlreadyExistsException;
49+
import org.apache.gravitino.function.Function;
50+
import org.apache.gravitino.function.FunctionCatalog;
51+
import org.apache.gravitino.function.FunctionChange;
52+
import org.apache.gravitino.function.FunctionColumn;
53+
import org.apache.gravitino.function.FunctionDefinition;
54+
import org.apache.gravitino.function.FunctionType;
4955
import org.apache.gravitino.policy.Policy;
5056
import org.apache.gravitino.policy.SupportsPolicies;
5157
import org.apache.gravitino.rest.RESTUtils;
@@ -58,7 +64,12 @@
5864
* create, load, alter and drop a schema with specified identifier.
5965
*/
6066
abstract class BaseSchemaCatalog extends CatalogDTO
61-
implements Catalog, SupportsSchemas, SupportsTags, SupportsRoles, SupportsPolicies {
67+
implements Catalog,
68+
SupportsSchemas,
69+
SupportsTags,
70+
SupportsRoles,
71+
SupportsPolicies,
72+
FunctionCatalog {
6273

6374
/** The REST client to send the requests. */
6475
protected final RESTClient restClient;
@@ -70,6 +81,7 @@ abstract class BaseSchemaCatalog extends CatalogDTO
7081
private final MetadataObjectPolicyOperations objectPolicyOperations;
7182
private final MetadataObjectRoleOperations objectRoleOperations;
7283
protected final MetadataObjectCredentialOperations objectCredentialOperations;
84+
private final FunctionCatalogOperations functionOperations;
7385

7486
BaseSchemaCatalog(
7587
Namespace catalogNamespace,
@@ -100,6 +112,8 @@ abstract class BaseSchemaCatalog extends CatalogDTO
100112
this.objectCredentialOperations =
101113
new MetadataObjectCredentialOperations(
102114
catalogNamespace.level(0), metadataObject, restClient);
115+
this.functionOperations =
116+
new FunctionCatalogOperations(restClient, catalogNamespace, this.name());
103117
}
104118

105119
@Override
@@ -317,4 +331,57 @@ static String formatSchemaRequestPath(Namespace ns) {
317331
.append("/schemas")
318332
.toString();
319333
}
334+
335+
@Override
336+
public FunctionCatalog asFunctionCatalog() {
337+
return this;
338+
}
339+
340+
@Override
341+
public NameIdentifier[] listFunctions(Namespace namespace) {
342+
return functionOperations.listFunctions(namespace);
343+
}
344+
345+
@Override
346+
public Function[] listFunctionInfos(Namespace namespace) throws NoSuchSchemaException {
347+
return functionOperations.listFunctionInfos(namespace);
348+
}
349+
350+
@Override
351+
public Function getFunction(NameIdentifier ident) {
352+
return functionOperations.getFunction(ident);
353+
}
354+
355+
@Override
356+
public Function registerFunction(
357+
NameIdentifier ident,
358+
String comment,
359+
FunctionType functionType,
360+
boolean deterministic,
361+
org.apache.gravitino.rel.types.Type returnType,
362+
FunctionDefinition[] definitions) {
363+
return functionOperations.registerFunction(
364+
ident, comment, functionType, deterministic, returnType, definitions);
365+
}
366+
367+
@Override
368+
public Function registerFunction(
369+
NameIdentifier ident,
370+
String comment,
371+
boolean deterministic,
372+
FunctionColumn[] returnColumns,
373+
FunctionDefinition[] definitions) {
374+
return functionOperations.registerFunction(
375+
ident, comment, deterministic, returnColumns, definitions);
376+
}
377+
378+
@Override
379+
public Function alterFunction(NameIdentifier ident, FunctionChange... changes) {
380+
return functionOperations.alterFunction(ident, changes);
381+
}
382+
383+
@Override
384+
public boolean dropFunction(NameIdentifier ident) {
385+
return functionOperations.dropFunction(ident);
386+
}
320387
}

clients/client-java/src/main/java/org/apache/gravitino/client/DTOConverters.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
import org.apache.gravitino.dto.MetalakeDTO;
3737
import org.apache.gravitino.dto.authorization.PrivilegeDTO;
3838
import org.apache.gravitino.dto.authorization.SecurableObjectDTO;
39+
import org.apache.gravitino.dto.function.FunctionColumnDTO;
40+
import org.apache.gravitino.dto.function.FunctionDefinitionDTO;
41+
import org.apache.gravitino.dto.function.FunctionImplDTO;
42+
import org.apache.gravitino.dto.function.FunctionParamDTO;
3943
import org.apache.gravitino.dto.job.JobTemplateDTO;
4044
import org.apache.gravitino.dto.job.ShellJobTemplateDTO;
4145
import org.apache.gravitino.dto.job.ShellTemplateUpdateDTO;
@@ -44,6 +48,7 @@
4448
import org.apache.gravitino.dto.job.TemplateUpdateDTO;
4549
import org.apache.gravitino.dto.requests.CatalogUpdateRequest;
4650
import org.apache.gravitino.dto.requests.FilesetUpdateRequest;
51+
import org.apache.gravitino.dto.requests.FunctionUpdateRequest;
4752
import org.apache.gravitino.dto.requests.JobTemplateUpdateRequest;
4853
import org.apache.gravitino.dto.requests.MetalakeUpdateRequest;
4954
import org.apache.gravitino.dto.requests.ModelUpdateRequest;
@@ -54,6 +59,10 @@
5459
import org.apache.gravitino.dto.requests.TagUpdateRequest;
5560
import org.apache.gravitino.dto.requests.TopicUpdateRequest;
5661
import org.apache.gravitino.file.FilesetChange;
62+
import org.apache.gravitino.function.FunctionChange;
63+
import org.apache.gravitino.function.FunctionColumn;
64+
import org.apache.gravitino.function.FunctionDefinition;
65+
import org.apache.gravitino.function.FunctionParam;
5766
import org.apache.gravitino.job.JobTemplate;
5867
import org.apache.gravitino.job.JobTemplateChange;
5968
import org.apache.gravitino.job.ShellJobTemplate;
@@ -552,4 +561,61 @@ static TemplateUpdateDTO toTemplateUpdateDTO(JobTemplateChange.TemplateUpdate ch
552561
"Unknown template update type: " + change.getClass().getSimpleName());
553562
}
554563
}
564+
565+
static FunctionUpdateRequest toFunctionUpdateRequest(FunctionChange change) {
566+
if (change instanceof FunctionChange.UpdateComment) {
567+
return new FunctionUpdateRequest.UpdateCommentRequest(
568+
((FunctionChange.UpdateComment) change).newComment());
569+
570+
} else if (change instanceof FunctionChange.AddDefinition) {
571+
FunctionDefinition def = ((FunctionChange.AddDefinition) change).definition();
572+
return new FunctionUpdateRequest.AddDefinitionRequest(
573+
FunctionDefinitionDTO.fromFunctionDefinition(def));
574+
575+
} else if (change instanceof FunctionChange.RemoveDefinition) {
576+
FunctionParam[] params = ((FunctionChange.RemoveDefinition) change).parameters();
577+
return new FunctionUpdateRequest.RemoveDefinitionRequest(toFunctionParamDTOs(params));
578+
579+
} else if (change instanceof FunctionChange.AddImpl) {
580+
FunctionChange.AddImpl addImpl = (FunctionChange.AddImpl) change;
581+
return new FunctionUpdateRequest.AddImplRequest(
582+
toFunctionParamDTOs(addImpl.parameters()),
583+
FunctionImplDTO.fromFunctionImpl(addImpl.implementation()));
584+
585+
} else if (change instanceof FunctionChange.UpdateImpl) {
586+
FunctionChange.UpdateImpl updateImpl = (FunctionChange.UpdateImpl) change;
587+
return new FunctionUpdateRequest.UpdateImplRequest(
588+
toFunctionParamDTOs(updateImpl.parameters()),
589+
updateImpl.runtime().name(),
590+
FunctionImplDTO.fromFunctionImpl(updateImpl.implementation()));
591+
592+
} else if (change instanceof FunctionChange.RemoveImpl) {
593+
FunctionChange.RemoveImpl removeImpl = (FunctionChange.RemoveImpl) change;
594+
return new FunctionUpdateRequest.RemoveImplRequest(
595+
toFunctionParamDTOs(removeImpl.parameters()), removeImpl.runtime().name());
596+
597+
} else {
598+
throw new IllegalArgumentException(
599+
"Unknown function change type: " + change.getClass().getSimpleName());
600+
}
601+
}
602+
603+
static FunctionDefinitionDTO toFunctionDefinitionDTO(FunctionDefinition definition) {
604+
return FunctionDefinitionDTO.fromFunctionDefinition(definition);
605+
}
606+
607+
static FunctionColumnDTO toFunctionColumnDTO(FunctionColumn column) {
608+
return FunctionColumnDTO.fromFunctionColumn(column);
609+
}
610+
611+
private static FunctionParamDTO[] toFunctionParamDTOs(FunctionParam[] params) {
612+
if (params == null) {
613+
return new FunctionParamDTO[0];
614+
}
615+
FunctionParamDTO[] dtos = new FunctionParamDTO[params.length];
616+
for (int i = 0; i < params.length; i++) {
617+
dtos[i] = FunctionParamDTO.fromFunctionParam(params[i]);
618+
}
619+
return dtos;
620+
}
555621
}

0 commit comments

Comments
 (0)