mirror of https://github.com/apache/lucene.git
SOLR-13827: Added support for PayLoad<T> as 3rd param
This commit is contained in:
parent
bed9e7c474
commit
8bfd8a55c9
|
@ -45,14 +45,14 @@ import org.apache.solr.response.SolrQueryResponse;
|
|||
import org.apache.solr.security.AuthorizationContext;
|
||||
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}
|
||||
* Each method must have an annotation {@link Command}
|
||||
* The methods that implement a command should have the first 2 parameters
|
||||
* {@link SolrQueryRequest} and {@link SolrQueryResponse} or it may optionally
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
public class AnnotatedApi extends Api implements PermissionNameProvider {
|
||||
|
@ -62,7 +62,6 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
|||
|
||||
public AnnotatedApi(Object obj) {
|
||||
this(obj, null);
|
||||
|
||||
}
|
||||
|
||||
public AnnotatedApi(Object obj, Api fallback) {
|
||||
|
@ -94,21 +93,21 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
|||
|
||||
private static SpecProvider readSpec(Class klas) {
|
||||
EndPoint endPoint = (EndPoint) klas.getAnnotation(EndPoint.class);
|
||||
if (endPoint == null) throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Invalid class : "+ klas.getName());
|
||||
EndPoint endPoint1 = (EndPoint) klas.getAnnotation(EndPoint.class);
|
||||
if (endPoint == null)
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Invalid class : " + klas.getName());
|
||||
return () -> {
|
||||
Map map = new LinkedHashMap();
|
||||
List<String> methods = new ArrayList<>();
|
||||
for (SolrRequest.METHOD method : endPoint1.method()) {
|
||||
for (SolrRequest.METHOD method : endPoint.method()) {
|
||||
methods.add(method.name());
|
||||
}
|
||||
map.put("methods", methods);
|
||||
map.put("url", new ValidatingJsonMap(Collections.singletonMap("paths", Arrays.asList(endPoint1.path()))));
|
||||
map.put("url", new ValidatingJsonMap(Collections.singletonMap("paths", Arrays.asList(endPoint.path()))));
|
||||
Map<String, Object> cmds = new HashMap<>();
|
||||
|
||||
for (Method method : klas.getMethods()) {
|
||||
Command command = method.getAnnotation(Command.class);
|
||||
if (command != null && !command.name().isBlank()) {
|
||||
if (command != null && !command.name().isEmpty()) {
|
||||
cmds.put(command.name(), AnnotatedApi.createSchema(method));
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +131,7 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
|||
}
|
||||
}
|
||||
|
||||
List<CommandOperation> cmds = req.getCommands(true);
|
||||
List<CommandOperation> cmds = req.getCommands(false);
|
||||
boolean allExists = true;
|
||||
for (CommandOperation cmd : cmds) {
|
||||
if (!commands.containsKey(cmd.name)) {
|
||||
|
@ -168,6 +167,7 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
|||
ObjectMapper mapper = new ObjectMapper();
|
||||
int paramsCount;
|
||||
Class c;
|
||||
boolean isWrappedInPayloadObj = false;
|
||||
|
||||
|
||||
Cmd(Command command, Object obj, Method method) {
|
||||
|
@ -181,7 +181,23 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
|||
throw new RuntimeException("Invalid params for method " + method);
|
||||
}
|
||||
if (parameterTypes.length == 3) {
|
||||
c = parameterTypes[2];
|
||||
Type t = method.getGenericParameterTypes()[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) {
|
||||
throw new RuntimeException("Invalid params count for method " + method);
|
||||
|
@ -195,7 +211,6 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
|||
|
||||
void invoke(SolrQueryRequest req, SolrQueryResponse rsp, CommandOperation cmd) {
|
||||
try {
|
||||
|
||||
if (paramsCount == 2) {
|
||||
method.invoke(obj, req, rsp);
|
||||
} else {
|
||||
|
@ -203,14 +218,26 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
|||
if (o instanceof Map && c != null) {
|
||||
o = mapper.readValue(Utils.toJSONString(o), c);
|
||||
}
|
||||
method.invoke(obj, req, rsp, o);
|
||||
if (isWrappedInPayloadObj) {
|
||||
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) {
|
||||
throw se;
|
||||
} catch (InvocationTargetException ite) {
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, ite.getCause());
|
||||
} catch (Exception e) {
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -243,11 +270,15 @@ public class AnnotatedApi extends Api implements PermissionNameProvider {
|
|||
|
||||
private static Map<String, Object> createSchemaFromType(Type t) {
|
||||
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)) {
|
||||
map.put("type", primitives.get(t));
|
||||
} else if (t == List.class) {
|
||||
|
||||
} else if (t instanceof ParameterizedType && ((ParameterizedType) t).getRawType() == List.class) {
|
||||
Type typ = ((ParameterizedType) t).getActualTypeArguments()[0];
|
||||
map.put("type", "array");
|
||||
|
|
|
@ -32,6 +32,4 @@ public @interface Command {
|
|||
*/
|
||||
String name() default "";
|
||||
|
||||
String jsonSchema() default "";
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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() throws IOException {
|
||||
public void testPayload() {
|
||||
String json = "{package:pkg1, version: '0.1', files :[a.jar, b.jar]}";
|
||||
Utils.fromJSONString(json);
|
||||
|
||||
|
@ -213,8 +213,6 @@ public class TestApiFramework extends SolrTestCaseJ4 {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static class AddVersion {
|
||||
|
|
Loading…
Reference in New Issue