Skip to content

Commit dd1893c

Browse files
abevk2023tdcmeehan
authored andcommitted
Add reference REST function server
1 parent 8041eb5 commit dd1893c

File tree

18 files changed

+1051
-130
lines changed

18 files changed

+1051
-130
lines changed

pom.xml

+1
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@
211211
<module>presto-openapi</module>
212212
<module>presto-native-sidecar-plugin</module>
213213
<module>presto-base-arrow-flight</module>
214+
<module>presto-function-server</module>
214215
</modules>
215216

216217
<dependencyManagement>

presto-function-namespace-managers/src/main/java/com/facebook/presto/functionNamespace/JsonBasedUdfFunctionMetadata.java

+9
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,19 @@ public JsonBasedUdfFunctionMetadata(
9292
this.version = requireNonNull(version, "version is null");
9393
}
9494

95+
@JsonProperty
9596
public String getDocString()
9697
{
9798
return docString;
9899
}
99100

101+
@JsonProperty
100102
public FunctionKind getFunctionKind()
101103
{
102104
return functionKind;
103105
}
104106

107+
@JsonProperty
105108
public TypeSignature getOutputType()
106109
{
107110
return outputType;
@@ -113,31 +116,37 @@ public List<String> getParamNames()
113116
return IntStream.range(0, paramTypes.size()).boxed().map(idx -> "input" + idx).collect(toImmutableList());
114117
}
115118

119+
@JsonProperty
116120
public List<TypeSignature> getParamTypes()
117121
{
118122
return paramTypes;
119123
}
120124

125+
@JsonProperty
121126
public String getSchema()
122127
{
123128
return schema;
124129
}
125130

131+
@JsonProperty
126132
public RoutineCharacteristics getRoutineCharacteristics()
127133
{
128134
return routineCharacteristics;
129135
}
130136

137+
@JsonProperty
131138
public Optional<AggregationFunctionMetadata> getAggregateMetadata()
132139
{
133140
return aggregateMetadata;
134141
}
135142

143+
@JsonProperty
136144
public Optional<SqlFunctionId> getFunctionId()
137145
{
138146
return functionId;
139147
}
140148

