/** * 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.rpc; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.protobuf.Message; import com.sixt.service.framework.ServiceProperties; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Builds RpcClients to interact with remote services. */ public class RpcClientBuilder<RESPONSE extends Message> { private static final Logger logger = LoggerFactory.getLogger(RpcClientBuilder.class); public final static int DEFAULT_RETRIES = 1; public final static int DEFAULT_RESPONSE_TIMEOUT = 1000; private final Injector injector; private String serviceName; private String methodName; private int retries; private int timeout; private Class<RESPONSE> responseClass; @Inject public RpcClientBuilder(Injector injector) { this.injector = injector; initialize(); } void setServiceName(String serviceName) { this.serviceName = serviceName; } void setMethodName(String methodName) { this.methodName = methodName; } /** * Modify retry policy from default */ public RpcClientBuilder<RESPONSE> withRetries(int retries) { this.retries = retries; return this; } /** * Modify timeout policy from default * @param timeout milliseconds */ public RpcClientBuilder<RESPONSE> withTimeout(int timeout) { this.timeout = timeout; return this; } public RpcClient<RESPONSE> build() { if (StringUtils.isBlank(serviceName)) { throw new IllegalStateException("RpcClientBuilder: Service name was not set"); } if (StringUtils.isBlank(methodName)) { throw new IllegalStateException("RpcClientBuilder: Method name was not set"); } LoadBalancerFactory lbFactory = injector.getInstance(LoadBalancerFactory.class); LoadBalancer loadBalancer = lbFactory.getLoadBalancer(serviceName); return new RpcClient<>(loadBalancer, serviceName, methodName, retries, timeout, responseClass); } public void setResponseClass(Class<RESPONSE> responseClass) { this.responseClass = responseClass; } private void initialize() { ServiceProperties properties = injector.getInstance(ServiceProperties.class); retries = parseSetting(properties, "rpcClientRetries", DEFAULT_RETRIES); timeout = parseSetting(properties, "rpcClientTimeout", DEFAULT_RESPONSE_TIMEOUT); } private int parseSetting(ServiceProperties properties, String key, int defaultValue) { String value = properties.getProperty(key); if (StringUtils.isNotBlank(value)) { try { int retval = Integer.parseInt(value); if (retval < 0) { throw new IllegalArgumentException("Invalid " + key + " setting: " + value); } return retval; } catch (Exception ex) { logger.warn("Caught exception", ex); } } return defaultValue; } }