@Override public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException { server.handleRequest(input, output); } }
public JsonRpcLambdaHandler(ObjectMapper mapper, Class<T> serviceClass, T service) { this.service = service; this.server = new JsonRpcBasicServer(mapper, this.service, serviceClass); this.server.setErrorResolver( new MultipleErrorResolver(new PojoErrorResolver(mapper), DefaultErrorResolver.INSTANCE)); }
private boolean acceptNonExactParam(int paramNumDiff) { return acceptMoreParam(paramNumDiff) || acceptLessParam(paramNumDiff); }
private Set<Method> collectMethodsMatchingParamCount(Set<Method> methods, int paramCount, int bestParamNumDiff) { Set<Method> matchedMethods = new HashSet<>(); // check every method for (Method method : methods) { Class<?>[] paramTypes = method.getParameterTypes(); final int paramNumDiff = paramTypes.length - paramCount; if (hasLessOrEqualAbsParamDiff(bestParamNumDiff, paramNumDiff) && acceptParamCount(paramNumDiff)) { if (hasLessAbsParamDiff(bestParamNumDiff, paramNumDiff)) { matchedMethods.clear(); } matchedMethods.add(method); bestParamNumDiff = paramNumDiff; } } return matchedMethods; }
@Test public void callOverloadedMethodExtraParams() throws Exception { EasyMock.expect(mockService.overloadedMethod(param1, param2)).andReturn(param1 + param2); EasyMock.replay(mockService); jsonRpcServer.setAllowExtraParams(true); jsonRpcServer.handleRequest(messageWithListParamsStream(1, "overloadedMethod", param1, param2, param3), byteArrayOutputStream); assertEquals(param1 + param2, decodeAnswer(byteArrayOutputStream).get(JsonRpcBasicServer.RESULT).textValue()); }
@Test public void exceptionWithoutAnnotatedServiceInterface() throws Exception { JsonRpcBasicServer jsonRpcServer = new JsonRpcBasicServer(mapper, new Service(), ServiceInterfaceWithoutAnnotation.class); jsonRpcServer.handleRequest(messageWithListParamsStream(1, "testMethod"), byteArrayOutputStream); JsonNode error = error(byteArrayOutputStream); assertNotNull(error); assertEquals(ErrorResolver.JsonError.ERROR_NOT_HANDLED.code, errorCode(error).intValue()); }
@Test public void callMethodWithTooFewParametersAllowOn() throws Exception { EasyMock.expect(mockService.testMethod(anyString())).andReturn(param1); EasyMock.replay(mockService); jsonRpcServer.setAllowLessParams(true); jsonRpcServer.handleRequest(messageWithListParamsStream(1, "testMethod"), byteArrayOutputStream); assertEquals(param1, decodeAnswer(byteArrayOutputStream).get(JsonRpcBasicServer.RESULT).textValue()); }
@SuppressWarnings("unchecked") @Test public void callConvertedParameterTransformerShouldBeCalledIfSet() throws Exception { final ConvertedParameterTransformer convertedParameterTransformer = EasyMock.niceMock(ConvertedParameterTransformer.class); EasyMock.expect(mockService.testMethod(param1)).andReturn(param1); jsonRpcServer.setConvertedParameterTransformer(convertedParameterTransformer); EasyMock.expect(convertedParameterTransformer.transformConvertedParameters(anyObject(), anyObject(Object[].class))).andReturn(new Object[]{param1}); EasyMock.replay(convertedParameterTransformer); jsonRpcServer.handleRequest(messageWithListParamsStream(1, "testMethod", param1), byteArrayOutputStream); EasyMock.verify(convertedParameterTransformer); }
/** * The {@link com.googlecode.jsonrpc4j.JsonRpcBasicServer} is able to have an instance of * {@link com.googlecode.jsonrpc4j.InvocationListener} configured for it. Prior to a * method being invoked, the lister is notified and after the method is invoked, the * listener is notified. This test checks that these two events are hit correctly * when a method is invoked. */ @SuppressWarnings("unchecked") @Test public void callMethodWithInvocationListener() throws Exception { final InvocationListener invocationListener = EasyMock.niceMock(InvocationListener.class); Method m = ServiceInterface.class.getMethod("throwsMethod", String.class); invocationListener.willInvoke(eq(m), anyObject(List.class)); invocationListener.didInvoke(eq(m), anyObject(List.class), EasyMock.notNull(), EasyMock.<Throwable>isNull(), EasyMock.geq(0L)); jsonRpcServer.setInvocationListener(invocationListener); EasyMock.expect(mockService.throwsMethod(param1)).andReturn(param1); EasyMock.replay(mockService, invocationListener); jsonRpcServer.handleRequest(messageWithListParamsStream(1, "throwsMethod", param1), byteArrayOutputStream); EasyMock.verify(invocationListener, mockService); JsonNode json = decodeAnswer(byteArrayOutputStream); assertEquals(param1, json.get(JsonRpcBasicServer.RESULT).textValue()); assertNull(json.get(JsonRpcBasicServer.ERROR)); }
/** * Finds the {@link Method} from the supplied {@link Set} that * best matches the rest of the arguments supplied and returns * it as a {@link AMethodWithItsArgs} class. * * @param methods the {@link Method}s * @param paramsNode the {@link JsonNode} passed as the parameters * @return the {@link AMethodWithItsArgs} */ private AMethodWithItsArgs findBestMethodByParamsNode(Set<Method> methods, JsonNode paramsNode) { if (hasNoParameters(paramsNode)) { return findBestMethodUsingParamIndexes(methods, 0, null); } AMethodWithItsArgs matchedMethod; if (paramsNode.isArray()) { matchedMethod = findBestMethodUsingParamIndexes(methods, paramsNode.size(), ArrayNode.class.cast(paramsNode)); } else if (paramsNode.isObject()) { matchedMethod = findBestMethodUsingParamNames(methods, collectFieldNames(paramsNode), ObjectNode.class.cast(paramsNode)); } else { throw new IllegalArgumentException("Unknown params node type: " + paramsNode.toString()); } if (matchedMethod == null) { matchedMethod = findBestMethodForVarargs(methods, paramsNode); } return matchedMethod; }
@Before public void setup() { byteArrayOutputStream = new ByteArrayOutputStream(); jsonRpcServerAnnotatedMethod = new JsonRpcBasicServer(mapper, mockService, ServiceInterfaceWithCustomMethodNameWithVarArgsAnnotation.class); }
/** * Finds the {@link Method} from the supplied {@link Set} that * best matches the rest of the arguments supplied and returns * it as a {@link AMethodWithItsArgs} class. * * @param methods the {@link Method}s * @param paramCount the number of expect parameters * @param paramNodes the parameters for matching types * @return the {@link AMethodWithItsArgs} */ private AMethodWithItsArgs findBestMethodUsingParamIndexes(Set<Method> methods, int paramCount, ArrayNode paramNodes) { int numParams = isNullNodeOrValue(paramNodes) ? 0 : paramNodes.size(); int bestParamNumDiff = Integer.MAX_VALUE; Set<Method> matchedMethods = collectMethodsMatchingParamCount(methods, paramCount, bestParamNumDiff); if (matchedMethods.isEmpty()) { return null; } Method bestMethod = getBestMatchingArgTypeMethod(paramNodes, numParams, matchedMethods); return new AMethodWithItsArgs(bestMethod, paramCount, paramNodes); }
return isNumericAssignable(type); return node.size() > 0 && isMatchingType(node.get(0), type.getComponentType()); return byteOrCharAssignable(type);
@Before public void setup() { byteArrayOutputStream = new ByteArrayOutputStream(); jsonRpcServer = new JsonRpcBasicServer(Util.mapper, mockService, ServiceInterface.class); jsonRpcServer.setInterceptorList(new ArrayList<JsonRpcInterceptor>() {{ add(mockInterceptor); }}); }
if (!acceptParamCount(typeNameCountDiff)) { continue; if (!acceptParamCount(parStat.nameCount - paramNames.size())) { continue; if (hasMoreMatches(max.nameCount, parStat.nameCount) || parStat.nameCount == max.nameCount && hasMoreMatches(max.typeCount, parStat.typeCount)) { max = parStat;
private boolean acceptParamCount(int paramNumDiff) { return paramNumDiff == 0 || acceptNonExactParam(paramNumDiff); }
@Test public void callMethodExactNumberOfParametersAllowOn() throws Exception { EasyMock.expect(mockService.testMethod(param1)).andReturn(param1); EasyMock.replay(mockService); jsonRpcServer.setAllowExtraParams(true); jsonRpcServer.handleRequest(messageWithListParamsStream(1, "testMethod", param1), byteArrayOutputStream); assertEquals(param1, decodeAnswer(byteArrayOutputStream).get(JsonRpcBasicServer.RESULT).textValue()); }
@Test public void exceptionWithAnnotatedServiceInterface() throws Exception { JsonRpcBasicServer jsonRpcServer = new JsonRpcBasicServer(mapper, new Service(), ServiceInterfaceWithAnnotation.class); jsonRpcServer.handleRequest(messageWithListParamsStream(1, "testMethod"), byteArrayOutputStream); JsonNode error = error(byteArrayOutputStream); assertNotNull(error); assertEquals(1234, errorCode(error).intValue()); assertEquals(null, errorMessage(error).textValue()); JsonNode data = errorData(error); assertNotNull(data); assertEquals(null, errorMessage(data).textValue()); assertEquals(CustomTestException.class.getName(), exceptionType(data).textValue()); }
@Test public void callMethodWithoutRequiredParamAllowOn() throws Exception { EasyMock.expect(mockService.methodWithoutRequiredParam(EasyMock.eq(param3), EasyMock.anyString())).andReturn(param3); EasyMock.replay(mockService); jsonRpcServerAnnotatedParam.setAllowLessParams(true); jsonRpcServerAnnotatedParam.handleRequest(messageWithMapParamsStream("methodWithoutRequiredParam", param1, param3), byteArrayOutputStream); assertEquals(param3, result().textValue()); }
@SuppressWarnings("unchecked") @Test public void callConvertedParameterTransformerShouldTransformTheParameters() throws Exception { final ConvertedParameterTransformer convertedParameterTransformer = EasyMock.niceMock(ConvertedParameterTransformer.class); String[] parameters = {param1, param2}; String[] expectedConvertedParameters = {param2, param1}; EasyMock.expect(mockService.overloadedMethod(param2, param1)).andReturn("converted"); jsonRpcServer.setConvertedParameterTransformer(convertedParameterTransformer); EasyMock.expect(convertedParameterTransformer.transformConvertedParameters(anyObject(), anyObject(Object[].class))).andReturn(expectedConvertedParameters); EasyMock.replay(mockService, convertedParameterTransformer); jsonRpcServer.handleRequest(messageWithListParamsStream(1, "overloadedMethod", (Object[]) parameters), byteArrayOutputStream); JsonNode json = decodeAnswer(byteArrayOutputStream); assertEquals("converted", json.get(JsonRpcBasicServer.RESULT).textValue()); assertNull(json.get(JsonRpcBasicServer.ERROR)); }