149+
@JsonProperty
141150
public Optional<String> getVersion()
142151
{
143152
return version;

presto-function-namespace-managers/src/main/java/com/facebook/presto/functionNamespace/rest/RestBasedFunctionApis.java

+8-19
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.facebook.presto.spi.PrestoException;
2424
import com.google.common.collect.ImmutableMap;
2525
import com.google.inject.Inject;
26+
import com.google.inject.name.Named;
2627

2728
import java.net.URI;
2829
import java.util.List;
@@ -31,33 +32,31 @@
3132
import static com.facebook.airlift.http.client.HttpUriBuilder.uriBuilderFrom;
3233
import static com.facebook.airlift.http.client.JsonResponseHandler.createJsonResponseHandler;
3334
import static com.facebook.airlift.http.client.StatusResponseHandler.createStatusResponseHandler;
35+
import static com.facebook.presto.functionNamespace.rest.RestErrorCode.REST_SERVER_FUNCTION_FETCH_ERROR;
3436
import static com.facebook.presto.spi.StandardErrorCode.NOT_SUPPORTED;
3537
import static java.util.Objects.requireNonNull;
3638

3739
public class RestBasedFunctionApis
3840
{
3941
public static final String ALL_FUNCTIONS_ENDPOINT = "/v1/functions";
40-
4142
private final HttpClient httpClient;
42-
4343
private final JsonCodec<Map<String, List<JsonBasedUdfFunctionMetadata>>> functionSignatureMapJsonCodec;
44-
45-
private final RestBasedFunctionNamespaceManagerConfig managerConfig;
44+
private final String restUrl;
4645

4746
@Inject
4847
public RestBasedFunctionApis(
4948
JsonCodec<Map<String, List<JsonBasedUdfFunctionMetadata>>> nativeFunctionSignatureMapJsonCodec,
5049
@ForRestServer HttpClient httpClient,
51-
RestBasedFunctionNamespaceManagerConfig managerConfig)
50+
@Named("restUrl") String restUrl)
5251
{
5352
this.functionSignatureMapJsonCodec = requireNonNull(nativeFunctionSignatureMapJsonCodec, "nativeFunctionSignatureMapJsonCodec is null");
5453
this.httpClient = requireNonNull(httpClient, "httpClient is null");
55-
this.managerConfig = requireNonNull(managerConfig, "httpClient is null");
54+
this.restUrl = requireNonNull(restUrl, "restUrl is null");
5655
}
5756

5857
public String getFunctionsETag()
5958
{
60-
URI uri = uriBuilderFrom(URI.create(managerConfig.getRestUrl()))
59+
URI uri = uriBuilderFrom(URI.create(restUrl))
6160
.appendPath(ALL_FUNCTIONS_ENDPOINT)
6261
.build();
6362
Request request = Request.builder()
@@ -89,21 +88,11 @@ public String addFunction(String schema, String functionName, JsonBasedUdfFuncti
8988
throw new PrestoException(NOT_SUPPORTED, "Add Function is yet to be added");
9089
}
9190

92-
public String updateFunction(String schema, String functionName, String functionId, JsonBasedUdfFunctionMetadata metadata)
93-
{
94-
throw new PrestoException(NOT_SUPPORTED, "Update Function is yet to be added");
95-
}
96-
97-
public String deleteFunction(String schema, String functionName, String functionId)
98-
{
99-
throw new PrestoException(NOT_SUPPORTED, "Delete Function is yet to be added");
100-
}
101-
10291
private UdfFunctionSignatureMap getFunctionsAt(String endpoint)
10392
throws IllegalStateException
10493
{
10594
try {
106-
URI uri = uriBuilderFrom(URI.create(managerConfig.getRestUrl()))
95+
URI uri = uriBuilderFrom(URI.create(restUrl))
10796
.appendPath(endpoint)
10897
.build();
10998
Request request = Request.builder()
@@ -115,7 +104,7 @@ private UdfFunctionSignatureMap getFunctionsAt(String endpoint)
115104
return new UdfFunctionSignatureMap(ImmutableMap.copyOf(nativeFunctionSignatureMap));
116105
}
117106
catch (Exception e) {
118-
throw new IllegalStateException("Failed to get function definitions from REST server, " + e.getMessage());
107+
throw new PrestoException(REST_SERVER_FUNCTION_FETCH_ERROR, "Failed to fetch function definitions from REST server: " + e.getMessage(), e);
119108
}
120109
}
121110
}

presto-function-namespace-managers/src/main/java/com/facebook/presto/functionNamespace/rest/RestBasedFunctionNamespaceManager.java

+17-14
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,12 @@
4545

4646
import java.util.ArrayList;
4747
import java.util.Collection;
48-
import java.util.Collections;
4948
import java.util.List;
5049
import java.util.Map;
5150
import java.util.Optional;
5251
import java.util.concurrent.atomic.AtomicReference;
5352

5453
import static com.facebook.presto.spi.StandardErrorCode.NOT_SUPPORTED;
55-
import static com.facebook.presto.spi.function.RoutineCharacteristics.Language.REST;
56-
import static com.google.common.base.Preconditions.checkState;
5754
import static com.google.common.collect.ImmutableList.toImmutableList;
5855
import static java.util.Collections.emptyList;
5956
import static java.util.Objects.requireNonNull;
@@ -99,7 +96,8 @@ private List<SqlInvokedFunction> getLatestFunctions()
9996
return ImmutableList.of();
10097
}
10198

102-
createSqlInvokedFunctions(udfFunctionSignatureMap, latestFunctions);
99+
List<SqlInvokedFunction> newFunctions = createSqlInvokedFunctions(udfFunctionSignatureMap);
100+
latestFunctions.addAll(newFunctions);
103101

