mirror of https://github.com/apache/lucene.git
SOLR-13787: Added support for PayLoad<T> as 3rd param
This commit is contained in:
parent
8bfd8a55c9
commit
2d32f0b5a6
|
@ -45,14 +45,14 @@ import org.apache.solr.response.SolrQueryResponse;
|
||||||
import org.apache.solr.security.AuthorizationContext;
|
import org.apache.solr.security.AuthorizationContext;
|
||||||
import org.apache.solr.security.PermissionNameProvider;
|
import org.apache.solr.security.PermissionNameProvider;
|
||||||
|
|
||||||
/**
|
/**This class implements an Api just from an annotated java class
|
||||||
* This class implements an Api just from an annotated java class
|
|
||||||
* The class must have an annotation {@link EndPoint}
|
* The class must have an annotation {@link EndPoint}
|
||||||
* Each method must have an annotation {@link Command}
|
* Each method must have an annotation {@link Command}
|
||||||
* The methods that implement a command should have the first 2 parameters
|
* The methods that implement a command should have the first 2 parameters
|
||||||
* {@link SolrQueryRequest} and {@link SolrQueryResponse} or it may optionally
|
* {@link SolrQueryRequest} and {@link SolrQueryResponse} or it may optionally
|
||||||
* have a third parameter which could be a java class annotated with jackson annotations.
|
* have a third parameter which could be a java class annotated with jackson annotations.
|
||||||
* The third parameter is only valid if it is using a json command payload
|
* The third parameter is only valid if it is using a json command payload
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class AnnotatedApi extends Api implements PermissionNameProvider {
|
public class AnnotatedApi extends Api implements PermissionNameProvider {
|
||||||
|
@ -62,6 +62,7 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
||||||
|
|
||||||
public AnnotatedApi(Object obj) {
|
public AnnotatedApi(Object obj) {
|
||||||
this(obj, null);
|
this(obj, null);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AnnotatedApi(Object obj, Api fallback) {
|
public AnnotatedApi(Object obj, Api fallback) {
|
||||||
|
@ -93,21 +94,21 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
||||||
|
|
||||||
private static SpecProvider readSpec(Class klas) {
|
private static SpecProvider readSpec(Class klas) {
|
||||||
EndPoint endPoint = (EndPoint) klas.getAnnotation(EndPoint.class);
|
EndPoint endPoint = (EndPoint) klas.getAnnotation(EndPoint.class);
|
||||||
if (endPoint == null)
|
if (endPoint == null) throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Invalid class : "+ klas.getName());
|
||||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Invalid class : " + klas.getName());
|
EndPoint endPoint1 = (EndPoint) klas.getAnnotation(EndPoint.class);
|
||||||
return () -> {
|
return () -> {
|
||||||
Map map = new LinkedHashMap();
|
Map map = new LinkedHashMap();
|
||||||
List<String> methods = new ArrayList<>();
|
List<String> methods = new ArrayList<>();
|
||||||
for (SolrRequest.METHOD method : endPoint.method()) {
|
for (SolrRequest.METHOD method : endPoint1.method()) {
|
||||||
methods.add(method.name());
|
methods.add(method.name());
|
||||||
}
|
}
|
||||||
map.put("methods", methods);
|
map.put("methods", methods);
|
||||||
map.put("url", new ValidatingJsonMap(Collections.singletonMap("paths", Arrays.asList(endPoint.path()))));
|
map.put("url", new ValidatingJsonMap(Collections.singletonMap("paths", Arrays.asList(endPoint1.path()))));
|
||||||
Map<String, Object> cmds = new HashMap<>();
|
Map<String, Object> cmds = new HashMap<>();
|
||||||
|
|
||||||
for (Method method : klas.getMethods()) {
|
for (Method method : klas.getMethods()) {
|
||||||
Command command = method.getAnnotation(Command.class);
|
Command command = method.getAnnotation(Command.class);
|
||||||
if (command != null && !command.name().isEmpty()) {
|
if (command != null && !command.name().isBlank()) {
|
||||||
cmds.put(command.name(), AnnotatedApi.createSchema(method));
|
cmds.put(command.name(), AnnotatedApi.createSchema(method));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,7 +132,7 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<CommandOperation> cmds = req.getCommands(false);
|
List<CommandOperation> cmds = req.getCommands(true);
|
||||||
boolean allExists = true;
|
boolean allExists = true;
|
||||||
for (CommandOperation cmd : cmds) {
|
for (CommandOperation cmd : cmds) {
|
||||||
if (!commands.containsKey(cmd.name)) {
|
if (!commands.containsKey(cmd.name)) {
|
||||||
|
@ -167,7 +168,6 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
int paramsCount;
|
int paramsCount;
|
||||||
Class c;
|
Class c;
|
||||||
boolean isWrappedInPayloadObj = false;
|
|
||||||
|
|
||||||
|
|
||||||
Cmd(Command command, Object obj, Method method) {
|
Cmd(Command command, Object obj, Method method) {
|
||||||
|
@ -181,23 +181,7 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
||||||
throw new RuntimeException("Invalid params for method " + method);
|
throw new RuntimeException("Invalid params for method " + method);
|
||||||
}
|
}
|
||||||
if (parameterTypes.length == 3) {
|
if (parameterTypes.length == 3) {
|
||||||
Type t = method.getGenericParameterTypes()[2];
|
c = parameterTypes[2];
|
||||||
if (t instanceof ParameterizedType) {
|
|
||||||
ParameterizedType typ = (ParameterizedType) t;
|
|
||||||
if (typ.getRawType() == PayloadObj.class) {
|
|
||||||
isWrappedInPayloadObj = true;
|
|
||||||
Type t1 = typ.getActualTypeArguments()[0];
|
|
||||||
if (t1 instanceof ParameterizedType) {
|
|
||||||
ParameterizedType parameterizedType = (ParameterizedType) t1;
|
|
||||||
c = (Class) parameterizedType.getRawType();
|
|
||||||
} else {
|
|
||||||
c = (Class) typ.getActualTypeArguments()[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
c = (Class) t;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (parameterTypes.length > 3) {
|
if (parameterTypes.length > 3) {
|
||||||
throw new RuntimeException("Invalid params count for method " + method);
|
throw new RuntimeException("Invalid params count for method " + method);
|
||||||
|
@ -211,6 +195,7 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
||||||
|
|
||||||
void invoke(SolrQueryRequest req, SolrQueryResponse rsp, CommandOperation cmd) {
|
void invoke(SolrQueryRequest req, SolrQueryResponse rsp, CommandOperation cmd) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (paramsCount == 2) {
|
if (paramsCount == 2) {
|
||||||
method.invoke(obj, req, rsp);
|
method.invoke(obj, req, rsp);
|
||||||
} else {
|
} else {
|
||||||
|
@ -218,26 +203,14 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
||||||
if (o instanceof Map && c != null) {
|
if (o instanceof Map && c != null) {
|
||||||
o = mapper.readValue(Utils.toJSONString(o), c);
|
o = mapper.readValue(Utils.toJSONString(o), c);
|
||||||
}
|
}
|
||||||
if (isWrappedInPayloadObj) {
|
method.invoke(obj, req, rsp, o);
|
||||||
PayloadObj<Object> payloadObj = new PayloadObj<>(cmd.name, cmd.getCommandData(), o);
|
|
||||||
cmd = payloadObj;
|
|
||||||
method.invoke(obj, req, rsp, payloadObj);
|
|
||||||
} else {
|
|
||||||
method.invoke(obj, req, rsp, o);
|
|
||||||
}
|
|
||||||
if (cmd.hasError()) {
|
|
||||||
throw new ApiBag.ExceptionWithErrObject(SolrException.ErrorCode.BAD_REQUEST, "Error executing command",
|
|
||||||
CommandOperation.captureErrors(Collections.singletonList(cmd)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} catch (SolrException se) {
|
} catch (SolrException se) {
|
||||||
throw se;
|
throw se;
|
||||||
} catch (InvocationTargetException ite) {
|
} catch (InvocationTargetException ite) {
|
||||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, ite.getCause());
|
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, ite.getCause());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -270,15 +243,11 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
||||||
|
|
||||||
private static Map<String, Object> createSchemaFromType(Type t) {
|
private static Map<String, Object> createSchemaFromType(Type t) {
|
||||||
Map<String, Object> map = new LinkedHashMap<>();
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
if (t instanceof ParameterizedType) {
|
|
||||||
ParameterizedType typ = (ParameterizedType) t;
|
|
||||||
if (typ.getRawType() == PayloadObj.class) {
|
|
||||||
t = typ.getActualTypeArguments()[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (primitives.containsKey(t)) {
|
if (primitives.containsKey(t)) {
|
||||||
map.put("type", primitives.get(t));
|
map.put("type", primitives.get(t));
|
||||||
|
} else if (t == List.class) {
|
||||||
|
|
||||||
} else if (t instanceof ParameterizedType && ((ParameterizedType) t).getRawType() == List.class) {
|
} else if (t instanceof ParameterizedType && ((ParameterizedType) t).getRawType() == List.class) {
|
||||||
Type typ = ((ParameterizedType) t).getActualTypeArguments()[0];
|
Type typ = ((ParameterizedType) t).getActualTypeArguments()[0];
|
||||||
map.put("type", "array");
|
map.put("type", "array");
|
||||||
|
|
|
@ -32,4 +32,6 @@ public @interface Command {
|
||||||
*/
|
*/
|
||||||
String name() default "";
|
String name() default "";
|
||||||
|
|
||||||
|
String jsonSchema() default "";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You 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 org.apache.solr.api;
|
|
||||||
|
|
||||||
import org.apache.solr.common.util.CommandOperation;
|
|
||||||
|
|
||||||
public class PayloadObj<T> extends CommandOperation {
|
|
||||||
|
|
||||||
private T obj;
|
|
||||||
|
|
||||||
|
|
||||||
public PayloadObj(String operationName, Object metaData, T obj) {
|
|
||||||
super(operationName, metaData);
|
|
||||||
this.obj = obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T get(){
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You 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 org.apache.solr.util;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import org.apache.solr.common.MapWriter;
|
|
||||||
|
|
||||||
public interface ReflectMapWriter extends MapWriter {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void writeMap(EntryWriter ew) throws IOException {
|
|
||||||
for (Field field : this.getClass().getDeclaredFields()) {
|
|
||||||
JsonProperty prop = field.getAnnotation(JsonProperty.class);
|
|
||||||
if (prop == null) continue;
|
|
||||||
int modifiers = field.getModifiers();
|
|
||||||
if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
|
|
||||||
String fname = prop.value().isEmpty() ? field.getName() : prop.value();
|
|
||||||
try {
|
|
||||||
if (field.getType() == int.class) {
|
|
||||||
ew.put(fname, field.getInt(this));
|
|
||||||
} else if (field.getType() == float.class) {
|
|
||||||
ew.put(fname, field.getFloat(this));
|
|
||||||
} else if (field.getType() == double.class) {
|
|
||||||
ew.put(fname, field.getDouble(this));
|
|
||||||
} else if (field.getType() == boolean.class) {
|
|
||||||
ew.put(fname, field.getBoolean(this));
|
|
||||||
} else if (field.getType() == long.class) {
|
|
||||||
ew.put(fname, field.getLong(this));
|
|
||||||
} else {
|
|
||||||
ew.putIfNotNull(fname, field.get(this));
|
|
||||||
}
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
//it should not happen
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -168,7 +168,7 @@ public class TestApiFramework extends SolrTestCaseJ4 {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPayload() {
|
public void testPayload() throws IOException {
|
||||||
String json = "{package:pkg1, version: '0.1', files :[a.jar, b.jar]}";
|
String json = "{package:pkg1, version: '0.1', files :[a.jar, b.jar]}";
|
||||||
Utils.fromJSONString(json);
|
Utils.fromJSONString(json);
|
||||||
|
|
||||||
|
@ -213,6 +213,8 @@ public class TestApiFramework extends SolrTestCaseJ4 {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AddVersion {
|
public static class AddVersion {
|
||||||
|
|
Loading…
Reference in New Issue