Skip to content

Commit bfae704

Browse files
Deprecate AppCookie (App session) based stickiness type policy for Virtual Router
1 parent 357186d commit bfae704

6 files changed

Lines changed: 61 additions & 32 deletions

File tree

core/src/main/java/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434

3535
import javax.naming.ConfigurationException;
3636

37+
import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
38+
import com.cloud.agent.api.to.LoadBalancerTO;
39+
import com.cloud.network.rules.LbStickinessMethod;
3740
import org.apache.cloudstack.agent.routing.ManageServiceCommand;
3841
import com.cloud.agent.api.routing.UpdateNetworkCommand;
3942
import com.cloud.agent.api.to.IpAddressTO;
@@ -157,6 +160,7 @@ public Answer executeRequest(final NetworkElementCommand cmd) {
157160
return new Answer(cmd);
158161
}
159162

163+
checkAndFailForAppCookieStickinessTypeInLoadBalancerConfigCommand(cmd);
160164
List<ConfigItem> cfg = generateCommandCfg(cmd);
161165
if (cfg == null) {
162166
return Answer.createUnsupportedCommandAnswer(cmd);
@@ -170,7 +174,21 @@ public Answer executeRequest(final NetworkElementCommand cmd) {
170174
if (!aggregated) {
171175
ExecutionResult rc = _vrDeployer.cleanupCommand(cmd);
172176
if (!rc.isSuccess()) {
173-
logger.error("Failed to cleanup VR command due to " + rc.getDetails());
177+
logger.error("Failed to cleanup VR command due to {}", rc.getDetails());
178+
}
179+
}
180+
}
181+
}
182+
183+
private void checkAndFailForAppCookieStickinessTypeInLoadBalancerConfigCommand(NetworkElementCommand cmd) {
184+
if (!(cmd instanceof LoadBalancerConfigCommand)) {
185+
return;
186+
}
187+
LoadBalancerConfigCommand lbConfigCmd = (LoadBalancerConfigCommand) cmd;
188+
for (final LoadBalancerTO lbTO : lbConfigCmd.getLoadBalancers()) {
189+
for (final LoadBalancerTO.StickinessPolicyTO stickinessPolicy : lbTO.getStickinessPolicies()) {
190+
if (stickinessPolicy != null && LbStickinessMethod.StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
191+
throw new IllegalArgumentException("App cookie based stickiness type not supported for Virtual Router, as 'appsession' support is not available from HAProxy 1.6)");
174192
}
175193
}
176194
}
@@ -302,7 +320,7 @@ private ExecutionResult applyConfigToVR(String routerAccessIp, ConfigItem c, Dur
302320
ScriptConfigItem configItem = (ScriptConfigItem)c;
303321
return _vrDeployer.executeInVR(routerAccessIp, configItem.getScript(), configItem.getArgs(), timeout);
304322
}
305-
throw new CloudRuntimeException("Unable to apply unknown configitem of type " + c.getClass().getSimpleName());
323+
throw new CloudRuntimeException("Unable to apply unknown config item of type " + c.getClass().getSimpleName());
306324
}
307325