104102
if (newETag != null) {
105103
cachedETag.set(Optional.of(newETag));
@@ -108,18 +106,17 @@ private List<SqlInvokedFunction> getLatestFunctions()
108106
return latestFunctions;
109107
}
110108

111-
private void createSqlInvokedFunctions(UdfFunctionSignatureMap udfFunctionSignatureMap, List<SqlInvokedFunction> functionList)
109+
private List<SqlInvokedFunction> createSqlInvokedFunctions(UdfFunctionSignatureMap udfFunctionSignatureMap)
112110
{
113111
Map<String, List<JsonBasedUdfFunctionMetadata>> udfSignatureMap = udfFunctionSignatureMap.getUDFSignatureMap();
114-
udfSignatureMap.forEach((name, metaInfoList) -> {
115-
List<SqlInvokedFunction> functions = metaInfoList.stream().map(metaInfo -> createSqlInvokedFunction(name, metaInfo)).collect(toImmutableList());
116-
functionList.addAll(functions);
117-
});
112+
return udfSignatureMap.entrySet().stream()
113+
.flatMap(entry -> entry.getValue().stream()
114+
.map(metaInfo -> createSqlInvokedFunction(entry.getKey(), metaInfo)))
115+
.collect(toImmutableList());
118116
}
119117

120118
private SqlInvokedFunction createSqlInvokedFunction(String functionName, JsonBasedUdfFunctionMetadata jsonBasedUdfFunctionMetaData)
121119
{
122-
checkState(jsonBasedUdfFunctionMetaData.getRoutineCharacteristics().getLanguage().equals(REST), "RestBasedFunctionNamespaceManager only supports REST UDF");
123120
QualifiedObjectName qualifiedFunctionName = QualifiedObjectName.valueOf(new CatalogSchemaName(getCatalogName(), jsonBasedUdfFunctionMetaData.getSchema()), functionName);
124121
List<String> parameterNameList = jsonBasedUdfFunctionMetaData.getParamNames();
125122
List<TypeSignature> parameterTypeList = jsonBasedUdfFunctionMetaData.getParamTypes();
@@ -130,7 +127,14 @@ private SqlInvokedFunction createSqlInvokedFunction(String functionName, JsonBas
130127
}
131128

132129
FunctionVersion functionVersion = new FunctionVersion(jsonBasedUdfFunctionMetaData.getVersion());
133-
SqlFunctionId functionId = jsonBasedUdfFunctionMetaData.getFunctionId().isPresent() ? jsonBasedUdfFunctionMetaData.getFunctionId().get() : null;
130+
SqlFunctionId functionId = jsonBasedUdfFunctionMetaData.getFunctionId().orElse(null);
131+
// The function server may return a functionId with a different catalog name. We need to update the catalog name to the current catalog name.
132+
functionId = new SqlFunctionId(
133+
new QualifiedObjectName(
134+
getCatalogName(),
135+
functionId.getFunctionName().getSchemaName(),
136+
functionId.getFunctionName().getObjectName()),
137+
functionId.getArgumentTypes());
134138
return new SqlInvokedFunction(
135139
qualifiedFunctionName,
136140
parameterBuilder.build(),
@@ -158,11 +162,10 @@ protected Collection<SqlInvokedFunction> fetchFunctionsDirect(QualifiedObjectNam
158162
{
159163
UdfFunctionSignatureMap udfFunctionSignatureMap = restApis.getFunctions(functionName.getSchemaName(), functionName.getObjectName());
160164
if (udfFunctionSignatureMap == null || udfFunctionSignatureMap.isEmpty()) {
161-
return Collections.emptyList();
165+
return ImmutableList.of();
162166
}
163167

164-
List<SqlInvokedFunction> functions = new ArrayList<>();
165-
createSqlInvokedFunctions(udfFunctionSignatureMap, functions);
168+
List<SqlInvokedFunction> functions = createSqlInvokedFunctions(udfFunctionSignatureMap);
166169
return functions;
167170
}
168171

presto-function-namespace-managers/src/main/java/com/facebook/presto/functionNamespace/rest/RestBasedFunctionNamespaceManagerFactory.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
import com.facebook.airlift.bootstrap.Bootstrap;
1717
import com.facebook.presto.functionNamespace.FunctionNamespaceManagerPlugin;
18-
import com.facebook.presto.functionNamespace.execution.NoopSqlFunctionExecutorsModule;
1918
import com.facebook.presto.spi.function.FunctionHandleResolver;
2019
import com.facebook.presto.spi.function.FunctionNamespaceManager;
2120
import com.facebook.presto.spi.function.FunctionNamespaceManagerContext;
@@ -57,7 +56,7 @@ public FunctionNamespaceManager<?> create(String catalogName, Map<String, String
5756
Bootstrap app = new Bootstrap(
5857
new RestBasedCommunicationModule(),
5958
new RestBasedFunctionNamespaceManagerModule(catalogName),
60-
new NoopSqlFunctionExecutorsModule());
59+
new RestSqlFunctionExecutorsModule());
6160

6261
Injector injector = app
6362
.doNotInitializeLogging()

presto-function-namespace-managers/src/main/java/com/facebook/presto/functionNamespace/rest/RestBasedFunctionNamespaceManagerModule.java

+9
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
import com.facebook.presto.functionNamespace.execution.SqlFunctionLanguageConfig;
2121
import com.google.inject.Binder;
2222
import com.google.inject.Module;
23+
import com.google.inject.Provides;
2324
import com.google.inject.TypeLiteral;
25+
import com.google.inject.name.Named;
2426

2527
import java.util.List;
2628
import java.util.Map;
@@ -52,4 +54,11 @@ public void configure(Binder binder)
5254
binder.bind(new TypeLiteral<JsonCodec<Map<String, List<JsonBasedUdfFunctionMetadata>>>>() {})
5355
.toInstance(new JsonCodecFactory().mapJsonCodec(String.class, listJsonCodec(JsonBasedUdfFunctionMetadata.class)));
5456
}
57+
58+
@Provides
59+
@Named("restUrl")
60+
public String provideRestUrl(RestBasedFunctionNamespaceManagerConfig config)
61+
{
62+
return config.getRestUrl();
63+
}
5564
}

presto-function-namespace-managers/src/main/java/com/facebook/presto/functionNamespace/rest/RestComminicationModule.java

-30
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package com.facebook.presto.functionNamespace.rest;
15+
16+
import com.facebook.presto.common.ErrorCode;
17+
import com.facebook.presto.common.ErrorType;
18+
import com.facebook.presto.spi.ErrorCodeSupplier;
19+
20+
import static com.facebook.presto.common.ErrorType.EXTERNAL;
21+
22+
public enum RestErrorCode
23+
implements ErrorCodeSupplier
24+
{
25+
REST_SERVER_NOT_FOUND(0, EXTERNAL),
26+
REST_SERVER_ERROR(1, EXTERNAL),
27+
REST_SERVER_TIMEOUT(2, EXTERNAL),
28+
REST_SERVER_CONNECT_ERROR(3, EXTERNAL),
29+
REST_SERVER_BAD_RESPONSE(4, EXTERNAL),
30+
REST_SERVER_IO_ERROR(5, EXTERNAL),
31+
REST_SERVER_FUNCTION_FETCH_ERROR(6, EXTERNAL);
32+
33+
private final ErrorCode errorCode;
34+
35+
public static final int ERROR_CODE_MASK = 0x0002_1000;
36+
37+
RestErrorCode(int code, ErrorType type)
38+
{
39+
errorCode = new ErrorCode(code + ERROR_CODE_MASK, name(), type);
40+
}
41+
42+
@Override
43+
public ErrorCode toErrorCode()
44+
{
45+
return errorCode;
46+
}
47+
}

0 commit comments

Comments
 (0)