From 4f374ff64c9c0f5dd331474a3206cfbb4c1f36cf Mon Sep 17 00:00:00 2001 From: Tsotne Tabidze Date: Fri, 14 Jan 2022 09:33:06 -0800 Subject: [PATCH 1/4] replace GetOnlineFeaturesResponse with GetOnlineFeaturesResponseV2 in Python Signed-off-by: Tsotne Tabidze --- go.mod | 4 +- go.sum | 7 + .../src/main/java/dev/feast/FeastClient.java | 4 +- .../test/java/dev/feast/FeastClientTest.java | 14 +- .../ServingServiceGRpcController.java | 4 +- .../ServingServiceRestController.java | 2 +- .../grpc/OnlineServingGrpcServiceV2.java | 2 +- .../service/OnlineServingServiceV2.java | 12 +- .../service/OnlineTransformationService.java | 4 +- .../serving/service/ServingServiceV2.java | 6 +- .../service/TransformationService.java | 4 +- .../util/mappers/ResponseJSONMapper.java | 4 +- .../feast/serving/it/ServingBaseTests.java | 6 +- .../service/OnlineServingServiceTest.java | 32 +- protos/feast/serving/ServingService.proto | 15 +- sdk/go/client_test.go | 4 +- sdk/go/mocks/serving_mock.go | 4 +- .../protos/feast/serving/ServingService.pb.go | 415 ++++++------------ sdk/go/request.go | 10 +- sdk/go/request_test.go | 4 +- sdk/go/response.go | 2 +- sdk/go/response_test.go | 4 +- sdk/python/feast/feature_store.py | 196 +++++---- sdk/python/feast/online_response.py | 39 +- sdk/python/tests/unit/test_proto_json.py | 84 ++-- 25 files changed, 361 insertions(+), 521 deletions(-) diff --git a/go.mod b/go.mod index f4a1455056..109666b762 100644 --- a/go.mod +++ b/go.mod @@ -25,8 +25,8 @@ require ( go.opencensus.io v0.22.3 // indirect golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d - golang.org/x/tools v0.1.7 // indirect + golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f + golang.org/x/tools v0.1.8 // indirect google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect google.golang.org/grpc v1.29.1 google.golang.org/protobuf v1.27.1 // indirect diff --git a/go.sum b/go.sum index 5e87ccf6db..8b0c2677f3 100644 --- a/go.sum +++ b/go.sum @@ -345,6 +345,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -386,6 +387,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d h1:g9qWBGx4puODJTMVyoPrpoxPFgVGd+z1DZwjfRu4d0I= @@ -415,6 +417,7 @@ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -454,6 +457,7 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= @@ -464,6 +468,7 @@ golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -525,6 +530,8 @@ golang.org/x/tools v0.0.0-20201124005743-911501bfb504 h1:jOKV2ysikH1GANB7t2Lotmh golang.org/x/tools v0.0.0-20201124005743-911501bfb504/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w= +golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= diff --git a/java/sdk/java/src/main/java/dev/feast/FeastClient.java b/java/sdk/java/src/main/java/dev/feast/FeastClient.java index e9aaab151a..c10a76ecf8 100644 --- a/java/sdk/java/src/main/java/dev/feast/FeastClient.java +++ b/java/sdk/java/src/main/java/dev/feast/FeastClient.java @@ -21,7 +21,7 @@ import feast.proto.serving.ServingAPIProto.GetFeastServingInfoRequest; import feast.proto.serving.ServingAPIProto.GetFeastServingInfoResponse; import feast.proto.serving.ServingAPIProto.GetOnlineFeaturesRequest; -import feast.proto.serving.ServingAPIProto.GetOnlineFeaturesResponseV2; +import feast.proto.serving.ServingAPIProto.GetOnlineFeaturesResponse; import feast.proto.serving.ServingServiceGrpc; import feast.proto.serving.ServingServiceGrpc.ServingServiceBlockingStub; import feast.proto.types.ValueProto; @@ -129,7 +129,7 @@ public List getOnlineFeatures(List featureRefs, List entities) requestBuilder.putAllEntities(getEntityValuesMap(entities)); - GetOnlineFeaturesResponseV2 response = stub.getOnlineFeatures(requestBuilder.build()); + GetOnlineFeaturesResponse response = stub.getOnlineFeatures(requestBuilder.build()); List results = Lists.newArrayList(); if (response.getResultsCount() == 0) { diff --git a/java/sdk/java/src/test/java/dev/feast/FeastClientTest.java b/java/sdk/java/src/test/java/dev/feast/FeastClientTest.java index 3de5142a85..1dfb9989c9 100644 --- a/java/sdk/java/src/test/java/dev/feast/FeastClientTest.java +++ b/java/sdk/java/src/test/java/dev/feast/FeastClientTest.java @@ -24,7 +24,7 @@ import feast.proto.serving.ServingAPIProto; import feast.proto.serving.ServingAPIProto.FieldStatus; import feast.proto.serving.ServingAPIProto.GetOnlineFeaturesRequest; -import feast.proto.serving.ServingAPIProto.GetOnlineFeaturesResponseV2; +import feast.proto.serving.ServingAPIProto.GetOnlineFeaturesResponse; import feast.proto.serving.ServingServiceGrpc.ServingServiceImplBase; import feast.proto.types.ValueProto; import feast.proto.types.ValueProto.Value; @@ -57,7 +57,7 @@ public class FeastClientTest { @Override public void getOnlineFeatures( GetOnlineFeaturesRequest request, - StreamObserver responseObserver) { + StreamObserver responseObserver) { if (!request.equals(FeastClientTest.getFakeRequest())) { responseObserver.onError(Status.FAILED_PRECONDITION.asRuntimeException()); } @@ -137,22 +137,22 @@ private static GetOnlineFeaturesRequest getFakeRequest() { .build(); } - private static GetOnlineFeaturesResponseV2 getFakeResponse() { - return GetOnlineFeaturesResponseV2.newBuilder() + private static GetOnlineFeaturesResponse getFakeResponse() { + return GetOnlineFeaturesResponse.newBuilder() .addResults( - GetOnlineFeaturesResponseV2.FeatureVector.newBuilder() + GetOnlineFeaturesResponse.FeatureVector.newBuilder() .addValues(strValue("david")) .addStatuses(FieldStatus.PRESENT) .addEventTimestamps(Timestamp.newBuilder()) .build()) .addResults( - GetOnlineFeaturesResponseV2.FeatureVector.newBuilder() + GetOnlineFeaturesResponse.FeatureVector.newBuilder() .addValues(intValue(3)) .addStatuses(FieldStatus.PRESENT) .addEventTimestamps(Timestamp.newBuilder()) .build()) .addResults( - GetOnlineFeaturesResponseV2.FeatureVector.newBuilder() + GetOnlineFeaturesResponse.FeatureVector.newBuilder() .addValues(Value.newBuilder().build()) .addStatuses(FieldStatus.NULL_VALUE) .addEventTimestamps(Timestamp.newBuilder()) diff --git a/java/serving/src/main/java/feast/serving/controller/ServingServiceGRpcController.java b/java/serving/src/main/java/feast/serving/controller/ServingServiceGRpcController.java index 0f4ef7b5ae..bc6af8ecce 100644 --- a/java/serving/src/main/java/feast/serving/controller/ServingServiceGRpcController.java +++ b/java/serving/src/main/java/feast/serving/controller/ServingServiceGRpcController.java @@ -60,12 +60,12 @@ public void getFeastServingInfo( @Override public void getOnlineFeatures( ServingAPIProto.GetOnlineFeaturesRequest request, - StreamObserver responseObserver) { + StreamObserver responseObserver) { try { // authorize for the project in request object. RequestHelper.validateOnlineRequest(request); Span span = tracer.buildSpan("getOnlineFeaturesV2").start(); - ServingAPIProto.GetOnlineFeaturesResponseV2 onlineFeatures = + ServingAPIProto.GetOnlineFeaturesResponse onlineFeatures = servingServiceV2.getOnlineFeatures(request); if (span != null) { span.finish(); diff --git a/java/serving/src/main/java/feast/serving/controller/ServingServiceRestController.java b/java/serving/src/main/java/feast/serving/controller/ServingServiceRestController.java index fe8f13d8bc..1983f3ebce 100644 --- a/java/serving/src/main/java/feast/serving/controller/ServingServiceRestController.java +++ b/java/serving/src/main/java/feast/serving/controller/ServingServiceRestController.java @@ -54,7 +54,7 @@ public GetFeastServingInfoResponse getInfo() { public List> getOnlineFeatures( @RequestBody ServingAPIProto.GetOnlineFeaturesRequest request) { RequestHelper.validateOnlineRequest(request); - ServingAPIProto.GetOnlineFeaturesResponseV2 onlineFeatures = + ServingAPIProto.GetOnlineFeaturesResponse onlineFeatures = servingService.getOnlineFeatures(request); return mapGetOnlineFeaturesResponse(onlineFeatures); } diff --git a/java/serving/src/main/java/feast/serving/grpc/OnlineServingGrpcServiceV2.java b/java/serving/src/main/java/feast/serving/grpc/OnlineServingGrpcServiceV2.java index f3a35d1d0f..8d82a1f182 100644 --- a/java/serving/src/main/java/feast/serving/grpc/OnlineServingGrpcServiceV2.java +++ b/java/serving/src/main/java/feast/serving/grpc/OnlineServingGrpcServiceV2.java @@ -41,7 +41,7 @@ public void getFeastServingInfo( @Override public void getOnlineFeatures( ServingAPIProto.GetOnlineFeaturesRequest request, - StreamObserver responseObserver) { + StreamObserver responseObserver) { responseObserver.onNext(this.servingServiceV2.getOnlineFeatures(request)); responseObserver.onCompleted(); } diff --git a/java/serving/src/main/java/feast/serving/service/OnlineServingServiceV2.java b/java/serving/src/main/java/feast/serving/service/OnlineServingServiceV2.java index 5774dc361a..3e62d4db75 100644 --- a/java/serving/src/main/java/feast/serving/service/OnlineServingServiceV2.java +++ b/java/serving/src/main/java/feast/serving/service/OnlineServingServiceV2.java @@ -72,7 +72,7 @@ public GetFeastServingInfoResponse getFeastServingInfo( } @Override - public ServingAPIProto.GetOnlineFeaturesResponseV2 getOnlineFeatures( + public ServingAPIProto.GetOnlineFeaturesResponse getOnlineFeatures( ServingAPIProto.GetOnlineFeaturesRequest request) { // Split all feature references into non-ODFV (e.g. batch and stream) references and ODFV. List allFeatureReferences = getFeaturesList(request); @@ -132,8 +132,8 @@ public ServingAPIProto.GetOnlineFeaturesResponseV2 getOnlineFeatures( Span postProcessingSpan = tracer.buildSpan("postProcessing").start(); - ServingAPIProto.GetOnlineFeaturesResponseV2.Builder responseBuilder = - ServingAPIProto.GetOnlineFeaturesResponseV2.newBuilder(); + ServingAPIProto.GetOnlineFeaturesResponse.Builder responseBuilder = + ServingAPIProto.GetOnlineFeaturesResponse.newBuilder(); Timestamp now = Timestamp.newBuilder().setSeconds(System.currentTimeMillis() / 1000).build(); Timestamp nullTimestamp = Timestamp.newBuilder().build(); @@ -147,7 +147,7 @@ public ServingAPIProto.GetOnlineFeaturesResponseV2 getOnlineFeatures( Duration maxAge = this.registryRepository.getMaxAge(featureReference); - ServingAPIProto.GetOnlineFeaturesResponseV2.FeatureVector.Builder vectorBuilder = + ServingAPIProto.GetOnlineFeaturesResponse.FeatureVector.Builder vectorBuilder = responseBuilder.addResultsBuilder(); for (int rowIdx = 0; rowIdx < features.size(); rowIdx++) { @@ -262,7 +262,7 @@ private void populateOnDemandFeatures( List retrievedFeatureReferences, ServingAPIProto.GetOnlineFeaturesRequest request, List> features, - ServingAPIProto.GetOnlineFeaturesResponseV2.Builder responseBuilder) { + ServingAPIProto.GetOnlineFeaturesResponse.Builder responseBuilder) { List>> onDemandContext = request.getRequestContextMap().entrySet().stream() @@ -383,7 +383,7 @@ private void populateHistogramMetrics( */ private void populateCountMetrics( FeatureReferenceV2 featureRef, - ServingAPIProto.GetOnlineFeaturesResponseV2.FeatureVectorOrBuilder featureVector) { + ServingAPIProto.GetOnlineFeaturesResponse.FeatureVectorOrBuilder featureVector) { String featureRefString = Feature.getFeatureReference(featureRef); featureVector .getStatusesList() diff --git a/java/serving/src/main/java/feast/serving/service/OnlineTransformationService.java b/java/serving/src/main/java/feast/serving/service/OnlineTransformationService.java index bfe717aa96..a535eacb9e 100644 --- a/java/serving/src/main/java/feast/serving/service/OnlineTransformationService.java +++ b/java/serving/src/main/java/feast/serving/service/OnlineTransformationService.java @@ -189,7 +189,7 @@ public void processTransformFeaturesResponse( transformFeaturesResponse, String onDemandFeatureViewName, Set onDemandFeatureStringReferences, - ServingAPIProto.GetOnlineFeaturesResponseV2.Builder responseBuilder) { + ServingAPIProto.GetOnlineFeaturesResponse.Builder responseBuilder) { try { BufferAllocator allocator = new RootAllocator(Long.MAX_VALUE); ArrowFileReader reader = @@ -219,7 +219,7 @@ public void processTransformFeaturesResponse( FieldVector fieldVector = readBatch.getVector(field); int valueCount = fieldVector.getValueCount(); - ServingAPIProto.GetOnlineFeaturesResponseV2.FeatureVector.Builder vectorBuilder = + ServingAPIProto.GetOnlineFeaturesResponse.FeatureVector.Builder vectorBuilder = responseBuilder.addResultsBuilder(); List valueList = Lists.newArrayListWithExpectedSize(valueCount); diff --git a/java/serving/src/main/java/feast/serving/service/ServingServiceV2.java b/java/serving/src/main/java/feast/serving/service/ServingServiceV2.java index 096b155a0e..4a44f4e09e 100644 --- a/java/serving/src/main/java/feast/serving/service/ServingServiceV2.java +++ b/java/serving/src/main/java/feast/serving/service/ServingServiceV2.java @@ -40,9 +40,9 @@ ServingAPIProto.GetFeastServingInfoResponse getFeastServingInfo( * *

This request is fulfilled synchronously. * - * @return {@link feast.proto.serving.ServingAPIProto.GetOnlineFeaturesResponseV2} with list of - * {@link feast.proto.serving.ServingAPIProto.GetOnlineFeaturesResponseV2.FeatureVector}. + * @return {@link feast.proto.serving.ServingAPIProto.GetOnlineFeaturesResponse} with list of + * {@link feast.proto.serving.ServingAPIProto.GetOnlineFeaturesResponse.FeatureVector}. */ - ServingAPIProto.GetOnlineFeaturesResponseV2 getOnlineFeatures( + ServingAPIProto.GetOnlineFeaturesResponse getOnlineFeatures( ServingAPIProto.GetOnlineFeaturesRequest getFeaturesRequest); } diff --git a/java/serving/src/main/java/feast/serving/service/TransformationService.java b/java/serving/src/main/java/feast/serving/service/TransformationService.java index 36cce43e0d..e47e847f9e 100644 --- a/java/serving/src/main/java/feast/serving/service/TransformationService.java +++ b/java/serving/src/main/java/feast/serving/service/TransformationService.java @@ -66,13 +66,13 @@ public interface TransformationService { * @param transformFeaturesResponse response to be processed * @param onDemandFeatureViewName name of ODFV to which the response corresponds * @param onDemandFeatureStringReferences set of all ODFV references that should be kept - * @param responseBuilder {@link ServingAPIProto.GetOnlineFeaturesResponseV2.Builder} + * @param responseBuilder {@link ServingAPIProto.GetOnlineFeaturesResponse.Builder} */ void processTransformFeaturesResponse( TransformFeaturesResponse transformFeaturesResponse, String onDemandFeatureViewName, Set onDemandFeatureStringReferences, - ServingAPIProto.GetOnlineFeaturesResponseV2.Builder responseBuilder); + ServingAPIProto.GetOnlineFeaturesResponse.Builder responseBuilder); /** * Serialize data into Arrow IPC format, to be sent to the Python feature transformation server. diff --git a/java/serving/src/main/java/feast/serving/util/mappers/ResponseJSONMapper.java b/java/serving/src/main/java/feast/serving/util/mappers/ResponseJSONMapper.java index 1e82bf864c..3ab9f43c34 100644 --- a/java/serving/src/main/java/feast/serving/util/mappers/ResponseJSONMapper.java +++ b/java/serving/src/main/java/feast/serving/util/mappers/ResponseJSONMapper.java @@ -26,14 +26,14 @@ public class ResponseJSONMapper { public static List> mapGetOnlineFeaturesResponse( - ServingAPIProto.GetOnlineFeaturesResponseV2 response) { + ServingAPIProto.GetOnlineFeaturesResponse response) { return response.getResultsList().stream() .map(fieldValues -> convertFieldValuesToMap(fieldValues)) .collect(Collectors.toList()); } private static Map convertFieldValuesToMap( - ServingAPIProto.GetOnlineFeaturesResponseV2.FeatureVector vec) { + ServingAPIProto.GetOnlineFeaturesResponse.FeatureVector vec) { return Map.of( "values", vec.getValuesList().stream() diff --git a/java/serving/src/test/java/feast/serving/it/ServingBaseTests.java b/java/serving/src/test/java/feast/serving/it/ServingBaseTests.java index 4d4272324e..cd732ce1dd 100644 --- a/java/serving/src/test/java/feast/serving/it/ServingBaseTests.java +++ b/java/serving/src/test/java/feast/serving/it/ServingBaseTests.java @@ -74,7 +74,7 @@ private static RegistryProto.Registry readLocalRegistry() { @Test public void shouldGetOnlineFeatures() { - ServingAPIProto.GetOnlineFeaturesResponseV2 featureResponse = + ServingAPIProto.GetOnlineFeaturesResponse featureResponse = servingStub.getOnlineFeatures(buildOnlineRequest(1005)); assertEquals(2, featureResponse.getResultsCount()); @@ -96,7 +96,7 @@ public void shouldGetOnlineFeatures() { @Test public void shouldGetOnlineFeaturesWithOutsideMaxAgeStatus() { - ServingAPIProto.GetOnlineFeaturesResponseV2 featureResponse = + ServingAPIProto.GetOnlineFeaturesResponse featureResponse = servingStub.getOnlineFeatures(buildOnlineRequest(1001)); assertEquals(2, featureResponse.getResultsCount()); @@ -113,7 +113,7 @@ public void shouldGetOnlineFeaturesWithOutsideMaxAgeStatus() { @Test public void shouldGetOnlineFeaturesWithNotFoundStatus() { - ServingAPIProto.GetOnlineFeaturesResponseV2 featureResponse = + ServingAPIProto.GetOnlineFeaturesResponse featureResponse = servingStub.getOnlineFeatures(buildOnlineRequest(-1)); assertEquals(2, featureResponse.getResultsCount()); diff --git a/java/serving/src/test/java/feast/serving/service/OnlineServingServiceTest.java b/java/serving/src/test/java/feast/serving/service/OnlineServingServiceTest.java index 4234e9dce3..64d2e20c9b 100644 --- a/java/serving/src/test/java/feast/serving/service/OnlineServingServiceTest.java +++ b/java/serving/src/test/java/feast/serving/service/OnlineServingServiceTest.java @@ -30,7 +30,7 @@ import feast.proto.core.FeatureViewProto; import feast.proto.serving.ServingAPIProto; import feast.proto.serving.ServingAPIProto.FieldStatus; -import feast.proto.serving.ServingAPIProto.GetOnlineFeaturesResponseV2; +import feast.proto.serving.ServingAPIProto.GetOnlineFeaturesResponse; import feast.proto.types.ValueProto; import feast.serving.registry.Registry; import feast.serving.registry.RegistryRepository; @@ -173,10 +173,10 @@ public void shouldReturnResponseWithValuesAndMetadataIfKeysPresent() { when(tracer.buildSpan(ArgumentMatchers.any())).thenReturn(Mockito.mock(SpanBuilder.class)); - GetOnlineFeaturesResponseV2 expected = - GetOnlineFeaturesResponseV2.newBuilder() + GetOnlineFeaturesResponse expected = + GetOnlineFeaturesResponse.newBuilder() .addResults( - GetOnlineFeaturesResponseV2.FeatureVector.newBuilder() + GetOnlineFeaturesResponse.FeatureVector.newBuilder() .addValues(createStrValue("1")) .addValues(createStrValue("3")) .addStatuses(FieldStatus.PRESENT) @@ -184,7 +184,7 @@ public void shouldReturnResponseWithValuesAndMetadataIfKeysPresent() { .addEventTimestamps(now) .addEventTimestamps(now)) .addResults( - GetOnlineFeaturesResponseV2.FeatureVector.newBuilder() + GetOnlineFeaturesResponse.FeatureVector.newBuilder() .addValues(createStrValue("2")) .addValues(createStrValue("4")) .addStatuses(FieldStatus.PRESENT) @@ -198,7 +198,7 @@ public void shouldReturnResponseWithValuesAndMetadataIfKeysPresent() { .addVal("featureview_1:feature_1") .addVal("featureview_1:feature_2"))) .build(); - ServingAPIProto.GetOnlineFeaturesResponseV2 actual = + ServingAPIProto.GetOnlineFeaturesResponse actual = onlineServingServiceV2.getOnlineFeatures(request); assertThat(actual, equalTo(expected)); } @@ -240,10 +240,10 @@ public void shouldReturnResponseWithUnsetValuesAndMetadataIfKeysNotPresent() { when(tracer.buildSpan(ArgumentMatchers.any())).thenReturn(Mockito.mock(SpanBuilder.class)); - GetOnlineFeaturesResponseV2 expected = - GetOnlineFeaturesResponseV2.newBuilder() + GetOnlineFeaturesResponse expected = + GetOnlineFeaturesResponse.newBuilder() .addResults( - GetOnlineFeaturesResponseV2.FeatureVector.newBuilder() + GetOnlineFeaturesResponse.FeatureVector.newBuilder() .addValues(createStrValue("1")) .addValues(createEmptyValue()) .addStatuses(FieldStatus.PRESENT) @@ -251,7 +251,7 @@ public void shouldReturnResponseWithUnsetValuesAndMetadataIfKeysNotPresent() { .addEventTimestamps(now) .addEventTimestamps(Timestamp.newBuilder().build())) .addResults( - GetOnlineFeaturesResponseV2.FeatureVector.newBuilder() + GetOnlineFeaturesResponse.FeatureVector.newBuilder() .addValues(createStrValue("2")) .addValues(createStrValue("5")) .addStatuses(FieldStatus.PRESENT) @@ -265,7 +265,7 @@ public void shouldReturnResponseWithUnsetValuesAndMetadataIfKeysNotPresent() { .addVal("featureview_1:feature_1") .addVal("featureview_1:feature_2"))) .build(); - GetOnlineFeaturesResponseV2 actual = onlineServingServiceV2.getOnlineFeatures(request); + GetOnlineFeaturesResponse actual = onlineServingServiceV2.getOnlineFeatures(request); assertThat(actual, equalTo(expected)); } @@ -317,10 +317,10 @@ public void shouldReturnResponseWithValuesAndMetadataIfMaxAgeIsExceeded() { when(tracer.buildSpan(ArgumentMatchers.any())).thenReturn(Mockito.mock(SpanBuilder.class)); - GetOnlineFeaturesResponseV2 expected = - GetOnlineFeaturesResponseV2.newBuilder() + GetOnlineFeaturesResponse expected = + GetOnlineFeaturesResponse.newBuilder() .addResults( - GetOnlineFeaturesResponseV2.FeatureVector.newBuilder() + GetOnlineFeaturesResponse.FeatureVector.newBuilder() .addValues(createStrValue("6")) .addValues(createStrValue("6")) .addStatuses(FieldStatus.OUTSIDE_MAX_AGE) @@ -328,7 +328,7 @@ public void shouldReturnResponseWithValuesAndMetadataIfMaxAgeIsExceeded() { .addEventTimestamps(Timestamp.newBuilder().setSeconds(1).build()) .addEventTimestamps(Timestamp.newBuilder().setSeconds(1).build())) .addResults( - GetOnlineFeaturesResponseV2.FeatureVector.newBuilder() + GetOnlineFeaturesResponse.FeatureVector.newBuilder() .addValues(createStrValue("2")) .addValues(createStrValue("2")) .addStatuses(FieldStatus.PRESENT) @@ -342,7 +342,7 @@ public void shouldReturnResponseWithValuesAndMetadataIfMaxAgeIsExceeded() { .addVal("featureview_1:feature_1") .addVal("featureview_1:feature_2"))) .build(); - GetOnlineFeaturesResponseV2 actual = onlineServingServiceV2.getOnlineFeatures(request); + GetOnlineFeaturesResponse actual = onlineServingServiceV2.getOnlineFeatures(request); assertThat(actual, equalTo(expected)); } diff --git a/protos/feast/serving/ServingService.proto b/protos/feast/serving/ServingService.proto index 7d45e61a5e..6c551a97ba 100644 --- a/protos/feast/serving/ServingService.proto +++ b/protos/feast/serving/ServingService.proto @@ -30,7 +30,7 @@ service ServingService { rpc GetFeastServingInfo (GetFeastServingInfoRequest) returns (GetFeastServingInfoResponse); // Get online features synchronously. - rpc GetOnlineFeatures (GetOnlineFeaturesRequest) returns (GetOnlineFeaturesResponseV2); + rpc GetOnlineFeatures (GetOnlineFeaturesRequest) returns (GetOnlineFeaturesResponse); } message GetFeastServingInfoRequest {} @@ -95,19 +95,6 @@ message GetOnlineFeaturesRequest { } message GetOnlineFeaturesResponse { - // Feature values retrieved from feast. - repeated FieldValues field_values = 1; - - message FieldValues { - // Map of feature or entity name to feature/entity values. - // Timestamps are not returned in this response. - map fields = 1; - // Map of feature or entity name to feature/entity statuses/metadata. - map statuses = 2; - } -} - -message GetOnlineFeaturesResponseV2 { GetOnlineFeaturesResponseMetadata metadata = 1; // Length of "results" array should match length of requested features. diff --git a/sdk/go/client_test.go b/sdk/go/client_test.go index 95be34af73..cb15f66654 100644 --- a/sdk/go/client_test.go +++ b/sdk/go/client_test.go @@ -33,8 +33,8 @@ func TestGetOnlineFeatures(t *testing.T) { Project: "driver_project", }, want: OnlineFeaturesResponse{ - RawResponse: &serving.GetOnlineFeaturesResponseV2{ - Results: []*serving.GetOnlineFeaturesResponseV2_FeatureVector{ + RawResponse: &serving.GetOnlineFeaturesResponse{ + Results: []*serving.GetOnlineFeaturesResponse_FeatureVector{ { Values: []*types.Value{Int64Val(1)}, Statuses: []serving.FieldStatus{ diff --git a/sdk/go/mocks/serving_mock.go b/sdk/go/mocks/serving_mock.go index 57ee0c1ea4..038d49f5e5 100644 --- a/sdk/go/mocks/serving_mock.go +++ b/sdk/go/mocks/serving_mock.go @@ -57,14 +57,14 @@ func (mr *MockServingServiceClientMockRecorder) GetFeastServingInfo(arg0, arg1 i } // GetOnlineFeaturesV2 mocks base method -func (m *MockServingServiceClient) GetOnlineFeatures(arg0 context.Context, arg1 *serving.GetOnlineFeaturesRequest, arg2 ...grpc.CallOption) (*serving.GetOnlineFeaturesResponseV2, error) { +func (m *MockServingServiceClient) GetOnlineFeatures(arg0 context.Context, arg1 *serving.GetOnlineFeaturesRequest, arg2 ...grpc.CallOption) (*serving.GetOnlineFeaturesResponse, error) { m.ctrl.T.Helper() varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "GetOnlineFeatures", varargs...) - ret0, _ := ret[0].(*serving.GetOnlineFeaturesResponseV2) + ret0, _ := ret[0].(*serving.GetOnlineFeaturesResponse) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/sdk/go/protos/feast/serving/ServingService.pb.go b/sdk/go/protos/feast/serving/ServingService.pb.go index 68e771a31b..b367a307f4 100644 --- a/sdk/go/protos/feast/serving/ServingService.pb.go +++ b/sdk/go/protos/feast/serving/ServingService.pb.go @@ -380,7 +380,10 @@ type GetOnlineFeaturesRequest struct { // A map of entity name -> list of values Entities map[string]*types.RepeatedValue `protobuf:"bytes,3,rep,name=entities,proto3" json:"entities,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` FullFeatureNames bool `protobuf:"varint,4,opt,name=full_feature_names,json=fullFeatureNames,proto3" json:"full_feature_names,omitempty"` - RequestContext map[string]*types.RepeatedValue `protobuf:"bytes,5,rep,name=request_context,json=requestContext,proto3" json:"request_context,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // Context for OnDemand Feature Transformation + // (was moved to dedicated parameter to avoid unnecessary separation logic on serving side) + // A map of variable name -> list of values + RequestContext map[string]*types.RepeatedValue `protobuf:"bytes,5,rep,name=request_context,json=requestContext,proto3" json:"request_context,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *GetOnlineFeaturesRequest) Reset() { @@ -478,8 +481,10 @@ type GetOnlineFeaturesResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Feature values retrieved from feast. - FieldValues []*GetOnlineFeaturesResponse_FieldValues `protobuf:"bytes,1,rep,name=field_values,json=fieldValues,proto3" json:"field_values,omitempty"` + Metadata *GetOnlineFeaturesResponseMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + // Length of "results" array should match length of requested features. + // We also preserve the same order of features here as in metadata.feature_names + Results []*GetOnlineFeaturesResponse_FeatureVector `protobuf:"bytes,2,rep,name=results,proto3" json:"results,omitempty"` } func (x *GetOnlineFeaturesResponse) Reset() { @@ -514,62 +519,14 @@ func (*GetOnlineFeaturesResponse) Descriptor() ([]byte, []int) { return file_feast_serving_ServingService_proto_rawDescGZIP(), []int{6} } -func (x *GetOnlineFeaturesResponse) GetFieldValues() []*GetOnlineFeaturesResponse_FieldValues { - if x != nil { - return x.FieldValues - } - return nil -} - -type GetOnlineFeaturesResponseV2 struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Metadata *GetOnlineFeaturesResponseMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` - Results []*GetOnlineFeaturesResponseV2_FeatureVector `protobuf:"bytes,2,rep,name=results,proto3" json:"results,omitempty"` -} - -func (x *GetOnlineFeaturesResponseV2) Reset() { - *x = GetOnlineFeaturesResponseV2{} - if protoimpl.UnsafeEnabled { - mi := &file_feast_serving_ServingService_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetOnlineFeaturesResponseV2) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetOnlineFeaturesResponseV2) ProtoMessage() {} - -func (x *GetOnlineFeaturesResponseV2) ProtoReflect() protoreflect.Message { - mi := &file_feast_serving_ServingService_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetOnlineFeaturesResponseV2.ProtoReflect.Descriptor instead. -func (*GetOnlineFeaturesResponseV2) Descriptor() ([]byte, []int) { - return file_feast_serving_ServingService_proto_rawDescGZIP(), []int{7} -} - -func (x *GetOnlineFeaturesResponseV2) GetMetadata() *GetOnlineFeaturesResponseMetadata { +func (x *GetOnlineFeaturesResponse) GetMetadata() *GetOnlineFeaturesResponseMetadata { if x != nil { return x.Metadata } return nil } -func (x *GetOnlineFeaturesResponseV2) GetResults() []*GetOnlineFeaturesResponseV2_FeatureVector { +func (x *GetOnlineFeaturesResponse) GetResults() []*GetOnlineFeaturesResponse_FeatureVector { if x != nil { return x.Results } @@ -587,7 +544,7 @@ type GetOnlineFeaturesResponseMetadata struct { func (x *GetOnlineFeaturesResponseMetadata) Reset() { *x = GetOnlineFeaturesResponseMetadata{} if protoimpl.UnsafeEnabled { - mi := &file_feast_serving_ServingService_proto_msgTypes[8] + mi := &file_feast_serving_ServingService_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -600,7 +557,7 @@ func (x *GetOnlineFeaturesResponseMetadata) String() string { func (*GetOnlineFeaturesResponseMetadata) ProtoMessage() {} func (x *GetOnlineFeaturesResponseMetadata) ProtoReflect() protoreflect.Message { - mi := &file_feast_serving_ServingService_proto_msgTypes[8] + mi := &file_feast_serving_ServingService_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -613,7 +570,7 @@ func (x *GetOnlineFeaturesResponseMetadata) ProtoReflect() protoreflect.Message // Deprecated: Use GetOnlineFeaturesResponseMetadata.ProtoReflect.Descriptor instead. func (*GetOnlineFeaturesResponseMetadata) Descriptor() ([]byte, []int) { - return file_feast_serving_ServingService_proto_rawDescGZIP(), []int{8} + return file_feast_serving_ServingService_proto_rawDescGZIP(), []int{7} } func (x *GetOnlineFeaturesResponseMetadata) GetFeatureNames() *FeatureList { @@ -638,7 +595,7 @@ type GetOnlineFeaturesRequestV2_EntityRow struct { func (x *GetOnlineFeaturesRequestV2_EntityRow) Reset() { *x = GetOnlineFeaturesRequestV2_EntityRow{} if protoimpl.UnsafeEnabled { - mi := &file_feast_serving_ServingService_proto_msgTypes[9] + mi := &file_feast_serving_ServingService_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -651,7 +608,7 @@ func (x *GetOnlineFeaturesRequestV2_EntityRow) String() string { func (*GetOnlineFeaturesRequestV2_EntityRow) ProtoMessage() {} func (x *GetOnlineFeaturesRequestV2_EntityRow) ProtoReflect() protoreflect.Message { - mi := &file_feast_serving_ServingService_proto_msgTypes[9] + mi := &file_feast_serving_ServingService_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -681,65 +638,7 @@ func (x *GetOnlineFeaturesRequestV2_EntityRow) GetFields() map[string]*types.Val return nil } -type GetOnlineFeaturesResponse_FieldValues struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Map of feature or entity name to feature/entity values. - // Timestamps are not returned in this response. - Fields map[string]*types.Value `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // Map of feature or entity name to feature/entity statuses/metadata. - Statuses map[string]FieldStatus `protobuf:"bytes,2,rep,name=statuses,proto3" json:"statuses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3,enum=feast.serving.FieldStatus"` -} - -func (x *GetOnlineFeaturesResponse_FieldValues) Reset() { - *x = GetOnlineFeaturesResponse_FieldValues{} - if protoimpl.UnsafeEnabled { - mi := &file_feast_serving_ServingService_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetOnlineFeaturesResponse_FieldValues) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetOnlineFeaturesResponse_FieldValues) ProtoMessage() {} - -func (x *GetOnlineFeaturesResponse_FieldValues) ProtoReflect() protoreflect.Message { - mi := &file_feast_serving_ServingService_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetOnlineFeaturesResponse_FieldValues.ProtoReflect.Descriptor instead. -func (*GetOnlineFeaturesResponse_FieldValues) Descriptor() ([]byte, []int) { - return file_feast_serving_ServingService_proto_rawDescGZIP(), []int{6, 0} -} - -func (x *GetOnlineFeaturesResponse_FieldValues) GetFields() map[string]*types.Value { - if x != nil { - return x.Fields - } - return nil -} - -func (x *GetOnlineFeaturesResponse_FieldValues) GetStatuses() map[string]FieldStatus { - if x != nil { - return x.Statuses - } - return nil -} - -type GetOnlineFeaturesResponseV2_FeatureVector struct { +type GetOnlineFeaturesResponse_FeatureVector struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -749,23 +648,23 @@ type GetOnlineFeaturesResponseV2_FeatureVector struct { EventTimestamps []*timestamppb.Timestamp `protobuf:"bytes,3,rep,name=event_timestamps,json=eventTimestamps,proto3" json:"event_timestamps,omitempty"` } -func (x *GetOnlineFeaturesResponseV2_FeatureVector) Reset() { - *x = GetOnlineFeaturesResponseV2_FeatureVector{} +func (x *GetOnlineFeaturesResponse_FeatureVector) Reset() { + *x = GetOnlineFeaturesResponse_FeatureVector{} if protoimpl.UnsafeEnabled { - mi := &file_feast_serving_ServingService_proto_msgTypes[16] + mi := &file_feast_serving_ServingService_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *GetOnlineFeaturesResponseV2_FeatureVector) String() string { +func (x *GetOnlineFeaturesResponse_FeatureVector) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetOnlineFeaturesResponseV2_FeatureVector) ProtoMessage() {} +func (*GetOnlineFeaturesResponse_FeatureVector) ProtoMessage() {} -func (x *GetOnlineFeaturesResponseV2_FeatureVector) ProtoReflect() protoreflect.Message { - mi := &file_feast_serving_ServingService_proto_msgTypes[16] +func (x *GetOnlineFeaturesResponse_FeatureVector) ProtoReflect() protoreflect.Message { + mi := &file_feast_serving_ServingService_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -776,26 +675,26 @@ func (x *GetOnlineFeaturesResponseV2_FeatureVector) ProtoReflect() protoreflect. return mi.MessageOf(x) } -// Deprecated: Use GetOnlineFeaturesResponseV2_FeatureVector.ProtoReflect.Descriptor instead. -func (*GetOnlineFeaturesResponseV2_FeatureVector) Descriptor() ([]byte, []int) { - return file_feast_serving_ServingService_proto_rawDescGZIP(), []int{7, 0} +// Deprecated: Use GetOnlineFeaturesResponse_FeatureVector.ProtoReflect.Descriptor instead. +func (*GetOnlineFeaturesResponse_FeatureVector) Descriptor() ([]byte, []int) { + return file_feast_serving_ServingService_proto_rawDescGZIP(), []int{6, 0} } -func (x *GetOnlineFeaturesResponseV2_FeatureVector) GetValues() []*types.Value { +func (x *GetOnlineFeaturesResponse_FeatureVector) GetValues() []*types.Value { if x != nil { return x.Values } return nil } -func (x *GetOnlineFeaturesResponseV2_FeatureVector) GetStatuses() []FieldStatus { +func (x *GetOnlineFeaturesResponse_FeatureVector) GetStatuses() []FieldStatus { if x != nil { return x.Statuses } return nil } -func (x *GetOnlineFeaturesResponseV2_FeatureVector) GetEventTimestamps() []*timestamppb.Timestamp { +func (x *GetOnlineFeaturesResponse_FeatureVector) GetEventTimestamps() []*timestamppb.Timestamp { if x != nil { return x.EventTimestamps } @@ -888,94 +787,63 @@ var file_feast_serving_ServingService_proto_rawDesc = []byte{ 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, - 0x64, 0x22, 0xe6, 0x03, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x46, + 0x64, 0x22, 0xf8, 0x02, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x57, 0x0a, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x73, 0x65, + 0x4c, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x30, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, + 0x67, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x50, 0x0a, + 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, + 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x2e, 0x47, + 0x65, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, + 0xba, 0x01, 0x0a, 0x0d, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x36, 0x0a, + 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, + 0x1a, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x2e, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x08, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x10, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0f, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x22, 0x64, 0x0a, 0x21, + 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x3f, 0x0a, 0x0d, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x0c, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x2a, 0x5b, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0b, + 0x0a, 0x07, 0x50, 0x52, 0x45, 0x53, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, + 0x55, 0x4c, 0x4c, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x4e, + 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x55, + 0x54, 0x53, 0x49, 0x44, 0x45, 0x5f, 0x4d, 0x41, 0x58, 0x5f, 0x41, 0x47, 0x45, 0x10, 0x04, 0x32, + 0xe6, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x6c, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x46, 0x65, 0x61, 0x73, 0x74, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x29, 0x2e, 0x66, 0x65, 0x61, 0x73, + 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x65, 0x61, + 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x65, 0x61, 0x73, 0x74, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x66, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x65, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x27, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x46, - 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, - 0x46, 0x69, 0x65, 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x0b, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x1a, 0xef, 0x02, 0x0a, 0x0b, 0x46, 0x69, 0x65, - 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x58, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x6c, 0x69, - 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x73, 0x12, 0x5e, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x65, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x65, 0x73, 0x1a, 0x4d, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x1a, 0x57, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x6e, 0x67, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xfc, 0x02, 0x0a, 0x1b, 0x47, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, + 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x12, 0x4c, 0x0a, 0x08, 0x6d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x66, - 0x65, 0x61, 0x73, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, - 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x52, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x66, 0x65, 0x61, 0x73, - 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x6c, - 0x69, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x56, 0x32, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x56, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, 0xba, 0x01, 0x0a, - 0x0d, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x2a, - 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x36, 0x0a, 0x08, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x66, - 0x65, 0x61, 0x73, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x2e, 0x46, 0x69, 0x65, - 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x65, 0x73, 0x12, 0x45, 0x0a, 0x10, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x22, 0x64, 0x0a, 0x21, 0x47, 0x65, 0x74, - 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x3f, - 0x0a, 0x0d, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x6e, 0x67, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x0c, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x2a, - 0x5b, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, - 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, - 0x52, 0x45, 0x53, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x55, 0x4c, 0x4c, - 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, - 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x55, 0x54, 0x53, 0x49, - 0x44, 0x45, 0x5f, 0x4d, 0x41, 0x58, 0x5f, 0x41, 0x47, 0x45, 0x10, 0x04, 0x32, 0xe8, 0x01, 0x0a, - 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x6c, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x46, 0x65, 0x61, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x29, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x65, 0x61, 0x73, 0x74, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2a, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, - 0x67, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x65, 0x61, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, - 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, - 0x11, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x73, 0x12, 0x27, 0x2e, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x66, 0x65, - 0x61, 0x73, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x4f, - 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x42, 0x5e, 0x0a, 0x13, 0x66, 0x65, 0x61, 0x73, 0x74, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x42, 0x0f, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x41, 0x50, 0x49, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5a, - 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, 0x65, 0x61, 0x73, - 0x74, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2f, 0x73, 0x64, 0x6b, 0x2f, - 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2f, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x5e, 0x0a, 0x13, 0x66, 0x65, 0x61, 0x73, + 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x42, + 0x0f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x41, 0x50, 0x49, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, 0x65, 0x61, + 0x73, 0x74, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x66, 0x65, 0x61, 0x73, 0x74, 0x2f, 0x73, 0x64, 0x6b, + 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x66, 0x65, 0x61, 0x73, 0x74, + 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -991,7 +859,7 @@ func file_feast_serving_ServingService_proto_rawDescGZIP() []byte { } var file_feast_serving_ServingService_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_feast_serving_ServingService_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_feast_serving_ServingService_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_feast_serving_ServingService_proto_goTypes = []interface{}{ (FieldStatus)(0), // 0: feast.serving.FieldStatus (*GetFeastServingInfoRequest)(nil), // 1: feast.serving.GetFeastServingInfoRequest @@ -1001,51 +869,42 @@ var file_feast_serving_ServingService_proto_goTypes = []interface{}{ (*FeatureList)(nil), // 5: feast.serving.FeatureList (*GetOnlineFeaturesRequest)(nil), // 6: feast.serving.GetOnlineFeaturesRequest (*GetOnlineFeaturesResponse)(nil), // 7: feast.serving.GetOnlineFeaturesResponse - (*GetOnlineFeaturesResponseV2)(nil), // 8: feast.serving.GetOnlineFeaturesResponseV2 - (*GetOnlineFeaturesResponseMetadata)(nil), // 9: feast.serving.GetOnlineFeaturesResponseMetadata - (*GetOnlineFeaturesRequestV2_EntityRow)(nil), // 10: feast.serving.GetOnlineFeaturesRequestV2.EntityRow - nil, // 11: feast.serving.GetOnlineFeaturesRequestV2.EntityRow.FieldsEntry - nil, // 12: feast.serving.GetOnlineFeaturesRequest.EntitiesEntry - nil, // 13: feast.serving.GetOnlineFeaturesRequest.RequestContextEntry - (*GetOnlineFeaturesResponse_FieldValues)(nil), // 14: feast.serving.GetOnlineFeaturesResponse.FieldValues - nil, // 15: feast.serving.GetOnlineFeaturesResponse.FieldValues.FieldsEntry - nil, // 16: feast.serving.GetOnlineFeaturesResponse.FieldValues.StatusesEntry - (*GetOnlineFeaturesResponseV2_FeatureVector)(nil), // 17: feast.serving.GetOnlineFeaturesResponseV2.FeatureVector - (*timestamppb.Timestamp)(nil), // 18: google.protobuf.Timestamp - (*types.Value)(nil), // 19: feast.types.Value - (*types.RepeatedValue)(nil), // 20: feast.types.RepeatedValue + (*GetOnlineFeaturesResponseMetadata)(nil), // 8: feast.serving.GetOnlineFeaturesResponseMetadata + (*GetOnlineFeaturesRequestV2_EntityRow)(nil), // 9: feast.serving.GetOnlineFeaturesRequestV2.EntityRow + nil, // 10: feast.serving.GetOnlineFeaturesRequestV2.EntityRow.FieldsEntry + nil, // 11: feast.serving.GetOnlineFeaturesRequest.EntitiesEntry + nil, // 12: feast.serving.GetOnlineFeaturesRequest.RequestContextEntry + (*GetOnlineFeaturesResponse_FeatureVector)(nil), // 13: feast.serving.GetOnlineFeaturesResponse.FeatureVector + (*timestamppb.Timestamp)(nil), // 14: google.protobuf.Timestamp + (*types.Value)(nil), // 15: feast.types.Value + (*types.RepeatedValue)(nil), // 16: feast.types.RepeatedValue } var file_feast_serving_ServingService_proto_depIdxs = []int32{ 3, // 0: feast.serving.GetOnlineFeaturesRequestV2.features:type_name -> feast.serving.FeatureReferenceV2 - 10, // 1: feast.serving.GetOnlineFeaturesRequestV2.entity_rows:type_name -> feast.serving.GetOnlineFeaturesRequestV2.EntityRow + 9, // 1: feast.serving.GetOnlineFeaturesRequestV2.entity_rows:type_name -> feast.serving.GetOnlineFeaturesRequestV2.EntityRow 5, // 2: feast.serving.GetOnlineFeaturesRequest.features:type_name -> feast.serving.FeatureList - 12, // 3: feast.serving.GetOnlineFeaturesRequest.entities:type_name -> feast.serving.GetOnlineFeaturesRequest.EntitiesEntry - 13, // 4: feast.serving.GetOnlineFeaturesRequest.request_context:type_name -> feast.serving.GetOnlineFeaturesRequest.RequestContextEntry - 14, // 5: feast.serving.GetOnlineFeaturesResponse.field_values:type_name -> feast.serving.GetOnlineFeaturesResponse.FieldValues - 9, // 6: feast.serving.GetOnlineFeaturesResponseV2.metadata:type_name -> feast.serving.GetOnlineFeaturesResponseMetadata - 17, // 7: feast.serving.GetOnlineFeaturesResponseV2.results:type_name -> feast.serving.GetOnlineFeaturesResponseV2.FeatureVector - 5, // 8: feast.serving.GetOnlineFeaturesResponseMetadata.feature_names:type_name -> feast.serving.FeatureList - 18, // 9: feast.serving.GetOnlineFeaturesRequestV2.EntityRow.timestamp:type_name -> google.protobuf.Timestamp - 11, // 10: feast.serving.GetOnlineFeaturesRequestV2.EntityRow.fields:type_name -> feast.serving.GetOnlineFeaturesRequestV2.EntityRow.FieldsEntry - 19, // 11: feast.serving.GetOnlineFeaturesRequestV2.EntityRow.FieldsEntry.value:type_name -> feast.types.Value - 20, // 12: feast.serving.GetOnlineFeaturesRequest.EntitiesEntry.value:type_name -> feast.types.RepeatedValue - 20, // 13: feast.serving.GetOnlineFeaturesRequest.RequestContextEntry.value:type_name -> feast.types.RepeatedValue - 15, // 14: feast.serving.GetOnlineFeaturesResponse.FieldValues.fields:type_name -> feast.serving.GetOnlineFeaturesResponse.FieldValues.FieldsEntry - 16, // 15: feast.serving.GetOnlineFeaturesResponse.FieldValues.statuses:type_name -> feast.serving.GetOnlineFeaturesResponse.FieldValues.StatusesEntry - 19, // 16: feast.serving.GetOnlineFeaturesResponse.FieldValues.FieldsEntry.value:type_name -> feast.types.Value - 0, // 17: feast.serving.GetOnlineFeaturesResponse.FieldValues.StatusesEntry.value:type_name -> feast.serving.FieldStatus - 19, // 18: feast.serving.GetOnlineFeaturesResponseV2.FeatureVector.values:type_name -> feast.types.Value - 0, // 19: feast.serving.GetOnlineFeaturesResponseV2.FeatureVector.statuses:type_name -> feast.serving.FieldStatus - 18, // 20: feast.serving.GetOnlineFeaturesResponseV2.FeatureVector.event_timestamps:type_name -> google.protobuf.Timestamp - 1, // 21: feast.serving.ServingService.GetFeastServingInfo:input_type -> feast.serving.GetFeastServingInfoRequest - 6, // 22: feast.serving.ServingService.GetOnlineFeatures:input_type -> feast.serving.GetOnlineFeaturesRequest - 2, // 23: feast.serving.ServingService.GetFeastServingInfo:output_type -> feast.serving.GetFeastServingInfoResponse - 8, // 24: feast.serving.ServingService.GetOnlineFeatures:output_type -> feast.serving.GetOnlineFeaturesResponseV2 - 23, // [23:25] is the sub-list for method output_type - 21, // [21:23] is the sub-list for method input_type - 21, // [21:21] is the sub-list for extension type_name - 21, // [21:21] is the sub-list for extension extendee - 0, // [0:21] is the sub-list for field type_name + 11, // 3: feast.serving.GetOnlineFeaturesRequest.entities:type_name -> feast.serving.GetOnlineFeaturesRequest.EntitiesEntry + 12, // 4: feast.serving.GetOnlineFeaturesRequest.request_context:type_name -> feast.serving.GetOnlineFeaturesRequest.RequestContextEntry + 8, // 5: feast.serving.GetOnlineFeaturesResponse.metadata:type_name -> feast.serving.GetOnlineFeaturesResponseMetadata + 13, // 6: feast.serving.GetOnlineFeaturesResponse.results:type_name -> feast.serving.GetOnlineFeaturesResponse.FeatureVector + 5, // 7: feast.serving.GetOnlineFeaturesResponseMetadata.feature_names:type_name -> feast.serving.FeatureList + 14, // 8: feast.serving.GetOnlineFeaturesRequestV2.EntityRow.timestamp:type_name -> google.protobuf.Timestamp + 10, // 9: feast.serving.GetOnlineFeaturesRequestV2.EntityRow.fields:type_name -> feast.serving.GetOnlineFeaturesRequestV2.EntityRow.FieldsEntry + 15, // 10: feast.serving.GetOnlineFeaturesRequestV2.EntityRow.FieldsEntry.value:type_name -> feast.types.Value + 16, // 11: feast.serving.GetOnlineFeaturesRequest.EntitiesEntry.value:type_name -> feast.types.RepeatedValue + 16, // 12: feast.serving.GetOnlineFeaturesRequest.RequestContextEntry.value:type_name -> feast.types.RepeatedValue + 15, // 13: feast.serving.GetOnlineFeaturesResponse.FeatureVector.values:type_name -> feast.types.Value + 0, // 14: feast.serving.GetOnlineFeaturesResponse.FeatureVector.statuses:type_name -> feast.serving.FieldStatus + 14, // 15: feast.serving.GetOnlineFeaturesResponse.FeatureVector.event_timestamps:type_name -> google.protobuf.Timestamp + 1, // 16: feast.serving.ServingService.GetFeastServingInfo:input_type -> feast.serving.GetFeastServingInfoRequest + 6, // 17: feast.serving.ServingService.GetOnlineFeatures:input_type -> feast.serving.GetOnlineFeaturesRequest + 2, // 18: feast.serving.ServingService.GetFeastServingInfo:output_type -> feast.serving.GetFeastServingInfoResponse + 7, // 19: feast.serving.ServingService.GetOnlineFeatures:output_type -> feast.serving.GetOnlineFeaturesResponse + 18, // [18:20] is the sub-list for method output_type + 16, // [16:18] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 16, // [16:16] is the sub-list for extension extendee + 0, // [0:16] is the sub-list for field type_name } func init() { file_feast_serving_ServingService_proto_init() } @@ -1139,18 +998,6 @@ func file_feast_serving_ServingService_proto_init() { } } file_feast_serving_ServingService_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetOnlineFeaturesResponseV2); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_feast_serving_ServingService_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetOnlineFeaturesResponseMetadata); i { case 0: return &v.state @@ -1162,7 +1009,7 @@ func file_feast_serving_ServingService_proto_init() { return nil } } - file_feast_serving_ServingService_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_feast_serving_ServingService_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetOnlineFeaturesRequestV2_EntityRow); i { case 0: return &v.state @@ -1174,20 +1021,8 @@ func file_feast_serving_ServingService_proto_init() { return nil } } - file_feast_serving_ServingService_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetOnlineFeaturesResponse_FieldValues); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_feast_serving_ServingService_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetOnlineFeaturesResponseV2_FeatureVector); i { + file_feast_serving_ServingService_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetOnlineFeaturesResponse_FeatureVector); i { case 0: return &v.state case 1: @@ -1209,7 +1044,7 @@ func file_feast_serving_ServingService_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_feast_serving_ServingService_proto_rawDesc, NumEnums: 1, - NumMessages: 17, + NumMessages: 13, NumExtensions: 0, NumServices: 1, }, @@ -1239,7 +1074,7 @@ type ServingServiceClient interface { // Get information about this Feast serving. GetFeastServingInfo(ctx context.Context, in *GetFeastServingInfoRequest, opts ...grpc.CallOption) (*GetFeastServingInfoResponse, error) // Get online features synchronously. - GetOnlineFeatures(ctx context.Context, in *GetOnlineFeaturesRequest, opts ...grpc.CallOption) (*GetOnlineFeaturesResponseV2, error) + GetOnlineFeatures(ctx context.Context, in *GetOnlineFeaturesRequest, opts ...grpc.CallOption) (*GetOnlineFeaturesResponse, error) } type servingServiceClient struct { @@ -1259,8 +1094,8 @@ func (c *servingServiceClient) GetFeastServingInfo(ctx context.Context, in *GetF return out, nil } -func (c *servingServiceClient) GetOnlineFeatures(ctx context.Context, in *GetOnlineFeaturesRequest, opts ...grpc.CallOption) (*GetOnlineFeaturesResponseV2, error) { - out := new(GetOnlineFeaturesResponseV2) +func (c *servingServiceClient) GetOnlineFeatures(ctx context.Context, in *GetOnlineFeaturesRequest, opts ...grpc.CallOption) (*GetOnlineFeaturesResponse, error) { + out := new(GetOnlineFeaturesResponse) err := c.cc.Invoke(ctx, "/feast.serving.ServingService/GetOnlineFeatures", in, out, opts...) if err != nil { return nil, err @@ -1273,7 +1108,7 @@ type ServingServiceServer interface { // Get information about this Feast serving. GetFeastServingInfo(context.Context, *GetFeastServingInfoRequest) (*GetFeastServingInfoResponse, error) // Get online features synchronously. - GetOnlineFeatures(context.Context, *GetOnlineFeaturesRequest) (*GetOnlineFeaturesResponseV2, error) + GetOnlineFeatures(context.Context, *GetOnlineFeaturesRequest) (*GetOnlineFeaturesResponse, error) } // UnimplementedServingServiceServer can be embedded to have forward compatible implementations. @@ -1283,7 +1118,7 @@ type UnimplementedServingServiceServer struct { func (*UnimplementedServingServiceServer) GetFeastServingInfo(context.Context, *GetFeastServingInfoRequest) (*GetFeastServingInfoResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetFeastServingInfo not implemented") } -func (*UnimplementedServingServiceServer) GetOnlineFeatures(context.Context, *GetOnlineFeaturesRequest) (*GetOnlineFeaturesResponseV2, error) { +func (*UnimplementedServingServiceServer) GetOnlineFeatures(context.Context, *GetOnlineFeaturesRequest) (*GetOnlineFeaturesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetOnlineFeatures not implemented") } diff --git a/sdk/go/request.go b/sdk/go/request.go index e6da10ff9b..94fecea01b 100644 --- a/sdk/go/request.go +++ b/sdk/go/request.go @@ -35,12 +35,12 @@ func (r OnlineFeaturesRequest) buildRequest() (*serving.GetOnlineFeaturesRequest if err != nil { return nil, err } - if len(r.Entities) == 0 { - return nil, fmt.Errorf("Entities must be provided") - } + if len(r.Entities) == 0 { + return nil, fmt.Errorf("Entities must be provided") + } - firstRow := r.Entities[0] - columnSize := len(firstRow) + firstRow := r.Entities[0] + columnSize := len(firstRow) // build request entity rows from native entities entityColumns := make(map[string][]*types.Value, columnSize) diff --git a/sdk/go/request_test.go b/sdk/go/request_test.go index 6beb15f7f7..9122c8ca40 100644 --- a/sdk/go/request_test.go +++ b/sdk/go/request_test.go @@ -37,12 +37,12 @@ func TestGetOnlineFeaturesRequest(t *testing.T) { }, }, Entities: map[string]*types.RepeatedValue{ - "entity1": &types.RepeatedValue{ + "entity1": { Val: []*types.Value{ Int64Val(1), Int64Val(1), Int64Val(1), }, }, - "entity2": &types.RepeatedValue{ + "entity2": { Val: []*types.Value{ StrVal("bob"), StrVal("annie"), StrVal("jane"), }, diff --git a/sdk/go/response.go b/sdk/go/response.go index 49c8904ab7..cdb2cbee38 100644 --- a/sdk/go/response.go +++ b/sdk/go/response.go @@ -19,7 +19,7 @@ var ( // OnlineFeaturesResponse is a wrapper around serving.GetOnlineFeaturesResponse. type OnlineFeaturesResponse struct { - RawResponse *serving.GetOnlineFeaturesResponseV2 + RawResponse *serving.GetOnlineFeaturesResponse } // Rows retrieves the result of the request as a list of Rows. diff --git a/sdk/go/response_test.go b/sdk/go/response_test.go index e9a9bc1605..693faae7e4 100644 --- a/sdk/go/response_test.go +++ b/sdk/go/response_test.go @@ -9,8 +9,8 @@ import ( ) var response = OnlineFeaturesResponse{ - RawResponse: &serving.GetOnlineFeaturesResponseV2{ - Results: []*serving.GetOnlineFeaturesResponseV2_FeatureVector{ + RawResponse: &serving.GetOnlineFeaturesResponse{ + Results: []*serving.GetOnlineFeaturesResponse_FeatureVector{ { Values: []*types.Value{Int64Val(1), Int64Val(2)}, Statuses: []serving.FieldStatus{ diff --git a/sdk/python/feast/feature_store.py b/sdk/python/feast/feature_store.py index d43a114b36..edfc8d4569 100644 --- a/sdk/python/feast/feature_store.py +++ b/sdk/python/feast/feature_store.py @@ -33,6 +33,7 @@ import pandas as pd from colorama import Fore, Style +from google.protobuf.timestamp_pb2 import Timestamp from tqdm import tqdm from feast import feature_server, flags, flags_helper, utils @@ -70,6 +71,7 @@ GetOnlineFeaturesResponse, ) from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto +from feast.protos.feast.types.Value_pb2 import Value as ValueProto from feast.registry import Registry from feast.repo_config import RepoConfig, load_repo_config from feast.request_feature_view import RequestFeatureView @@ -1137,13 +1139,19 @@ def get_online_features( entity_row_proto_list = _infer_online_entity_rows(join_key_rows) union_of_entity_keys: List[EntityKeyProto] = [] - result_rows: List[GetOnlineFeaturesResponse.FieldValues] = [] for entity_row_proto in entity_row_proto_list: # Create a list of entity keys to filter down for each feature view at lookup time. union_of_entity_keys.append(_entity_row_to_key(entity_row_proto)) - # Also create entity values to append to the result - result_rows.append(_entity_row_to_field_values(entity_row_proto)) + + online_features_response = GetOnlineFeaturesResponse( + results=[GetOnlineFeaturesResponse.FeatureVector()] * len(join_key_rows) + ) + + # Append entity keys to the response + self._populate_entities_in_response( + online_features_response, entity_row_proto_list + ) # Keep track of what has been requested from the OnlineStore # to avoid requesting the same thing twice for ODFVs. @@ -1153,12 +1161,12 @@ def get_online_features( entity_name_to_join_key_map[entity_name] for entity_name in table.entities ] - self._populate_result_rows_from_feature_view( + self._populate_fvs_in_response( + online_features_response, table_join_keys, full_feature_names, provider, requested_features, - result_rows, table, union_of_entity_keys, ) @@ -1168,52 +1176,39 @@ def get_online_features( for feature in requested_features } - requested_result_row_names = self._get_requested_result_fields( - result_rows, needed_request_fv_features + requested_result_row_names = ( + set(online_features_response.metadata.feature_names.val) + | needed_request_fv_features ) + self._populate_odfv_dependencies( + online_features_response, entity_name_to_join_key_map, full_feature_names, grouped_odfv_refs, provider, request_data_features, - result_rows, union_of_entity_keys, retrieved_feature_refs, ) self._augment_response_with_on_demand_transforms( + online_features_response, _feature_refs, requested_result_row_names, requested_on_demand_feature_views, full_feature_names, - result_rows, ) - return OnlineResponse(GetOnlineFeaturesResponse(field_values=result_rows)) - - def _get_requested_result_fields( - self, - result_rows: List[GetOnlineFeaturesResponse.FieldValues], - needed_request_fv_features: Set[str], - ): - # Get requested feature values so we can drop odfv dependencies that aren't requested - requested_result_row_names: Set[str] = set() - for result_row in result_rows: - for feature_name in result_row.fields.keys(): - requested_result_row_names.add(feature_name) - # Request feature view values are also request data features that should be in the - # final output - requested_result_row_names.update(needed_request_fv_features) - return requested_result_row_names + return OnlineResponse(online_features_response) def _populate_odfv_dependencies( self, + online_features_response: GetOnlineFeaturesResponse, entity_name_to_join_key_map: Dict[str, str], full_feature_names: bool, grouped_odfv_refs: List[Tuple[OnDemandFeatureView, List[str]]], provider: Provider, request_data_features: Dict[str, List[Any]], - result_rows: List[GetOnlineFeaturesResponse.FieldValues], union_of_entity_keys: List[EntityKeyProto], retrieved_feature_refs: Set[str], ): @@ -1222,11 +1217,13 @@ def _populate_odfv_dependencies( proto_values = python_values_to_proto_values( feature_values, ValueType.UNKNOWN ) + online_features_response.metadata.feature_names.val.append(feature_name) for row_idx, proto_value in enumerate(proto_values): - result_row = result_rows[row_idx] - result_row.fields[feature_name].CopyFrom(proto_value) - result_row.statuses[feature_name] = FieldStatus.PRESENT + result_row = online_features_response.results[row_idx] + result_row.values.append(proto_value) + result_row.statuses.append(FieldStatus.PRESENT) + result_row.event_timestamps.append(Timestamp()) # Add data if odfv requests specific feature views as dependencies if len(grouped_odfv_refs) > 0: @@ -1246,12 +1243,12 @@ def _populate_odfv_dependencies( entity_name_to_join_key_map[entity_name] for entity_name in fv.entities ] - self._populate_result_rows_from_feature_view( + self._populate_fvs_in_response( + online_features_response, table_join_keys, full_feature_names, provider, list(not_yet_retrieved), - result_rows, fv, union_of_entity_keys, ) @@ -1294,13 +1291,32 @@ def ensure_request_data_values_exist( feature_names=missing_features ) - def _populate_result_rows_from_feature_view( + def _populate_entities_in_response( + self, + online_features_response: GetOnlineFeaturesResponse, + rows: List[GetOnlineFeaturesRequestV2.EntityRow], + ): + # Note: We temporarily store entities in the same field as features for backwards compatibility. + # Java server uses the same GetOnlineFeaturesResponse but does not return entities right now. + # We need to unify the logic between Python & Java on this. + if len(rows) == 0: + return + fields = list(rows[0].fields.keys()) + online_features_response.metadata.feature_names.val.extend(fields) + for idx, row in enumerate(rows): + for field in fields: + result_row = online_features_response.results[idx] + result_row.values.append(row.fields[field]) + result_row.statuses.append(FieldStatus.PRESENT) + result_row.event_timestamps.append(Timestamp()) + + def _populate_fvs_in_response( self, + online_features_response: GetOnlineFeaturesResponse, table_join_keys: List[str], full_feature_names: bool, provider: Provider, requested_features: List[str], - result_rows: List[GetOnlineFeaturesResponse.FieldValues], table: FeatureView, union_of_entity_keys: List[EntityKeyProto], ): @@ -1313,47 +1329,55 @@ def _populate_result_rows_from_feature_view( entity_keys=entity_keys, requested_features=requested_features, ) + requested_feature_refs = [ + f"{table.projection.name_to_use()}__{feature_name}" + if full_feature_names + else feature_name + for feature_name in requested_features + ] + online_features_response.metadata.feature_names.val.extend( + requested_feature_refs + ) + # Each row is a set of features for a given entity key for row_idx, read_row in enumerate(read_rows): row_ts, feature_data = read_row - result_row = result_rows[row_idx] + result_row = online_features_response.results[row_idx] + row_ts_proto = Timestamp() + if row_ts is not None: + row_ts_proto.FromDatetime(row_ts) + result_row.event_timestamps.extend([row_ts_proto] * len(requested_features)) if feature_data is None: - for feature_name in requested_features: - feature_ref = ( - f"{table.projection.name_to_use()}__{feature_name}" - if full_feature_names - else feature_name - ) - result_row.statuses[feature_ref] = FieldStatus.NOT_FOUND + result_row.statuses.extend( + [FieldStatus.NOT_FOUND] * len(requested_features) + ) + result_row.values.extend([ValueProto()] * len(requested_features)) else: - for feature_name in feature_data: - feature_ref = ( - f"{table.projection.name_to_use()}__{feature_name}" - if full_feature_names - else feature_name - ) - if feature_name in requested_features: - result_row.fields[feature_ref].CopyFrom( - feature_data[feature_name] - ) - result_row.statuses[feature_ref] = FieldStatus.PRESENT + for feature_name in requested_features: + if feature_name not in feature_data: + result_row.statuses.append(FieldStatus.NOT_FOUND) + result_row.values.append(ValueProto()) + else: + result_row.statuses.append(FieldStatus.PRESENT) + result_row.values.append(feature_data[feature_name]) def _augment_response_with_on_demand_transforms( self, + online_features_response: GetOnlineFeaturesResponse, feature_refs: List[str], requested_result_row_names: Set[str], requested_on_demand_feature_views: List[OnDemandFeatureView], full_feature_names: bool, - result_rows: List[GetOnlineFeaturesResponse.FieldValues], ): """Computes on demand feature values and adds them to the result rows. - Assumes that 'result_rows' already contains the necessary request data and input feature + Assumes that 'online_features_response' already contains the necessary request data and input feature views for the on demand feature views. Unneeded feature values such as request data and - unrequested input feature views will be removed from 'result_rows'. + unrequested input feature views will be removed from 'online_features_response'. Args: + online_features_response: Protobuf object to populate feature_refs: List of all feature references to be returned. requested_result_row_names: Fields from 'result_rows' that have been requested, and therefore should not be dropped. @@ -1361,7 +1385,6 @@ def _augment_response_with_on_demand_transforms( full_feature_names: A boolean that provides the option to add the feature view prefixes to the feature names, changing them from the format "feature" to "feature_view__feature" (e.g., "daily_transactions" changes to "customer_fv__daily_transactions"). - result_rows: List of result rows to be augmented with on demand feature values. """ if len(requested_on_demand_feature_views) == 0: return @@ -1381,9 +1404,7 @@ def _augment_response_with_on_demand_transforms( else feature_name ) - initial_response = OnlineResponse( - GetOnlineFeaturesResponse(field_values=result_rows) - ) + initial_response = OnlineResponse(online_features_response) initial_response_df = initial_response.to_df() # Apply on demand transformations and augment the result rows @@ -1397,34 +1418,42 @@ def _augment_response_with_on_demand_transforms( f for f in transformed_features_df.columns if f in _feature_refs ] - proto_values_by_column = { - feature: python_values_to_proto_values( + proto_values = [ + python_values_to_proto_values( transformed_features_df[feature].values, ValueType.UNKNOWN ) for feature in selected_subset - } + ] - for row_idx in range(len(result_rows)): - result_row = result_rows[row_idx] + odfv_result_names |= set(selected_subset) - for transformed_feature in selected_subset: - odfv_result_names.add(transformed_feature) - result_row.fields[transformed_feature].CopyFrom( - proto_values_by_column[transformed_feature][row_idx] - ) - result_row.statuses[transformed_feature] = FieldStatus.PRESENT + online_features_response.metadata.feature_names.val.extend(selected_subset) + + for row_idx in range(len(online_features_response.results)): + result_row = online_features_response.results[row_idx] + for feature_idx, transformed_feature in enumerate(selected_subset): + result_row.values.append(proto_values[feature_idx][row_idx]) + result_row.statuses.append(FieldStatus.PRESENT) + result_row.event_timestamps.append(Timestamp()) # Drop values that aren't needed - unneeded_features = [ - val - for val in result_rows[0].fields + unneeded_feature_indices = [ + idx + for idx, val in enumerate( + online_features_response.metadata.feature_names.val + ) if val not in requested_result_row_names and val not in odfv_result_names ] - for row_idx in range(len(result_rows)): - result_row = result_rows[row_idx] - for unneeded_feature in unneeded_features: - result_row.fields.pop(unneeded_feature) - result_row.statuses.pop(unneeded_feature) + + for idx in reversed(unneeded_feature_indices): + del online_features_response.metadata.feature_names.val[idx] + + for row_idx in range(len(online_features_response.results)): + result_row = online_features_response.results[row_idx] + for idx in reversed(unneeded_feature_indices): + del result_row.values[idx] + del result_row.statuses[idx] + del result_row.event_timestamps[idx] def _get_feature_views_to_use( self, @@ -1517,17 +1546,6 @@ def _entity_row_to_key(row: GetOnlineFeaturesRequestV2.EntityRow) -> EntityKeyPr return EntityKeyProto(join_keys=names, entity_values=values) -def _entity_row_to_field_values( - row: GetOnlineFeaturesRequestV2.EntityRow, -) -> GetOnlineFeaturesResponse.FieldValues: - result = GetOnlineFeaturesResponse.FieldValues() - for k in row.fields: - result.fields[k].CopyFrom(row.fields[k]) - result.statuses[k] = FieldStatus.PRESENT - - return result - - def _validate_feature_refs(feature_refs: List[str], full_feature_names: bool = False): collided_feature_refs = [] diff --git a/sdk/python/feast/online_response.py b/sdk/python/feast/online_response.py index 359e216165..fdef90e57a 100644 --- a/sdk/python/feast/online_response.py +++ b/sdk/python/feast/online_response.py @@ -45,34 +45,31 @@ def __init__(self, online_response_proto: GetOnlineFeaturesResponse): online_response_proto: GetOnlineResponse proto object to construct from. """ self.proto = online_response_proto - # Delete DUMMY_ENTITY_ID from proto if it exists - for item in self.proto.field_values: - if DUMMY_ENTITY_ID in item.statuses: - del item.statuses[DUMMY_ENTITY_ID] - if DUMMY_ENTITY_ID in item.fields: - del item.fields[DUMMY_ENTITY_ID] - - @property - def field_values(self): - """ - Getter for GetOnlineResponse's field_values. - """ - return self.proto.field_values + if DUMMY_ENTITY_ID in self.proto.metadata.feature_names.val: + for idx, val in enumerate(self.proto.metadata.feature_names.val): + if val == DUMMY_ENTITY_ID: + del self.proto.metadata.feature_names.val[idx] + for result in self.proto.results: + del result.values[idx] + del result.statuses[idx] + del result.event_timestamps[idx] + break def to_dict(self) -> Dict[str, Any]: """ Converts GetOnlineFeaturesResponse features into a dictionary form. """ - features_dict: Dict[str, List[Any]] = { - k: list() for row in self.field_values for k, _ in row.statuses.items() - } + response: Dict[str, List[Any]] = {} - for row in self.field_values: - for feature in features_dict.keys(): - native_type_value = feast_value_type_to_python_type(row.fields[feature]) - features_dict[feature].append(native_type_value) + for result in self.proto.results: + for idx, feature_ref in enumerate(self.proto.metadata.feature_names.val): + native_type_value = feast_value_type_to_python_type(result.values[idx]) + if feature_ref not in response: + response[feature_ref] = [native_type_value] + else: + response[feature_ref].append(native_type_value) - return features_dict + return response def to_df(self) -> pd.DataFrame: """ diff --git a/sdk/python/tests/unit/test_proto_json.py b/sdk/python/tests/unit/test_proto_json.py index 1b352ccb19..4fec47759e 100644 --- a/sdk/python/tests/unit/test_proto_json.py +++ b/sdk/python/tests/unit/test_proto_json.py @@ -9,7 +9,7 @@ ) from feast.protos.feast.types.Value_pb2 import RepeatedValue -FieldValues = GetOnlineFeaturesResponse.FieldValues +FeatureVector = GetOnlineFeaturesResponse.FeatureVector @pytest.fixture(scope="module") @@ -17,70 +17,66 @@ def proto_json_patch(): proto_json.patch() -def test_feast_value(proto_json_patch): - # FieldValues contains "map fields" proto field. +def test_feature_vector_values(proto_json_patch): + # FeatureVector contains "repeated values" proto field. # We want to test that feast.types.Value can take different types in JSON # without using additional structure (e.g. 1 instead of {int64_val: 1}). - field_values_str = """{ - "fields": { - "a": 1, - "b": 2.0, - "c": true, - "d": "foo", - "e": [1, 2, 3], - "f": [2.0, 3.0, 4.0, null], - "g": [true, false, true], - "h": ["foo", "bar", "foobar"], - "i": null - } + feature_vector_str = """{ + "values": [ + 1, + 2.0, + true, + "foo", + [1, 2, 3], + [2.0, 3.0, 4.0, null], + [true, false, true], + ["foo", "bar", "foobar"], + null + ] }""" - field_values_proto = FieldValues() - Parse(field_values_str, field_values_proto) - assertpy.assert_that(field_values_proto.fields.keys()).is_equal_to( - {"a", "b", "c", "d", "e", "f", "g", "h", "i"} - ) - assertpy.assert_that(field_values_proto.fields["a"].int64_val).is_equal_to(1) - assertpy.assert_that(field_values_proto.fields["b"].double_val).is_equal_to(2.0) - assertpy.assert_that(field_values_proto.fields["c"].bool_val).is_equal_to(True) - assertpy.assert_that(field_values_proto.fields["d"].string_val).is_equal_to("foo") - assertpy.assert_that(field_values_proto.fields["e"].int64_list_val.val).is_equal_to( + feature_vector_proto = FeatureVector() + Parse(feature_vector_str, feature_vector_proto) + assertpy.assert_that(len(feature_vector_proto.values)).is_equal_to(9) + assertpy.assert_that(feature_vector_proto.values[0].int64_val).is_equal_to(1) + assertpy.assert_that(feature_vector_proto.values[1].double_val).is_equal_to(2.0) + assertpy.assert_that(feature_vector_proto.values[2].bool_val).is_equal_to(True) + assertpy.assert_that(feature_vector_proto.values[3].string_val).is_equal_to("foo") + assertpy.assert_that(feature_vector_proto.values[4].int64_list_val.val).is_equal_to( [1, 2, 3] ) # Can't directly check equality to [2.0, 3.0, 4.0, float("nan")], because float("nan") != float("nan") assertpy.assert_that( - field_values_proto.fields["f"].double_list_val.val[:3] + feature_vector_proto.values[5].double_list_val.val[:3] ).is_equal_to([2.0, 3.0, 4.0]) - assertpy.assert_that(field_values_proto.fields["f"].double_list_val.val[3]).is_nan() - assertpy.assert_that(field_values_proto.fields["g"].bool_list_val.val).is_equal_to( + assertpy.assert_that(feature_vector_proto.values[5].double_list_val.val[3]).is_nan() + assertpy.assert_that(feature_vector_proto.values[6].bool_list_val.val).is_equal_to( [True, False, True] ) assertpy.assert_that( - field_values_proto.fields["h"].string_list_val.val + feature_vector_proto.values[7].string_list_val.val ).is_equal_to(["foo", "bar", "foobar"]) - assertpy.assert_that(field_values_proto.fields["i"].null_val).is_equal_to(0) + assertpy.assert_that(feature_vector_proto.values[8].null_val).is_equal_to(0) # Now convert protobuf back to json and check that - field_values_json = MessageToDict(field_values_proto) - assertpy.assert_that(field_values_json["fields"].keys()).is_equal_to( - {"a", "b", "c", "d", "e", "f", "g", "h", "i"} - ) - assertpy.assert_that(field_values_json["fields"]["a"]).is_equal_to(1) - assertpy.assert_that(field_values_json["fields"]["b"]).is_equal_to(2.0) - assertpy.assert_that(field_values_json["fields"]["c"]).is_equal_to(True) - assertpy.assert_that(field_values_json["fields"]["d"]).is_equal_to("foo") - assertpy.assert_that(field_values_json["fields"]["e"]).is_equal_to([1, 2, 3]) + feature_vector_json = MessageToDict(feature_vector_proto) + assertpy.assert_that(len(feature_vector_json["values"])).is_equal_to(9) + assertpy.assert_that(feature_vector_json["values"][0]).is_equal_to(1) + assertpy.assert_that(feature_vector_json["values"][1]).is_equal_to(2.0) + assertpy.assert_that(feature_vector_json["values"][2]).is_equal_to(True) + assertpy.assert_that(feature_vector_json["values"][3]).is_equal_to("foo") + assertpy.assert_that(feature_vector_json["values"][4]).is_equal_to([1, 2, 3]) # Can't directly check equality to [2.0, 3.0, 4.0, float("nan")], because float("nan") != float("nan") - assertpy.assert_that(field_values_json["fields"]["f"][:3]).is_equal_to( + assertpy.assert_that(feature_vector_json["values"][5][:3]).is_equal_to( [2.0, 3.0, 4.0] ) - assertpy.assert_that(field_values_json["fields"]["f"][3]).is_nan() - assertpy.assert_that(field_values_json["fields"]["g"]).is_equal_to( + assertpy.assert_that(feature_vector_json["values"][5][3]).is_nan() + assertpy.assert_that(feature_vector_json["values"][6]).is_equal_to( [True, False, True] ) - assertpy.assert_that(field_values_json["fields"]["h"]).is_equal_to( + assertpy.assert_that(feature_vector_json["values"][7]).is_equal_to( ["foo", "bar", "foobar"] ) - assertpy.assert_that(field_values_json["fields"]["i"]).is_equal_to(None) + assertpy.assert_that(feature_vector_json["values"][8]).is_equal_to(None) def test_feast_repeated_value(proto_json_patch): From f0a0aae01a3935499423299cf0faa9a13047581f Mon Sep 17 00:00:00 2001 From: Tsotne Tabidze Date: Fri, 14 Jan 2022 10:35:01 -0800 Subject: [PATCH 2/4] Fix unit tests Signed-off-by: Tsotne Tabidze --- .../tests/integration/online_store/test_e2e_local.py | 9 ++++++++- sdk/python/tests/unit/test_proto_json.py | 9 +++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/sdk/python/tests/integration/online_store/test_e2e_local.py b/sdk/python/tests/integration/online_store/test_e2e_local.py index dd900e90dc..7990227344 100644 --- a/sdk/python/tests/integration/online_store/test_e2e_local.py +++ b/sdk/python/tests/integration/online_store/test_e2e_local.py @@ -40,7 +40,14 @@ def _assert_online_features( # Float features should still be floats from the online store... assert ( - response.field_values[0].fields["driver_hourly_stats__conv_rate"].float_val > 0 + response.proto.results[0] + .values[ + list(response.proto.metadata.feature_names.val).index( + "driver_hourly_stats__conv_rate" + ) + ] + .float_val + > 0 ) result = response.to_dict() diff --git a/sdk/python/tests/unit/test_proto_json.py b/sdk/python/tests/unit/test_proto_json.py index 4fec47759e..6bfdbbbf91 100644 --- a/sdk/python/tests/unit/test_proto_json.py +++ b/sdk/python/tests/unit/test_proto_json.py @@ -30,13 +30,12 @@ def test_feature_vector_values(proto_json_patch): [1, 2, 3], [2.0, 3.0, 4.0, null], [true, false, true], - ["foo", "bar", "foobar"], - null + ["foo", "bar", "foobar"] ] }""" feature_vector_proto = FeatureVector() Parse(feature_vector_str, feature_vector_proto) - assertpy.assert_that(len(feature_vector_proto.values)).is_equal_to(9) + assertpy.assert_that(len(feature_vector_proto.values)).is_equal_to(8) assertpy.assert_that(feature_vector_proto.values[0].int64_val).is_equal_to(1) assertpy.assert_that(feature_vector_proto.values[1].double_val).is_equal_to(2.0) assertpy.assert_that(feature_vector_proto.values[2].bool_val).is_equal_to(True) @@ -55,11 +54,10 @@ def test_feature_vector_values(proto_json_patch): assertpy.assert_that( feature_vector_proto.values[7].string_list_val.val ).is_equal_to(["foo", "bar", "foobar"]) - assertpy.assert_that(feature_vector_proto.values[8].null_val).is_equal_to(0) # Now convert protobuf back to json and check that feature_vector_json = MessageToDict(feature_vector_proto) - assertpy.assert_that(len(feature_vector_json["values"])).is_equal_to(9) + assertpy.assert_that(len(feature_vector_json["values"])).is_equal_to(8) assertpy.assert_that(feature_vector_json["values"][0]).is_equal_to(1) assertpy.assert_that(feature_vector_json["values"][1]).is_equal_to(2.0) assertpy.assert_that(feature_vector_json["values"][2]).is_equal_to(True) @@ -76,7 +74,6 @@ def test_feature_vector_values(proto_json_patch): assertpy.assert_that(feature_vector_json["values"][7]).is_equal_to( ["foo", "bar", "foobar"] ) - assertpy.assert_that(feature_vector_json["values"][8]).is_equal_to(None) def test_feast_repeated_value(proto_json_patch): From 6a67d76fa99d880f43301e15f3a8e343fa518725 Mon Sep 17 00:00:00 2001 From: Tsotne Tabidze Date: Fri, 14 Jan 2022 11:19:05 -0800 Subject: [PATCH 3/4] Fix java compilation & python integration tests Signed-off-by: Tsotne Tabidze --- .../logging/entry/AuditLogEntryTest.java | 26 +++++++++++++------ .../feast/infra/online_stores/dynamodb.py | 2 +- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/java/common/src/test/java/feast/common/logging/entry/AuditLogEntryTest.java b/java/common/src/test/java/feast/common/logging/entry/AuditLogEntryTest.java index 0c96ee9c56..bc3dcbcf74 100644 --- a/java/common/src/test/java/feast/common/logging/entry/AuditLogEntryTest.java +++ b/java/common/src/test/java/feast/common/logging/entry/AuditLogEntryTest.java @@ -21,11 +21,12 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import com.google.protobuf.Timestamp; import feast.common.logging.entry.LogResource.ResourceType; +import feast.proto.serving.ServingAPIProto; import feast.proto.serving.ServingAPIProto.FeatureReferenceV2; import feast.proto.serving.ServingAPIProto.GetOnlineFeaturesRequestV2; import feast.proto.serving.ServingAPIProto.GetOnlineFeaturesResponse; -import feast.proto.serving.ServingAPIProto.GetOnlineFeaturesResponse.FieldValues; import feast.proto.types.ValueProto.Value; import io.grpc.Status; import java.util.Arrays; @@ -50,15 +51,24 @@ public List getTestAuditLogs() { GetOnlineFeaturesResponse responseSpec = GetOnlineFeaturesResponse.newBuilder() - .addAllFieldValues( + .setMetadata( + ServingAPIProto.GetOnlineFeaturesResponseMetadata.newBuilder() + .setFeatureNames( + ServingAPIProto.FeatureList.newBuilder() + .addAllVal( + Arrays.asList( + "featuretable_1:feature_1", "featuretable_1:feature2")))) + .addAllResults( Arrays.asList( - FieldValues.newBuilder() - .putFields( - "featuretable_1:feature_1", Value.newBuilder().setInt32Val(32).build()) + GetOnlineFeaturesResponse.FeatureVector.newBuilder() + .addValues(Value.newBuilder().setInt32Val(32).build()) + .addStatuses(ServingAPIProto.FieldStatus.PRESENT) + .addEventTimestamps(Timestamp.newBuilder().build()) .build(), - FieldValues.newBuilder() - .putFields( - "featuretable_1:feature2", Value.newBuilder().setInt32Val(64).build()) + GetOnlineFeaturesResponse.FeatureVector.newBuilder() + .addValues(Value.newBuilder().setInt32Val(64).build()) + .addStatuses(ServingAPIProto.FieldStatus.PRESENT) + .addEventTimestamps(Timestamp.newBuilder().build()) .build())) .build(); diff --git a/sdk/python/feast/infra/online_stores/dynamodb.py b/sdk/python/feast/infra/online_stores/dynamodb.py index b7f8680e1f..46592bf2a3 100644 --- a/sdk/python/feast/infra/online_stores/dynamodb.py +++ b/sdk/python/feast/infra/online_stores/dynamodb.py @@ -173,7 +173,7 @@ def online_read( val = ValueProto() val.ParseFromString(value_bin.value) res[feature_name] = val - result.append((value["event_ts"], res)) + result.append((datetime.fromisoformat(value["event_ts"]), res)) else: result.append((None, None)) return result From eedac3c08d1d6bc792619e37101984cfd48fd3fe Mon Sep 17 00:00:00 2001 From: Tsotne Tabidze Date: Fri, 14 Jan 2022 11:45:52 -0800 Subject: [PATCH 4/4] Fix integration tests Signed-off-by: Tsotne Tabidze --- .../tests/integration/online_store/test_universal_online.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/python/tests/integration/online_store/test_universal_online.py b/sdk/python/tests/integration/online_store/test_universal_online.py index c47f2bbfd0..1f1b619cd0 100644 --- a/sdk/python/tests/integration/online_store/test_universal_online.py +++ b/sdk/python/tests/integration/online_store/test_universal_online.py @@ -212,11 +212,11 @@ def _get_online_features_dict_remotely( time.sleep(1) else: raise Exception("Failed to get online features from remote feature server") - keys = response["field_values"][0]["statuses"].keys() + keys = response["metadata"]["feature_names"] # Get rid of unnecessary structure in the response, leaving list of dicts - response = [row["fields"] for row in response["field_values"]] + response = [row["values"] for row in response["results"]] # Convert list of dicts (response) into dict of lists which is the format of the return value - return {key: [row.get(key) for row in response] for key in keys} + return {key: [row[idx] for row in response] for idx, key in enumerate(keys)} def get_online_features_dict(