Skip to content

Commit

Permalink
Added a custom request plugin (#444)
Browse files Browse the repository at this point in the history
* Added a custom request plugin

* Spotless apply

* Changed how routes are defined and added tests

* Alphabetized code block

* Re-ran buildGrpcGateway after merge

* Added path as a parameter to RequestProcessor

* Added id and path as request parameters

* Testing path and added some javadoc for RequestProcessor

* Spotless apply
  • Loading branch information
sarthakn7 authored Apr 28, 2022
1 parent 8b1e50c commit 3cea509
Show file tree
Hide file tree
Showing 12 changed files with 1,305 additions and 502 deletions.
20 changes: 20 additions & 0 deletions clientlib/src/main/proto/yelp/nrtsearch/luceneserver.proto
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,16 @@ service LuceneServer {
body: "*"
};
}

/*
Process request in a plugin which implements CustomRequestPlugin interface.
*/
rpc custom(CustomRequest) returns (CustomResponse) {
option (google.api.http) = {
post: "/v1/custom/{id}/{path}"
body: "*"
};
}
}

//The ReplicationServer service definition.
Expand Down Expand Up @@ -1048,4 +1058,14 @@ message IndexStateInfo {
IndexLiveSettings liveSettings = 5;
// Registered fields
map<string, Field> fields = 6;
}

message CustomRequest {
string id = 1; // ID defined for custom requests in a plugin
string path = 2; // Custom path that is defined in a plugin that maps to a route
map<string, string> params = 3; // Parameters that can be processed by the plugin at the specified path
}

message CustomResponse {
map<string, string> response = 1; // Custom response sent by the plugin
}
1,213 changes: 711 additions & 502 deletions grpc-gateway/luceneserver.pb.go

Large diffs are not rendered by default.

139 changes: 139 additions & 0 deletions grpc-gateway/luceneserver.pb.gw.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

73 changes: 73 additions & 0 deletions grpc-gateway/luceneserver.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,51 @@
]
}
},
"/v1/custom/{id}/{path}": {
"post": {
"summary": "Process request in a plugin which implements CustomRequestPlugin interface.",
"operationId": "LuceneServer_custom",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/luceneserverCustomResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/runtimeError"
}
}
},
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "path",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/luceneserverCustomRequest"
}
}
],
"tags": [
"LuceneServer"
]
}
},
"/v1/delete": {
"post": {
"summary": "Delete documents",
Expand Down Expand Up @@ -2352,6 +2397,34 @@
}
}
},
"luceneserverCustomRequest": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"path": {
"type": "string"
},
"params": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
},
"luceneserverCustomResponse": {
"type": "object",
"properties": {
"response": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
},
"luceneserverDeleteAllDocumentsRequest": {
"type": "object",
"properties": {
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/com/yelp/nrtsearch/server/grpc/LuceneServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.yelp.nrtsearch.server.luceneserver.*;
import com.yelp.nrtsearch.server.luceneserver.AddDocumentHandler.DocumentIndexer;
import com.yelp.nrtsearch.server.luceneserver.analysis.AnalyzerCreator;
import com.yelp.nrtsearch.server.luceneserver.custom.request.CustomRequestProcessor;
import com.yelp.nrtsearch.server.luceneserver.field.FieldDefCreator;
import com.yelp.nrtsearch.server.luceneserver.index.IndexStateManager;
import com.yelp.nrtsearch.server.luceneserver.index.handlers.FieldUpdateHandler;
Expand Down Expand Up @@ -396,6 +397,7 @@ private void initExtendableComponents(
LuceneServerConfiguration configuration, List<Plugin> plugins) {
AnalyzerCreator.initialize(configuration, plugins);
CollectorCreator.initialize(configuration, plugins);
CustomRequestProcessor.initialize(configuration, plugins);
FetchTaskCreator.initialize(configuration, plugins);
FieldDefCreator.initialize(configuration, plugins);
RescorerCreator.initialize(configuration, plugins);
Expand Down Expand Up @@ -1796,6 +1798,17 @@ public void forceMergeDeletes(
responseObserver.onNext(response);
responseObserver.onCompleted();
}

@Override
public void custom(CustomRequest request, StreamObserver<CustomResponse> responseObserver) {
try {
CustomResponse response = CustomRequestProcessor.processCustomRequest(request);
responseObserver.onNext(response);
responseObserver.onCompleted();
} catch (Exception e) {
responseObserver.onError(e);
}
}
}

static class ReplicationServerImpl extends ReplicationServerGrpc.ReplicationServerImplBase {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright 2022 Yelp Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.yelp.nrtsearch.server.luceneserver.custom.request;

import com.yelp.nrtsearch.server.config.LuceneServerConfiguration;
import com.yelp.nrtsearch.server.grpc.CustomRequest;
import com.yelp.nrtsearch.server.grpc.CustomResponse;
import com.yelp.nrtsearch.server.plugins.CustomRequestPlugin;
import com.yelp.nrtsearch.server.plugins.Plugin;
import java.util.HashMap;
import java.util.Map;

public class CustomRequestProcessor {

private static CustomRequestProcessor instance;
private final Map<String, Map<String, CustomRequestPlugin.RequestProcessor>> routeMapping =
new HashMap<>();

public CustomRequestProcessor(LuceneServerConfiguration configuration) {}

public static void initialize(LuceneServerConfiguration configuration, Iterable<Plugin> plugins) {
instance = new CustomRequestProcessor(configuration);
for (Plugin plugin : plugins) {
if (plugin instanceof CustomRequestPlugin) {
instance.registerRoutes((CustomRequestPlugin) plugin);
}
}
}

public static CustomResponse processCustomRequest(CustomRequest request) {
if (!instance.routeMapping.containsKey(request.getId())) {
throw new RouteNotFoundException(request.getId());
}
Map<String, CustomRequestPlugin.RequestProcessor> routesForId =
instance.routeMapping.get(request.getId());
if (!routesForId.containsKey(request.getPath())) {
throw new RouteNotFoundException(request.getId(), request.getPath());
}
Map<String, String> response =
routesForId.get(request.getPath()).process(request.getPath(), request.getParamsMap());
return CustomResponse.newBuilder().putAllResponse(response).build();
}

private void registerRoutes(CustomRequestPlugin plugin) {
String id = plugin.id();
if (routeMapping.containsKey(id)) {
throw new DuplicateRouteException(id);
}
Map<String, CustomRequestPlugin.RequestProcessor> routesForId = new HashMap<>();
for (Map.Entry<String, CustomRequestPlugin.RequestProcessor> route :
plugin.getRoutes().entrySet()) {
String path = route.getKey();
routesForId.put(path, route.getValue());
}
routeMapping.put(id, routesForId);
}
}
Loading

0 comments on commit 3cea509

Please sign in to comment.