use of org.apache.solr.api.Api in project lucene-solr by apache.
the class UpdateRequestHandlerApi method getApiImpl.
private Api getApiImpl() {
return new Api(ApiBag.getSpec("core.Update")) {
@Override
public void call(SolrQueryRequest req, SolrQueryResponse rsp) {
String path = req.getPath();
String target = mapping.get(path);
if (target != null)
req.getContext().put("path", target);
try {
handleRequest(req, rsp);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e);
}
}
};
}
use of org.apache.solr.api.Api in project lucene-solr by apache.
the class BaseHandlerApiSupport method getApi.
private Api getApi(final V2EndPoint op) {
final BaseHandlerApiSupport apiHandler = this;
return new Api(ApiBag.getSpec(op.getSpecName())) {
@Override
public void call(SolrQueryRequest req, SolrQueryResponse rsp) {
SolrParams params = req.getParams();
SolrRequest.METHOD method = SolrRequest.METHOD.valueOf(req.getHttpMethod());
List<ApiCommand> commands = commandsMapping.get(method).get(op);
try {
if (method == POST) {
List<CommandOperation> cmds = req.getCommands(true);
if (cmds.size() > 1)
throw new SolrException(BAD_REQUEST, "Only one command is allowed");
CommandOperation c = cmds.size() == 0 ? null : cmds.get(0);
ApiCommand command = null;
String commandName = c == null ? null : c.name;
for (ApiCommand cmd : commands) {
if (Objects.equals(cmd.meta().getName(), commandName)) {
command = cmd;
break;
}
}
if (command == null) {
throw new SolrException(BAD_REQUEST, " no such command " + c);
}
wrapParams(req, c, command, false);
command.invoke(req, rsp, apiHandler);
} else {
if (commands == null || commands.isEmpty()) {
rsp.add("error", "No support for : " + method + " at :" + req.getPath());
return;
}
if (commands.size() > 1) {
for (ApiCommand command : commands) {
if (command.meta().getName().equals(req.getPath())) {
commands = Collections.singletonList(command);
break;
}
}
}
wrapParams(req, new CommandOperation("", Collections.EMPTY_MAP), commands.get(0), true);
commands.get(0).invoke(req, rsp, apiHandler);
}
} catch (SolrException e) {
throw e;
} catch (Exception e) {
throw new SolrException(BAD_REQUEST, e);
} finally {
req.setParams(params);
}
}
};
}
use of org.apache.solr.api.Api in project lucene-solr by apache.
the class TestApiFramework method testFramework.
public void testFramework() {
Map<String, Object[]> calls = new HashMap<>();
Map<String, Object> out = new HashMap<>();
CoreContainer mockCC = TestCoreAdminApis.getCoreContainerMock(calls, out);
PluginBag<SolrRequestHandler> containerHandlers = new PluginBag<>(SolrRequestHandler.class, null, false);
containerHandlers.put(COLLECTIONS_HANDLER_PATH, new TestCollectionAPIs.MockCollectionsHandler());
containerHandlers.put(CORES_HANDLER_PATH, new CoreAdminHandler(mockCC));
containerHandlers.put(CONFIGSETS_HANDLER_PATH, new ConfigSetsHandler(mockCC));
out.put("getRequestHandlers", containerHandlers);
PluginBag<SolrRequestHandler> coreHandlers = new PluginBag<>(SolrRequestHandler.class, null, false);
coreHandlers.put("/schema", new SchemaHandler());
coreHandlers.put("/config", new SolrConfigHandler());
coreHandlers.put("/admin/ping", new PingRequestHandler());
Map<String, String> parts = new HashMap<>();
String fullPath = "/collections/hello/shards";
Api api = V2HttpCall.getApiInfo(containerHandlers, fullPath, "POST", fullPath, parts);
assertNotNull(api);
assertConditions(api.getSpec(), Utils.makeMap("/methods[0]", "POST", "/commands/create", NOT_NULL));
assertEquals("hello", parts.get("collection"));
parts = new HashMap<>();
api = V2HttpCall.getApiInfo(containerHandlers, "/collections/hello/shards", "POST", null, parts);
assertConditions(api.getSpec(), Utils.makeMap("/methods[0]", "POST", "/commands/split", NOT_NULL, "/commands/add-replica", NOT_NULL));
parts = new HashMap<>();
api = V2HttpCall.getApiInfo(containerHandlers, "/collections/hello/shards/shard1", "POST", null, parts);
assertConditions(api.getSpec(), Utils.makeMap("/methods[0]", "POST", "/commands/force-leader", NOT_NULL));
assertEquals("hello", parts.get("collection"));
assertEquals("shard1", parts.get("shard"));
parts = new HashMap<>();
api = V2HttpCall.getApiInfo(containerHandlers, "/collections/hello", "POST", null, parts);
assertConditions(api.getSpec(), Utils.makeMap("/methods[0]", "POST", "/commands/add-replica-property", NOT_NULL, "/commands/delete-replica-property", NOT_NULL));
assertEquals("hello", parts.get("collection"));
api = V2HttpCall.getApiInfo(containerHandlers, "/collections/hello/shards/shard1/replica1", "DELETE", null, parts);
assertConditions(api.getSpec(), Utils.makeMap("/methods[0]", "DELETE", "/url/params/onlyIfDown/type", "boolean"));
assertEquals("hello", parts.get("collection"));
assertEquals("shard1", parts.get("shard"));
assertEquals("replica1", parts.get("replica"));
SolrQueryResponse rsp = invoke(containerHandlers, null, "/collections/_introspect", GET, mockCC);
assertConditions(rsp.getValues().asMap(2), Utils.makeMap("/spec[0]/methods[0]", "DELETE", "/spec[1]/methods[0]", "POST", "/spec[2]/methods[0]", "GET"));
rsp = invoke(coreHandlers, "/schema/_introspect", "/collections/hello/schema/_introspect", GET, mockCC);
assertConditions(rsp.getValues().asMap(2), Utils.makeMap("/spec[0]/methods[0]", "POST", "/spec[0]/commands", NOT_NULL, "/spec[1]/methods[0]", "GET"));
rsp = invoke(coreHandlers, "/", "/collections/hello/_introspect", GET, mockCC);
assertConditions(rsp.getValues().asMap(2), Utils.makeMap("/availableSubPaths", NOT_NULL, "availableSubPaths /collections/hello/config/jmx", NOT_NULL, "availableSubPaths /collections/hello/schema", NOT_NULL, "availableSubPaths /collections/hello/shards", NOT_NULL, "availableSubPaths /collections/hello/shards/{shard}", NOT_NULL, "availableSubPaths /collections/hello/shards/{shard}/{replica}", NOT_NULL));
}
use of org.apache.solr.api.Api in project lucene-solr by apache.
the class TestApiFramework method invoke.
private SolrQueryResponse invoke(PluginBag<SolrRequestHandler> reqHandlers, String path, String fullPath, SolrRequest.METHOD method, CoreContainer mockCC) {
HashMap<String, String> parts = new HashMap<>();
boolean containerHandlerLookup = mockCC.getRequestHandlers() == reqHandlers;
path = path == null ? fullPath : path;
Api api = null;
if (containerHandlerLookup) {
api = V2HttpCall.getApiInfo(reqHandlers, path, "GET", fullPath, parts);
} else {
api = V2HttpCall.getApiInfo(mockCC.getRequestHandlers(), fullPath, "GET", fullPath, parts);
if (api == null)
api = new CompositeApi(null);
if (api instanceof CompositeApi) {
CompositeApi compositeApi = (CompositeApi) api;
api = V2HttpCall.getApiInfo(reqHandlers, path, "GET", fullPath, parts);
compositeApi.add(api);
api = compositeApi;
}
}
SolrQueryResponse rsp = new SolrQueryResponse();
LocalSolrQueryRequest req = new LocalSolrQueryRequest(null, new MapSolrParams(new HashMap<>())) {
@Override
public List<CommandOperation> getCommands(boolean validateInput) {
return Collections.emptyList();
}
};
api.call(req, rsp);
return rsp;
}
use of org.apache.solr.api.Api in project lucene-solr by apache.
the class TestCollectionAPIs method testCommands.
public void testCommands() throws Exception {
MockCollectionsHandler collectionsHandler = new MockCollectionsHandler();
ApiBag apiBag = new ApiBag(false);
Collection<Api> apis = collectionsHandler.getApis();
for (Api api : apis) apiBag.register(api, Collections.emptyMap());
//test a simple create collection call
compareOutput(apiBag, "/collections", POST, "{create:{name:'newcoll', config:'schemaless', numShards:2, replicationFactor:2 }}", null, "{name:newcoll, fromApi:'true', replicationFactor:'2', collection.configName:schemaless, numShards:'2', stateFormat:'2', operation:create}");
compareOutput(apiBag, "/collections", POST, "{create:{name:'newcoll', config:'schemaless', numShards:2, nrtReplicas:2 }}", null, "{name:newcoll, fromApi:'true', nrtReplicas:'2', collection.configName:schemaless, numShards:'2', stateFormat:'2', operation:create}");
compareOutput(apiBag, "/collections", POST, "{create:{name:'newcoll', config:'schemaless', numShards:2, nrtReplicas:2, tlogReplicas:2, pullReplicas:2 }}", null, "{name:newcoll, fromApi:'true', nrtReplicas:'2', tlogReplicas:'2', pullReplicas:'2', collection.configName:schemaless, numShards:'2', stateFormat:'2', operation:create}");
//test a create collection with custom properties
compareOutput(apiBag, "/collections", POST, "{create:{name:'newcoll', config:'schemaless', numShards:2, replicationFactor:2, properties:{prop1:'prop1val', prop2: prop2val} }}", null, "{name:newcoll, fromApi:'true', replicationFactor:'2', collection.configName:schemaless, numShards:'2', stateFormat:'2', operation:create, property.prop1:prop1val, property.prop2:prop2val}");
compareOutput(apiBag, "/collections", POST, "{create-alias:{name: aliasName , collections:[c1,c2] }}", null, "{operation : createalias, name: aliasName, collections:[c1,c2] }");
compareOutput(apiBag, "/collections", POST, "{delete-alias:{ name: aliasName}}", null, "{operation : deletealias, name: aliasName}");
compareOutput(apiBag, "/collections/collName", POST, "{reload:{}}", null, "{name:collName, operation :reload}");
compareOutput(apiBag, "/collections/collName", DELETE, null, null, "{name:collName, operation :delete}");
compareOutput(apiBag, "/collections/collName/shards/shard1", DELETE, null, null, "{collection:collName, shard: shard1 , operation :deleteshard }");
compareOutput(apiBag, "/collections/collName/shards/shard1/replica1?deleteDataDir=true&onlyIfDown=true", DELETE, null, null, "{collection:collName, shard: shard1, replica :replica1 , deleteDataDir:'true', onlyIfDown: 'true', operation :deletereplica }");
compareOutput(apiBag, "/collections/collName/shards", POST, "{split:{shard:shard1, ranges: '0-1f4,1f5-3e8,3e9-5dc', coreProperties : {prop1:prop1Val, prop2:prop2Val} }}", null, "{collection: collName , shard : shard1, ranges :'0-1f4,1f5-3e8,3e9-5dc', operation : splitshard, property.prop1:prop1Val, property.prop2: prop2Val}");
compareOutput(apiBag, "/collections/collName/shards", POST, "{add-replica:{shard: shard1, node: 'localhost_8978' , coreProperties : {prop1:prop1Val, prop2:prop2Val} }}", null, "{collection: collName , shard : shard1, node :'localhost_8978', operation : addreplica, property.prop1:prop1Val, property.prop2: prop2Val}");
compareOutput(apiBag, "/collections/collName/shards", POST, "{split:{ splitKey:id12345, coreProperties : {prop1:prop1Val, prop2:prop2Val} }}", null, "{collection: collName , split.key : id12345 , operation : splitshard, property.prop1:prop1Val, property.prop2: prop2Val}");
compareOutput(apiBag, "/collections/collName/shards", POST, "{add-replica:{shard: shard1, node: 'localhost_8978' , type:'TLOG' }}", null, "{collection: collName , shard : shard1, node :'localhost_8978', operation : addreplica, type: TLOG}");
compareOutput(apiBag, "/collections/collName/shards", POST, "{add-replica:{shard: shard1, node: 'localhost_8978' , type:'PULL' }}", null, "{collection: collName , shard : shard1, node :'localhost_8978', operation : addreplica, type: PULL}");
assertErrorContains(apiBag, "/collections/collName/shards", POST, "{add-replica:{shard: shard1, node: 'localhost_8978' , type:'foo' }}", null, "Value of enum must be one of");
compareOutput(apiBag, "/collections/collName", POST, "{add-replica-property : {name:propA , value: VALA, shard: shard1, replica:replica1}}", null, "{collection: collName, shard: shard1, replica : replica1 , property : propA , operation : addreplicaprop, property.value : 'VALA'}");
compareOutput(apiBag, "/collections/collName", POST, "{delete-replica-property : {property: propA , shard: shard1, replica:replica1} }", null, "{collection: collName, shard: shard1, replica : replica1 , property : propA , operation : deletereplicaprop}");
compareOutput(apiBag, "/collections/collName", POST, "{modify : {rule : ['replica:*, cores:<5'], autoAddReplicas : false} }", null, "{collection: collName, operation : modifycollection , autoAddReplicas : 'false', rule : [{replica: '*', cores : '<5' }]}");
compareOutput(apiBag, "/cluster", POST, "{add-role : {role : overseer, node : 'localhost_8978'} }", null, "{operation : addrole ,role : overseer, node : 'localhost_8978'}");
compareOutput(apiBag, "/cluster", POST, "{remove-role : {role : overseer, node : 'localhost_8978'} }", null, "{operation : removerole ,role : overseer, node : 'localhost_8978'}");
compareOutput(apiBag, "/collections/coll1", POST, "{balance-shard-unique : {property: preferredLeader} }", null, "{operation : balanceshardunique ,collection : coll1, property : preferredLeader}");
compareOutput(apiBag, "/collections/coll1", POST, "{migrate-docs : {forwardTimeout: 1800, target: coll2, splitKey: 'a123!'} }", null, "{operation : migrate ,collection : coll1, target.collection:coll2, forward.timeout:1800, split.key:'a123!'}");
}
Aggregations