@Override public final boolean process(final TProtocol in, final TProtocol out) throws TException { final TMessage msg = in.readMessageBegin(); final ProcessFunction<LocatorServiceImpl, ?> fn = this.fnMap .get(msg.name); if (fn != null) { fn.process(msg.seqid, in, out, this.inst); // terminate connection on receiving closeConnection // direct class comparison should be the fastest way return fn.getClass() != LocatorService.Processor.closeConnection.class; } else { TProtocolUtil.skip(in, TType.STRUCT); in.readMessageEnd(); TApplicationException x = new TApplicationException( TApplicationException.UNKNOWN_METHOD, "Invalid method name: '" + msg.name + "'"); out.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid)); x.write(out); out.writeMessageEnd(); out.getTransport().flush(); return true; } }
private static void invokeSynchronously( ServiceRequestContext ctx, Object impl, ThriftFunction func, TBase<?, ?> args, DefaultRpcResponse reply) { final ProcessFunction<Object, TBase<?, ?>> f = func.syncFunc(); ctx.blockingTaskExecutor().execute(() -> { if (reply.isDone()) { // Closed already most likely due to timeout. return; } try { final TBase<?, ?> result = f.getResult(impl, args); if (func.isOneWay()) { reply.complete(null); } else { reply.complete(func.getResult(result)); } } catch (Throwable t) { reply.completeExceptionally(t); } }); }
@SuppressWarnings("rawtypes") private void registerFunction(Set<String> methodNames, Class<?> iface, String name, Object func) { checkDuplicateMethodName(methodNames, name); methodNames.add(name); try { final ThriftFunction f; if (func instanceof ProcessFunction) { f = new ThriftFunction(iface, (ProcessFunction) func); } else { f = new ThriftFunction(iface, (AsyncProcessFunction) func); } functions.put(name, f); } catch (Exception e) { throw new IllegalArgumentException("failed to retrieve function metadata: " + iface.getName() + '.' + name + "()", e); } }
@Override public final boolean process(final TProtocol in, final TProtocol out) throws TException { final TMessage msg = in.readMessageBegin(); final ProcessFunction<GFXDServiceImpl, ?> fn = this.fnMap.get(msg.name); if (fn != null) { fn.process(msg.seqid, in, out, this.inst); // terminate connection on receiving closeConnection // direct class comparison should be the fastest way // TODO: SW: also need to clean up connection artifacts in the case of // client connection failure (ConnectionListener does get a notification // but how to tie the socket/connectionNumber to the connectionID?) return fn.getClass() != GFXDService.Processor.closeConnection.class; } else { TProtocolUtil.skip(in, TType.STRUCT); in.readMessageEnd(); TApplicationException x = new TApplicationException( TApplicationException.UNKNOWN_METHOD, "Invalid method name: '" + msg.name + "'"); out.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid)); x.write(out); out.writeMessageEnd(); out.getTransport().flush(); return true; } }
/** * Constructs the map from function name -> handler. * @param calls The call queue. * @return The map. */ private static Map<String, ProcessFunction> getProcessMap( LinkedBlockingQueue<TBase> calls) { Map<String, ProcessFunction> processMap = new HashMap<String, ProcessFunction>(); processMap.put("grantResource", new grantResourceHandler(calls)); processMap.put("revokeResource", new revokeResourceHandler(calls)); processMap.put("processDeadNode", new processDeadNodeHandler(calls)); return processMap; }
private Set<Class<?>> init(Object implementation, Iterable<Class<?>> candidateInterfaces) { // Build the map of method names and their corresponding process functions. final Set<String> methodNames = new HashSet<>(); final Set<Class<?>> interfaces = new HashSet<>(); for (Class<?> iface : candidateInterfaces) { final Map<String, AsyncProcessFunction<?, ?, ?>> asyncProcessMap; asyncProcessMap = getThriftAsyncProcessMap(implementation, iface); if (asyncProcessMap != null) { asyncProcessMap.forEach( (name, func) -> registerFunction(methodNames, iface, name, func)); interfaces.add(iface); } final Map<String, ProcessFunction<?, ?>> processMap; processMap = getThriftProcessMap(implementation, iface); if (processMap != null) { processMap.forEach( (name, func) -> registerFunction(methodNames, iface, name, func)); interfaces.add(iface); } } if (functions.isEmpty()) { if (implementation != null) { throw new IllegalArgumentException('\'' + implementation.getClass().getName() + "' is not a Thrift service implementation."); } else { throw new IllegalArgumentException("not a Thrift service interface: " + candidateInterfaces); } } return Collections.unmodifiableSet(interfaces); }
private static Map<String, ProcessFunction<?, ?>> getThriftProcessMap(Object service, Class<?> iface) { final String name = iface.getName(); if (!name.endsWith("$Iface")) { return null; } final String processorName = name.substring(0, name.length() - 5) + "Processor"; try { final Class<?> processorClass = Class.forName(processorName, false, iface.getClassLoader()); if (!TBaseProcessor.class.isAssignableFrom(processorClass)) { return null; } final Constructor<?> processorConstructor = processorClass.getConstructor(iface); @SuppressWarnings("rawtypes") final TBaseProcessor processor = (TBaseProcessor) processorConstructor.newInstance(service); @SuppressWarnings("unchecked") Map<String, ProcessFunction<?, ?>> processMap = (Map<String, ProcessFunction<?, ?>>) processor.getProcessMapView(); return processMap; } catch (Exception e) { logger.debug("Failed to retrieve the process map from: {}", iface, e); return null; } }
@Override public void before(Object target, Object[] args) { if (isDebug) { logger.beforeInterceptor(target, args); } // process(int seqid, TProtocol iprot, TProtocol oprot, I iface) if (args.length != 4) { return; } String methodName = ThriftConstants.UNKNOWN_METHOD_NAME; if (target instanceof ProcessFunction) { ProcessFunction<?, ?> processFunction = (ProcessFunction<?, ?>)target; methodName = processFunction.getMethodName(); } ThriftClientCallContext clientCallContext = new ThriftClientCallContext(methodName); InterceptorScopeInvocation currentTransaction = this.scope.getCurrentInvocation(); currentTransaction.setAttachment(clientCallContext); // Set server marker - server handlers may create a client to call another Thrift server. // When this happens, TProtocol interceptors for clients are triggered since technically they're still within THRIFT_SERVER_SCOPE. // We set the marker inside server's input protocol to safeguard against such cases. Object iprot = args[1]; // With the addition of TProtocolDecorator, iprot may actually be a wrapper around the actual input protocol Object rootInputProtocol = getRootInputProtocol(iprot); if (validateInputProtocol(rootInputProtocol)) { ((ServerMarkerFlagFieldAccessor)rootInputProtocol)._$PINPOINT$_setServerMarkerFlag(true); } }
public Processor(LocatorServiceImpl inst) { super(inst); this.inst = inst; this.fnMap = new HashMap<String, ProcessFunction<LocatorServiceImpl, ?>>( super.getProcessMapView()); }
public Processor(GFXDServiceImpl inst) { super(inst); this.inst = inst; this.fnMap = new HashMap<String, ProcessFunction<GFXDServiceImpl, ?>>( super.getProcessMapView()); }
@SuppressWarnings("rawtypes") public ServiceProcessor(Service service) { super(service, getProcessMap(new HashMap<String, ProcessFunction<Service, ? extends TBase>>())); }
@SuppressWarnings("rawtypes") private static Map<String, ProcessFunction<Service, ? extends TBase>> getProcessMap( Map<String, ProcessFunction<Service, ? extends TBase>> processMap) { processMap.put(FUNCTION_NAME, new GetProcessFunction()); return processMap; }
ThriftFunction(Class<?> serviceType, ProcessFunction<?, ?> func) throws Exception { this(serviceType, func.getMethodName(), func, Type.SYNC, getArgFields(func), getResult(func), getDeclaredExceptions(func)); }
private static TBase<?, ?> getResult(ProcessFunction<?, ?> func) { return getResult0(Type.SYNC, func.getClass(), func.getMethodName()); }
private static TBase<?, ?> getArgs(ProcessFunction<?, ?> func) { return getArgs0(Type.SYNC, func.getClass(), func.getMethodName()); }
private static TFieldIdEnum[] getArgFields(ProcessFunction<?, ?> func) { return getArgFields0(Type.SYNC, func.getClass(), func.getMethodName()); }
private static Class<?>[] getDeclaredExceptions(ProcessFunction<?, ?> func) { return getDeclaredExceptions0(Type.SYNC, func.getClass(), func.getMethodName()); }
public Processor(I iface) { super(iface, getProcessMap(new HashMap<String, org.apache.thrift.ProcessFunction<I, ? extends TBase>>())); }
protected Processor(I iface, Map<String, org.apache.thrift.ProcessFunction<I, ? extends TBase>> processMap) { super(iface, getProcessMap(processMap)); }
private static <I extends Iface> Map<String, ProcessFunction<I, ? extends TBase>> getProcessMap(Map<String, ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) { processMap.put("Log", new Log()); return processMap; }
/** * Returns the {@link ProcessFunction}. * * @throws ClassCastException if this function is asynchronous */ @SuppressWarnings("unchecked") public ProcessFunction<Object, TBase<?, ?>> syncFunc() { return (ProcessFunction<Object, TBase<?, ?>>) func; }