/** * Copyright 2016-2017 Sixt GmbH & Co. Autovermietung KG * Licensed 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 com.sixt.service.framework; import com.google.protobuf.Message; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; public class MethodHandlerDictionary { private static final Logger logger = LoggerFactory.getLogger(MethodHandlerDictionary.class); public static final String GLOBAL = "*"; private Map<String, ServiceMethodHandler<? extends Message, ? extends Message>> methodHandlers; private List<ServiceMethodPreHook<? extends Message>> globalPreHooks; private List<ServiceMethodPostHook<? extends Message>> globalPostHooks; private Map<String, List<ServiceMethodPreHook<? extends Message>>> methodPreHooks; private Map<String, List<ServiceMethodPostHook<? extends Message>>> methodPostHooks; public MethodHandlerDictionary() { this.methodHandlers = new HashMap<>(); this.globalPreHooks = new ArrayList<>(); this.globalPostHooks = new ArrayList<>(); this.methodPreHooks = new HashMap<>(); this.methodPostHooks = new HashMap<>(); } /** * Add a hook to inspect or modify incoming requests. Invoked in the same order as configured at runtime * @param endpoint Use MethodHandlerDictionary.GLOBAL to apply to all handlers, or the RPC method full-name * @param handlerClass ServiceMethodPreHook instance */ public void addPreHook(String endpoint, ServiceMethodPreHook<? extends Message> handlerClass) { if (GLOBAL.equals(endpoint)) { globalPreHooks.add(handlerClass); } else { List<ServiceMethodPreHook<? extends Message>> hooks = methodPreHooks.get(endpoint); if (hooks == null) { hooks = new ArrayList<>(); methodPreHooks.put(endpoint, hooks); } hooks.add(handlerClass); } } /** * Add a hook to inspect or modify outgoing responses. Invoked in the same order as configured at runtime * @param endpoint Use MethodHandlerDictionary.GLOBAL to apply to all handlers, or the RPC method full-name * @param handlerClass ServiceMethodPostHook instance */ public void addPostHook(String endpoint, ServiceMethodPostHook<? extends Message> handlerClass) { if (GLOBAL.equals(endpoint)) { globalPostHooks.add(handlerClass); } else { List<ServiceMethodPostHook<? extends Message>> hooks = methodPostHooks.get(endpoint); if (hooks == null) { hooks = new ArrayList<>(); methodPostHooks.put(endpoint, hooks); } hooks.add(handlerClass); } } public void put(String endpoint, ServiceMethodHandler<? extends Message, ? extends Message> instance) { ServiceMethodHandler existing = methodHandlers.get(endpoint); if (existing != null) { logger.warn("Overwriting ServiceMethodHandler registration for {}", endpoint); } methodHandlers.put(endpoint, instance); } public Map<String, ServiceMethodHandler<? extends Message, ? extends Message>> getMethodHandlers() { return methodHandlers; } public ServiceMethodHandler<? extends Message, ? extends Message> getMethodHandler(String endpoint) { return methodHandlers.get(endpoint); } /** * For backward-compatibility */ @Deprecated public ServiceMethodHandler<? extends Message, ? extends Message> get(String endpoint) { return getMethodHandler(endpoint); } public List<ServiceMethodPreHook<? extends Message>> getPreHooksFor(String methodName) { List<ServiceMethodPreHook<? extends Message>> retval = new ArrayList<>(globalPreHooks); List<ServiceMethodPreHook<? extends Message>> methodHooks = methodPreHooks.get(methodName); if (methodHooks != null) { retval.addAll(methodHooks); } return Collections.unmodifiableList(retval); } public List<ServiceMethodPostHook<? extends Message>> getPostHooksFor(String methodName) { List<ServiceMethodPostHook<? extends Message>> hooks = methodPostHooks.get(methodName); List<ServiceMethodPostHook<? extends Message>> retval = new ArrayList<>(); if (hooks != null) { retval.addAll(hooks); } if (! globalPostHooks.isEmpty()) { retval.addAll(globalPostHooks); } return Collections.unmodifiableList(retval); } public boolean hasMethodHandler(String method) { return methodHandlers.containsKey(method); } }