308326
private Answer applyConfig(NetworkElementCommand cmd, List<ConfigItem> cfg) {
@@ -591,7 +609,7 @@ private List<ConfigItem> generateCommandCfg(NetworkElementCommand cmd) {
591609
* [TODO] Still have to migrate LoadBalancerConfigCommand and BumpUpPriorityCommand
592610
* [FIXME] Have a look at SetSourceNatConfigItem
593611
*/
594-
logger.debug("Transforming " + cmd.getClass().getCanonicalName() + " to ConfigItems");
612+
logger.debug("Transforming {} to ConfigItems", cmd.getClass().getCanonicalName());
595613

596614
final AbstractConfigItemFacade configItemFacade = AbstractConfigItemFacade.getInstance(cmd.getClass());
597615

core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/LoadBalancerConfigItem.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ public class LoadBalancerConfigItem extends AbstractConfigItemFacade {
3838
public List<ConfigItem> generateConfig(final NetworkElementCommand cmd) {
3939
final LoadBalancerConfigCommand command = (LoadBalancerConfigCommand) cmd;
4040

41-
final LoadBalancerConfigurator cfgtr = new HAProxyConfigurator();
42-
final String[] configuration = cfgtr.generateConfiguration(command);
41+
final LoadBalancerConfigurator configurator = new HAProxyConfigurator();
42+
final String[] configuration = configurator.generateConfiguration(command);
4343

4444
String routerIp = command.getNic().getIp();
4545
if (command.getVpcId() == null) {
@@ -49,7 +49,7 @@ public List<ConfigItem> generateConfig(final NetworkElementCommand cmd) {
4949
final String tmpCfgFilePath = "/etc/haproxy/";
5050
final String tmpCfgFileName = "haproxy.cfg.new." + String.valueOf(System.currentTimeMillis());
5151

52-
final String[][] allRules = cfgtr.generateFwRules(command);
52+
final String[][] allRules = configurator.generateFwRules(command);
5353

5454
final String[] addRules = allRules[LoadBalancerConfigurator.ADD];
5555
final String[] removeRules = allRules[LoadBalancerConfigurator.REMOVE];

core/src/main/java/com/cloud/network/HAProxyConfigurator.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,8 @@ private String getLbSubRuleForStickiness(final LoadBalancerTO lbTO) {
399399
sb.append("\t").append("stick-table type ip size ").append(tablesize).append(" expire ").append(expire);
400400
sb.append("\n\t").append("stick on src");
401401
} else if (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
402+
// This is not needed for Virtual Router - 'appsession' is not supported since HAProxy 1.6.
403+
// In case this is used only for Virtual Router, remove it in the later release.
402404
/*
403405
* FORMAT : appsession <cookie> len <length> timeout <holdtime>
404406
* [request-learn] [prefix] [mode

core/src/test/java/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package com.cloud.agent.resource.virtualnetwork;
2121

2222
import static org.junit.Assert.assertEquals;
23+
import static org.junit.Assert.assertFalse;
2324
import static org.junit.Assert.assertTrue;
2425
import static org.junit.Assert.fail;
2526

@@ -31,6 +32,9 @@
3132

3233
import javax.naming.ConfigurationException;
3334

35+
import com.cloud.network.lb.LoadBalancingRule;
36+
import com.cloud.network.rules.LbStickinessMethod;
37+
import com.cloud.utils.Pair;
3438
import org.joda.time.Duration;
3539
import org.junit.Before;
3640
import org.junit.Ignore;
@@ -805,6 +809,36 @@ protected LoadBalancerConfigCommand generateLoadBalancerConfigCommand2() {
805809
return cmd;
806810
}
807811

812+
@Test
813+
public void testLoadBalancerConfigCommandForAppCookie() {
814+
_count = 0;
815+
_file = "";
816+
817+
Answer answer = _resource.executeRequest(generateLoadBalancerConfigCommandWithAppCookie());
818+
assertFalse(answer.getResult());
819+
}
820+
821+
protected LoadBalancerConfigCommand generateLoadBalancerConfigCommandWithAppCookie() {
822+
final List<LoadBalancerTO> lbs = new ArrayList<>();
823+
final List<LbDestination> dests = new ArrayList<>();
824+
dests.add(new LbDestination(80, 8080, "10.1.10.2", false));
825+
dests.add(new LbDestination(80, 8080, "10.1.10.2", true));
826+
final List<LoadBalancingRule.LbStickinessPolicy> stickinessPolicies = new ArrayList<>();
827+
final List<Pair<String, String>> params = new ArrayList<>();
828+
params.add(new Pair<>("cookie", "testcookie"));
829+
params.add(new Pair<>("name", "JSESSIONID"));
830+
stickinessPolicies.add(new LoadBalancingRule.LbStickinessPolicy(LbStickinessMethod.StickinessMethodType.AppCookieBased.getName(), params));
831+
lbs.add(new LoadBalancerTO(UUID.randomUUID().toString(), "64.10.1.10", 80, "tcp", "algo", false, false, false, dests, stickinessPolicies));
832+
final LoadBalancerTO[] arrayLbs = new LoadBalancerTO[lbs.size()];
833+
lbs.toArray(arrayLbs);
834+
final NicTO nic = new NicTO();
835+
nic.setIp("10.1.10.2");
836+
final LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(arrayLbs, "64.10.2.10", "10.1.10.2", "192.168.1.2", nic, Long.valueOf(1), "1000", false);
837+
cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, "10.1.10.2");
838+
cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
839+
return cmd;
840+
}
841+
808842
protected void verifyFile(final LoadBalancerConfigCommand cmd, final String path, final String filename, final String content) {
809843
_count ++;
810844
switch (_count) {

plugins/network-elements/ovs/src/main/java/com/cloud/network/element/OvsElement.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ public static String getHAProxyStickinessCapability() {
333333
"This is App session based sticky method. Define session stickiness on an existing application cookie. " +
334334
"It can be used only for a specific http traffic");
335335
method.addParam("cookie-name", false, "This is the name of the cookie used by the application and which LB will " +
336-
"have to learn for each new session. Default value: Auto geneared based on ip", false);
336+
"have to learn for each new session. Default value: Auto generated based on ip", false);
337337
method.addParam("length", false, "This is the max number of characters that will be memorized and checked in " +
338338
"each cookie value. Default value:52", false);
339339
method.addParam(

server/src/main/java/com/cloud/network/element/VirtualRouterElement.java

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -474,31 +474,6 @@ public static String getHAProxyStickinessCapability() {
474474
+ "For the record, sending 10 domains to MSIE 6 or Firefox 2 works as expected.", false);
475475
methodList.add(method);
476476

477-
method = new LbStickinessMethod(StickinessMethodType.AppCookieBased,
478-
"This is App session based sticky method. Define session stickiness on an existing application cookie. " + "It can be used only for a specific http traffic");
479-
method.addParam("cookie-name", false, "This is the name of the cookie used by the application and which LB will "
480-
+ "have to learn for each new session. Default value: Auto geneared based on ip", false);
481-
method.addParam("length", false, "This is the max number of characters that will be memorized and checked in " + "each cookie value. Default value:52", false);
482-
method.addParam("holdtime", false, "This is the time after which the cookie will be removed from memory if unused. The value should be in "
483-
+ "the format Example : 20s or 30m or 4h or 5d . only seconds(s), minutes(m) hours(h) and days(d) are valid,"
484-
+ " cannot use th combinations like 20h30m. Default value:3h ", false);
485-
method.addParam(
486-
"request-learn",
487-
false,
488-
"If this option is specified, then haproxy will be able to learn the cookie found in the request in case the server does not specify any in response. This is typically what happens with PHPSESSID cookies, or when haproxy's session expires before the application's session and the correct server is selected. It is recommended to specify this option to improve reliability",
489-
true);
490-
method.addParam(
491-
"prefix",
492-
false,
493-
"When this option is specified, haproxy will match on the cookie prefix (or URL parameter prefix). "
494-
+ "The appsession value is the data following this prefix. Example : appsession ASPSESSIONID len 64 timeout 3h prefix This will match the cookie ASPSESSIONIDXXXX=XXXXX, the appsession value will be XXXX=XXXXX.",
495-
true);
496-
method.addParam("mode", false, "This option allows to change the URL parser mode. 2 modes are currently supported : - path-parameters "
497-
+ ": The parser looks for the appsession in the path parameters part (each parameter is separated by a semi-colon), "
498-
+ "which is convenient for JSESSIONID for example.This is the default mode if the option is not set. - query-string :"
499-
+ " In this mode, the parser will look for the appsession in the query string.", false);
500-
methodList.add(method);
501-
502477
method = new LbStickinessMethod(StickinessMethodType.SourceBased, "This is source based Stickiness method, " + "it can be used for any type of protocol.");
503478
method.addParam("tablesize", false, "Size of table to store source ip addresses. example: tablesize=200k or 300m" + " or 400g. Default value:200k", false);
504479
method.addParam("expire", false, "Entry in source ip table will expire after expire duration. units can be s,m,h,d ."

0 commit comments

Comments
 (0)