Skip to content

Commit ae87c94

Browse files
committed
java client supports udf ops and add ITs
1 parent cf12d2e commit ae87c94

File tree

8 files changed

+1660
-3
lines changed

8 files changed

+1660
-3
lines changed

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

Lines changed: 66 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;
@@ -754,6 +763,63 @@ public void testListTables() {
754763
Assertions.assertEquals(1, tables.length);
755764
}
756765

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

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: 73 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,62 @@ 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 getFunction(NameIdentifier ident, int version) {
357+
return functionOperations.getFunction(ident, version);
358+
}
359+
360+
@Override
361+
public Function registerFunction(
362+
NameIdentifier ident,
363+
String comment,
364+
FunctionType functionType,
365+
boolean deterministic,
366+
org.apache.gravitino.rel.types.Type returnType,
367+
FunctionDefinition[] definitions) {
368+
return functionOperations.registerFunction(
369+
ident, comment, functionType, deterministic, returnType, definitions);
370+
}
371+
372+
@Override
373+
public Function registerFunction(
374+
NameIdentifier ident,
375+
String comment,
376+
boolean deterministic,
377+
FunctionColumn[] returnColumns,
378+
FunctionDefinition[] definitions) {
379+
return functionOperations.registerFunction(
380+
ident, comment, deterministic, returnColumns, definitions);
381+
}
382+
383+
@Override
384+
public Function alterFunction(NameIdentifier ident, FunctionChange... changes) {
385+
return functionOperations.alterFunction(ident, changes);
386+
}
387+
388+
@Override
389+
public boolean dropFunction(NameIdentifier ident) {
390+
return functionOperations.dropFunction(ident);
391+
}
320392
}

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)