Java tutorial
/* * Copyright 2013 Netflix, Inc. * * 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.netflix.zuul.dependency.ribbon; import com.netflix.client.ClientException; import com.netflix.client.ClientFactory; import com.netflix.client.config.DefaultClientConfigImpl; import com.netflix.config.*; import com.netflix.zuul.ZuulApplicationInfo; import com.netflix.zuul.constants.ZuulConstants; import org.apache.commons.configuration.AbstractConfiguration; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Handles Eureka VIP names and addresses. * * @author mhawthorne */ public class RibbonConfig { static String APPLICATION_NAME = null; static String APPLICATION_STACK = null; private static Logger LOG = LoggerFactory.getLogger(RibbonConfig.class); private static final DynamicBooleanProperty AUTODETECT_BACKEND_VIPS = DynamicPropertyFactory.getInstance() .getBooleanProperty(ZuulConstants.ZUUL_AUTODETECT_BACKEND_VIPS, true); private static final DynamicStringProperty DEFAULT_CLIENT = DynamicPropertyFactory.getInstance() .getStringProperty(ZuulConstants.ZUUL_NIWS_DEFAULTCLIENT, null); /** * This method attempts to set up the default Ribbon origin VIP from properties and environment. * One method is through autoscale name convention. The Autoscaling group name can be set up as follow : zuul-origin_stack. * Zuul will derive the origin VIP as origin-stack.{zuul.ribbon.vipAddress.template} * <p/> * the client may also be specified by the property ZuulConstants.ZUUL_NIWS_DEFAULTCLIENT * * @throws ClientException */ public static void setupDefaultRibbonConfig() throws ClientException { final DeploymentContext config = ConfigurationManager.getDeploymentContext(); String stack = config.getDeploymentStack(); if (stack != null && stack.contains("_")) { //use stack for client and stack client_stack setAppInfoFromZuulStack(stack); } else { String env = config.getDeploymentEnvironment(); if (stack != null) { setApplicationName(stack); } else { if (DEFAULT_CLIENT.get() == null) throw new RuntimeException( "Can't figure out default origin vips. Set stack as appName_stack of set zuul.niws.defaultClient param"); setApplicationName(DEFAULT_CLIENT.get()); } setApplicationStack(env); } String vip = RibbonConfig.getDefaultVipName(); String vipAddr = RibbonConfig.getDefaultVipAddress(getApplicationStack()); String namespace = DynamicPropertyFactory.getInstance() .getStringProperty(ZuulConstants.ZUUL_RIBBON_NAMESPACE, "ribbon").get(); setIfNotDefined(vip, vipAddr); setIfNotDefined(getApplicationName() + "." + namespace + ".Port", "7001"); setIfNotDefined(getApplicationName() + "." + namespace + ".AppName", getApplicationName()); setIfNotDefined(getApplicationName() + "." + namespace + ".ReadTimeout", "2000"); setIfNotDefined(getApplicationName() + "." + namespace + ".ConnectTimeout", "2000"); setIfNotDefined(getApplicationName() + "." + namespace + ".MaxAutoRetriesNextServer", "1"); setIfNotDefined(getApplicationName() + "." + namespace + ".FollowRedirects", "false"); setIfNotDefined(getApplicationName() + "." + namespace + ".ConnIdleEvictTimeMilliSeconds", "3600000"); setIfNotDefined(getApplicationName() + "." + namespace + ".EnableZoneAffinity", "true"); DefaultClientConfigImpl clientConfig = DefaultClientConfigImpl .getClientConfigWithDefaultValues(getApplicationName(), namespace); ClientFactory.registerClientFromProperties(getApplicationName(), clientConfig); } private static void setIfNotDefined(String key, String value) { final AbstractConfiguration config = ConfigurationManager.getConfigInstance(); if (config.getString(key) == null) { LOG.info("Setting default NIWS Property " + key + "=" + value); config.setProperty(key, value); } } /** * Parses out the the applicationName and application stack from the zuul "stack" element. * when deployed, the applicaiton * * @param stack * @return */ public static boolean setAppInfoFromZuulStack(String stack) { String[] stackSplit = stack.split("_"); if (stackSplit == null || stackSplit.length != 2) return false; setApplicationName(stackSplit[0]); setApplicationStack(stackSplit[1]); return true; } /** * @return the APPLICATION_NAME */ public static String getApplicationName() { return APPLICATION_NAME; } /** * sets the application name of the origin * * @param app_name */ public static void setApplicationName(String app_name) { RibbonConfig.APPLICATION_NAME = app_name; if (ZuulApplicationInfo.applicationName == null) ZuulApplicationInfo.applicationName = app_name; LOG.info("Setting back end VIP application = " + app_name); } /** * returns the application_stack * * @return */ public static String getApplicationStack() { return APPLICATION_STACK; } /** * sets the default origin applcation stack * * @param stack */ public static void setApplicationStack(String stack) { RibbonConfig.APPLICATION_STACK = stack; if (ZuulApplicationInfo.getStack() == null) ZuulApplicationInfo.stack = stack; LOG.info("Setting back end VIP stack = " + stack); } /** * true if the app shoudl autodetect the origin vip * * @return true if the app shoudl autodetect the origin vip */ public static final boolean isAutodetectingBackendVips() { return AUTODETECT_BACKEND_VIPS.get(); } /** * returns the Ribbon property name for the default origin vip * * @return */ public static final String getDefaultVipName() { String client = getApplicationName(); if (client == null) client = DEFAULT_CLIENT.get(); String namespace = DynamicPropertyFactory.getInstance() .getStringProperty(ZuulConstants.ZUUL_RIBBON_NAMESPACE, "ribbon").get(); String vipTemplate = "%s." + namespace + ".DeploymentContextBasedVipAddresses"; return String.format(vipTemplate, client); } /** * builds the default vip address of the origin based on the stack. * You need to configure zuul.ribbon.vipAddress.template . eg zuul.ribbon.vipAddress.template=%s-%s.netflix.net:8888 where %s(1) is client and %s(2) is stack * * @param stack * @return */ public static final String getDefaultVipAddress(String stack) { String client = getApplicationName(); if (client == null) client = DEFAULT_CLIENT.get(); String vipAddressTemplate = DynamicPropertyFactory.getInstance() .getStringProperty(ZuulConstants.ZUUL_RIBBON_VIPADDRESS_TEMPLATE, null).get(); if (vipAddressTemplate == null) throw new RuntimeException( "need to configure zuul.ribbon.vipAddress.template . eg zuul.ribbon.vipAddress.template=%s-%s.netflix.net:8888 where %s(1) is client and %s(2) is stack"); return String.format(vipAddressTemplate, client, stack); } public static final class UnitTest { @Test public void defaultVipAddressForStandardStack() { //todo fix // assertEquals("null-prod.netflix.net:7001", RibbonConfig.getDefaultVipAddress("prod")); } @Test public void defaultVipAddressForLatAmStack() { //todo fix // assertEquals("null-prod.latam.netflix.net:7001", RibbonConfig.getDefaultVipAddress("prod.latam")); } } }