From 378b8e7d7e7e3493fb2284486c2d2f686fed15ec Mon Sep 17 00:00:00 2001 From: daizhenyu <1449308021@qq.com> Date: Mon, 26 Aug 2024 20:15:39 +0800 Subject: [PATCH] xds framework route and load balance config Signed-off-by: daizhenyu <1449308021@qq.com> --- .../service/xds/XdsLoadBalanceService.java | 43 ++++++ .../core/service/xds/XdsRouteService.java | 45 ++++++ .../core/service/xds/entity/XdsCluster.java | 65 ++++++++ .../xds/entity/XdsClusterLoadAssigment.java | 59 ++++++++ .../service/xds/entity/XdsHeaderMatcher.java | 57 +++++++ .../xds/entity/XdsHttpConnectionManager.java | 35 +++++ .../core/service/xds/entity/XdsLbPolicy.java | 50 +++++++ .../core/service/xds/entity/XdsLocality.java | 96 ++++++++++++ .../service/xds/entity/XdsPathMatcher.java | 58 +++++++ .../core/service/xds/entity/XdsRoute.java | 55 +++++++ .../service/xds/entity/XdsRouteAction.java | 113 ++++++++++++++ .../xds/entity/XdsRouteConfiguration.java | 50 +++++++ .../service/xds/entity/XdsRouteMatch.java | 57 +++++++ .../service/xds/entity/XdsServiceCluster.java | 107 +++++++++++++ .../XdsServiceClusterLoadAssigment.java | 100 +++++++++++++ .../service/xds/entity/XdsVirtualHost.java | 57 +++++++ .../xds/entity/match/ExactMatchStrategy.java | 41 +++++ .../xds/entity/match/MatchStrategy.java | 33 ++++ .../xds/entity/match/PrefixMatchStrategy.java | 41 +++++ .../entity/match/PresentMatchStrategy.java | 30 ++++ .../xds/entity/match/RegexMatchStrategy.java | 45 ++++++ .../xds/entity/match/SuffixMatchStrategy.java | 41 +++++ .../entity/match/UnknownMatchStrategy.java | 30 ++++ .../xds/entity/TestServiceInstance.java | 75 ++++++++++ .../entity/XdsClusterLoadAssigmentTest.java | 47 ++++++ .../service/xds/entity/XdsClusterTest.java | 41 +++++ .../xds/entity/XdsHeaderMatcherTest.java | 65 ++++++++ .../entity/XdsHttpConnectionManagerTest.java | 35 +++++ .../service/xds/entity/XdsLocalityTest.java | 64 ++++++++ .../xds/entity/XdsPathMatcherTest.java | 65 ++++++++ .../XdsServiceClusterLoadAssigmentTest.java | 141 ++++++++++++++++++ .../xds/entity/XdsServiceClusterTest.java | 95 ++++++++++++ .../entity/match/ExactMatchStrategyTest.java | 69 +++++++++ .../entity/match/PrefixMatchStrategyTest.java | 75 ++++++++++ .../match/PresentMatchStrategyTest.java | 48 ++++++ .../entity/match/RegexMatchStrategyTest.java | 65 ++++++++ .../entity/match/SuffixMatchStrategyTest.java | 70 +++++++++ .../match/UnknownMatchStrategyTest.java | 36 +++++ 38 files changed, 2299 insertions(+) create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/XdsLoadBalanceService.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/XdsRouteService.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsCluster.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsClusterLoadAssigment.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsHeaderMatcher.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsHttpConnectionManager.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsLbPolicy.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsLocality.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsPathMatcher.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRoute.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRouteAction.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRouteConfiguration.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRouteMatch.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsServiceCluster.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsServiceClusterLoadAssigment.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsVirtualHost.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/ExactMatchStrategy.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/MatchStrategy.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/PrefixMatchStrategy.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/PresentMatchStrategy.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/RegexMatchStrategy.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/SuffixMatchStrategy.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/UnknownMatchStrategy.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/TestServiceInstance.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsClusterLoadAssigmentTest.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsClusterTest.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsHeaderMatcherTest.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsHttpConnectionManagerTest.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsLocalityTest.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsPathMatcherTest.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsServiceClusterLoadAssigmentTest.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsServiceClusterTest.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/ExactMatchStrategyTest.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/PrefixMatchStrategyTest.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/PresentMatchStrategyTest.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/RegexMatchStrategyTest.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/SuffixMatchStrategyTest.java create mode 100644 sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/UnknownMatchStrategyTest.java diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/XdsLoadBalanceService.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/XdsLoadBalanceService.java new file mode 100644 index 0000000000..a7eb4295be --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/XdsLoadBalanceService.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds; + +import io.sermant.core.service.xds.entity.XdsLbPolicy; + +/** + * xDS load balance service + * + * @author daizhenyu + * @since 2024-07-30 + **/ +public interface XdsLoadBalanceService { + /** + * get lb policy of cluster + * + * @param clusterName cluster name + * @return route rules + */ + XdsLbPolicy getClusterLbPolicy(String clusterName); + + /** + * get lb policy of service (base cluster) + * + * @param serviceName service name + * @return route rules + */ + XdsLbPolicy getServiceLbPolicy(String serviceName); +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/XdsRouteService.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/XdsRouteService.java new file mode 100644 index 0000000000..af4d2c6e96 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/XdsRouteService.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds; + +import io.sermant.core.service.xds.entity.XdsRoute; + +import java.util.List; + +/** + * xDS route service + * + * @author daizhenyu + * @since 2024-07-30 + **/ +public interface XdsRouteService { + /** + * get route rules of service + * + * @param serviceName service name + * @return route rules + */ + List getServiceRoute(String serviceName); + + /** + * get lb policy of cluster + * + * @param clusterName cluster name + * @return route rules + */ + boolean isLocalityRoute(String clusterName); +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsCluster.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsCluster.java new file mode 100644 index 0000000000..53abe91e3e --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsCluster.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +/** + * XdsCluster corresponds to io.envoyproxy.envoy.config.cluster.v3.Cluster + * + * @author daizhenyu + * @since 2024-08-06 + **/ +public class XdsCluster { + private String clusterName; + + private String serviceName; + + private XdsLbPolicy lbPolicy; + + private boolean isLocalityLb; + + public String getClusterName() { + return clusterName; + } + + public void setClusterName(String clusterName) { + this.clusterName = clusterName; + } + + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public XdsLbPolicy getLbPolicy() { + return lbPolicy; + } + + public void setLbPolicy(XdsLbPolicy lbPolicy) { + this.lbPolicy = lbPolicy; + } + + public boolean isLocalityLb() { + return isLocalityLb; + } + + public void setLocalityLb(boolean localityLb) { + isLocalityLb = localityLb; + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsClusterLoadAssigment.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsClusterLoadAssigment.java new file mode 100644 index 0000000000..e4b1450e9c --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsClusterLoadAssigment.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import java.util.Map; +import java.util.Set; + +/** + * XdsClusterLoadAssigment corresponds to io.envoyproxy.envoy.config.endpoint.v3.ClusterLoadAssignment + * + * @author daizhenyu + * @since 2024-08-15 + **/ +public class XdsClusterLoadAssigment { + private String serviceName; + + private String clusterName; + + private Map> localityInstances; + + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public String getClusterName() { + return clusterName; + } + + public void setClusterName(String clusterName) { + this.clusterName = clusterName; + } + + public Map> getLocalityInstances() { + return localityInstances; + } + + public void setLocalityInstances( + Map> localityInstances) { + this.localityInstances = localityInstances; + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsHeaderMatcher.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsHeaderMatcher.java new file mode 100644 index 0000000000..4ab34494be --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsHeaderMatcher.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import io.sermant.core.service.xds.entity.match.MatchStrategy; + +import java.util.Map; + +/** + * xDS HeaderMatcher + * + * @author daizhenyu + * @since 2024-08-15 + **/ +public class XdsHeaderMatcher { + private final String name; + + private final MatchStrategy matchStrategy; + + /** + * parameterized constructor + * + * @param name header name + * @param matchStrategy match strategy + */ + public XdsHeaderMatcher(String name, MatchStrategy matchStrategy) { + this.name = name; + this.matchStrategy = matchStrategy; + } + + /** + * the request header matches the route configuration header or not. + * + * @param headers request headers + * @return isMatch + */ + public boolean isMatch(Map headers) { + if (headers.containsKey(name)) { + return matchStrategy.isMatch(headers.get(name)); + } + return false; + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsHttpConnectionManager.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsHttpConnectionManager.java new file mode 100644 index 0000000000..682c393938 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsHttpConnectionManager.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +/** + * xDS HttpConnectionManager + * + * @author daizhenyu + * @since 2024-08-15 + **/ +public class XdsHttpConnectionManager { + private String routeConfigName; + + public String getRouteConfigName() { + return routeConfigName; + } + + public void setRouteConfigName(String routeConfigName) { + this.routeConfigName = routeConfigName; + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsLbPolicy.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsLbPolicy.java new file mode 100644 index 0000000000..1191eaad2f --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsLbPolicy.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +/** + * xDS LbPolicy + * + * @author daizhenyu + * @since 2024-08-15 + **/ +public enum XdsLbPolicy { + /** + * random + */ + RANDOM, + /** + * round_robin + */ + ROUND_ROBIN, + /** + * least_request + */ + LEAST_REQUEST, + /** + * ring_hash + */ + RING_HASH, + /** + * maglev + */ + MAGLEV, + /** + * unrecognized + */ + UNRECOGNIZED; +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsLocality.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsLocality.java new file mode 100644 index 0000000000..52cb856def --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsLocality.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import java.util.Objects; + +/** + * xDS Locality + * + * @author daizhenyu + * @since 2024-08-15 + **/ +public class XdsLocality { + private String region; + + private String zone; + + private String subZone; + + private int loadBalanceWeight; + + private int localityPriority; + + public String getRegion() { + return region; + } + + public void setRegion(String region) { + this.region = region; + } + + public String getZone() { + return zone; + } + + public void setZone(String zone) { + this.zone = zone; + } + + public String getSubZone() { + return subZone; + } + + public void setSubZone(String subZone) { + this.subZone = subZone; + } + + public int getLoadBalanceWeight() { + return loadBalanceWeight; + } + + public void setLoadBalanceWeight(int loadBalanceWeight) { + this.loadBalanceWeight = loadBalanceWeight; + } + + public int getLocalityPriority() { + return localityPriority; + } + + public void setLocalityPriority(int localityPriority) { + this.localityPriority = localityPriority; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + XdsLocality locality = (XdsLocality) obj; + return Objects.equals(region, locality.region) + && Objects.equals(zone, locality.zone) + && Objects.equals(subZone, locality.subZone); + } + + @Override + public int hashCode() { + return Objects.hash(region, zone, subZone); + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsPathMatcher.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsPathMatcher.java new file mode 100644 index 0000000000..32cae4461e --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsPathMatcher.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import io.sermant.core.service.xds.entity.match.MatchStrategy; + +import java.util.Locale; + +/** + * XdsPathMatcher + * + * @author daizhenyu + * @since 2024-08-06 + **/ +public class XdsPathMatcher { + private final MatchStrategy matchStrategy; + + private final boolean caseSensitive; + + /** + * parameterized constructor + * + * @param matchStrategy match strategy + * @param caseSensitive case sensitive + */ + public XdsPathMatcher(MatchStrategy matchStrategy, boolean caseSensitive) { + this.matchStrategy = matchStrategy; + this.caseSensitive = caseSensitive; + } + + /** + * the request path matches the route configuration path or not. + * + * @param path request path + * @return isMatch + */ + public boolean isMatch(String path) { + return path != null && matchStrategy.isMatch(caseSensitive ? path : path.toLowerCase(Locale.ROOT)); + } + + public boolean isCaseSensitive() { + return caseSensitive; + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRoute.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRoute.java new file mode 100644 index 0000000000..41ca560a02 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRoute.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +/** + * route + * + * @author daizhenyu + * @since 2024-08-05 + **/ +public class XdsRoute { + private String name; + + private XdsRouteMatch routeMatch; + + private XdsRouteAction routeAction; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public XdsRouteMatch getRouteMatch() { + return routeMatch; + } + + public void setRouteMatch(XdsRouteMatch routeMatch) { + this.routeMatch = routeMatch; + } + + public XdsRouteAction getRouteAction() { + return routeAction; + } + + public void setRouteAction(XdsRouteAction routeAction) { + this.routeAction = routeAction; + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRouteAction.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRouteAction.java new file mode 100644 index 0000000000..eb44873448 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRouteAction.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import java.util.List; + +/** + * xDS RouteAction + * + * @author daizhenyu + * @since 2024-08-05 + **/ +public class XdsRouteAction { + private String cluster; + + private boolean isWeighted = false; + + private XdsWeightedClusters weightedClusters; + + public String getCluster() { + return cluster; + } + + public void setCluster(String cluster) { + this.cluster = cluster; + } + + public boolean isWeighted() { + return isWeighted; + } + + public void setWeighted(boolean weighted) { + isWeighted = weighted; + } + + public XdsWeightedClusters getWeightedClusters() { + return weightedClusters; + } + + public void setWeightedClusters(XdsWeightedClusters weightedClusters) { + this.weightedClusters = weightedClusters; + } + + /** + * xDS WeightedClusters + * + * @author daizhenyu + * @since 2024-08-05 + **/ + public static class XdsWeightedClusters { + private List clusters; + + private int totalWeight; + + public List getClusters() { + return clusters; + } + + public void setClusters(List clusters) { + this.clusters = clusters; + } + + public int getTotalWeight() { + return totalWeight; + } + + public void setTotalWeight(int totalWeight) { + this.totalWeight = totalWeight; + } + } + + /** + * xDS ClusterWeight + * + * @author daizhenyu + * @since 2024-08-05 + **/ + public static class XdsClusterWeight { + private String clusterName; + + private int weight; + + public String getClusterName() { + return clusterName; + } + + public void setClusterName(String clusterName) { + this.clusterName = clusterName; + } + + public int getWeight() { + return weight; + } + + public void setWeight(int weight) { + this.weight = weight; + } + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRouteConfiguration.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRouteConfiguration.java new file mode 100644 index 0000000000..2c33cb5ff4 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRouteConfiguration.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import java.util.Map; + +/** + * xDS RouteConfiguration + * + * @author daizhenyu + * @since 2024-08-05 + **/ +public class XdsRouteConfiguration { + private String routeConfigName; + + /** + * key:service name value:virtual host + */ + private Map virtualHosts; + + public String getRouteConfigName() { + return routeConfigName; + } + + public void setRouteConfigName(String routeConfigName) { + this.routeConfigName = routeConfigName; + } + + public Map getVirtualHosts() { + return virtualHosts; + } + + public void setVirtualHosts(Map virtualHosts) { + this.virtualHosts = virtualHosts; + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRouteMatch.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRouteMatch.java new file mode 100644 index 0000000000..dd35b8a996 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsRouteMatch.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import java.util.List; + +/** + * XdsRouteMatch + * + * @author daizhenyu + * @since 2024-08-05 + **/ +public class XdsRouteMatch { + private XdsPathMatcher pathMatcher; + + private List headerMatchers; + + private boolean caseSensitive; + + public void setPathMatcher(XdsPathMatcher pathMatcher) { + this.pathMatcher = pathMatcher; + } + + public void setHeaderMatchers(List headerMatchers) { + this.headerMatchers = headerMatchers; + } + + public XdsPathMatcher getPathMatcher() { + return pathMatcher; + } + + public List getHeaderMatchers() { + return headerMatchers; + } + + public boolean isCaseSensitive() { + return caseSensitive; + } + + public void setCaseSensitive(boolean caseSensitive) { + this.caseSensitive = caseSensitive; + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsServiceCluster.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsServiceCluster.java new file mode 100644 index 0000000000..d072fb99d5 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsServiceCluster.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +/** + * XdsServiceCluster contains all XdsCluster data of service + * + * @author daizhenyu + * @since 2024-08-15 + **/ +public class XdsServiceCluster { + /** + * key:cluster name value:XdsCluster + */ + private Map clusters; + + private String baseClusterName; + + public String getBaseClusterName() { + return baseClusterName; + } + + public void setBaseClusterName(String baseClusterName) { + this.baseClusterName = baseClusterName; + } + + public void setClusters(Map clusters) { + this.clusters = clusters; + } + + /** + * get service all cluster resource + * + * @return clusters + */ + public Set getClusterResources() { + if (clusters == null) { + return Collections.EMPTY_SET; + } + return clusters.keySet(); + } + + /** + * is cluster locality lb + * + * @param clusterName cluster name + * @return boolean + */ + public boolean isClusterLocalityLb(String clusterName) { + if (clusters == null) { + return false; + } + XdsCluster xdsCluster = clusters.get(clusterName); + return xdsCluster != null && xdsCluster.isLocalityLb(); + } + + /** + * get cluster lb policy + * + * @param clusterName cluster name + * @return XdsLbPolicy + */ + public XdsLbPolicy getLbPolicyOfCluster(String clusterName) { + if (clusters == null) { + return XdsLbPolicy.UNRECOGNIZED; + } + XdsCluster xdsCluster = clusters.get(clusterName); + if (xdsCluster == null) { + return XdsLbPolicy.UNRECOGNIZED; + } + return xdsCluster.getLbPolicy(); + } + + /** + * get service(base cluster) lb policy + * + * @return XdsLbPolicy + */ + public XdsLbPolicy getBaseLbPolicyOfService() { + if (clusters == null) { + return XdsLbPolicy.UNRECOGNIZED; + } + XdsCluster xdsCluster = clusters.get(baseClusterName); + if (xdsCluster == null) { + return XdsLbPolicy.UNRECOGNIZED; + } + return xdsCluster.getLbPolicy(); + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsServiceClusterLoadAssigment.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsServiceClusterLoadAssigment.java new file mode 100644 index 0000000000..87ffb96983 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsServiceClusterLoadAssigment.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * XdsServiceClusterLoadAssigment contains all XdsClusterLoadAssigment data of service + * + * @author daizhenyu + * @since 2024-08-15 + **/ +public class XdsServiceClusterLoadAssigment { + /** + * key:cluster name value:XdsClusterLoadAssigment + */ + private Map clusterLoadAssigments; + + private String baseClusterName; + + public Map getClusterLoadAssigments() { + return clusterLoadAssigments; + } + + public void setClusterLoadAssigments(Map clusterLoadAssigments) { + this.clusterLoadAssigments = clusterLoadAssigments; + } + + public String getBaseClusterName() { + return baseClusterName; + } + + public void setBaseClusterName(String baseClusterName) { + this.baseClusterName = baseClusterName; + } + + /** + * get all service instance + * + * @return service instances + */ + public Set getServiceInstance() { + return getClusterServiceInstance(baseClusterName); + } + + /** + * get service instance of service cluster + * + * @param clusterName cluster name + * @return service instances + */ + public Set getServiceInstance(String clusterName) { + return getClusterServiceInstance(clusterName); + } + + /** + * get XdsClusterLoadAssigment + * + * @param clusterName cluster name + * @return XdsClusterLoadAssigment + */ + public XdsClusterLoadAssigment getXdsClusterLoadAssigment(String clusterName) { + return clusterLoadAssigments.get(clusterName); + } + + private Set getClusterServiceInstance(String clusterName) { + if (clusterLoadAssigments == null) { + return Collections.EMPTY_SET; + } + XdsClusterLoadAssigment xdsClusterLoadAssigment = clusterLoadAssigments.get(clusterName); + if (xdsClusterLoadAssigment == null) { + return Collections.EMPTY_SET; + } + Map> localityInstances = xdsClusterLoadAssigment.getLocalityInstances(); + if (localityInstances == null) { + return Collections.EMPTY_SET; + } + return localityInstances.entrySet() + .stream() + .flatMap(entry -> entry.getValue().stream()) + .collect(Collectors.toSet()); + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsVirtualHost.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsVirtualHost.java new file mode 100644 index 0000000000..f9a426e86e --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/XdsVirtualHost.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import java.util.List; + +/** + * xDS VirtualHost + * + * @author daizhenyu + * @since 2024-08-05 + **/ +public class XdsVirtualHost { + private String name; + + private List domains; + + private List routes; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getDomains() { + return domains; + } + + public void setDomains(List domains) { + this.domains = domains; + } + + public List getRoutes() { + return routes; + } + + public void setRoutes(List routes) { + this.routes = routes; + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/ExactMatchStrategy.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/ExactMatchStrategy.java new file mode 100644 index 0000000000..779510d63b --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/ExactMatchStrategy.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity.match; + +/** + * ExactMatchStrategy + * + * @author daizhenyu + * @since 2024-08-15 + **/ +public class ExactMatchStrategy implements MatchStrategy { + private final String exactValue; + + /** + * parameterized constructor + * + * @param exactValue exact value + */ + public ExactMatchStrategy(String exactValue) { + this.exactValue = exactValue == null ? "" : exactValue; + } + + @Override + public boolean isMatch(String requestValue) { + return exactValue.equals(requestValue); + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/MatchStrategy.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/MatchStrategy.java new file mode 100644 index 0000000000..93ed7e58e6 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/MatchStrategy.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity.match; + +/** + * MatchStrategy + * + * @author daizhenyu + * @since 2024-08-15 + **/ +public interface MatchStrategy { + /** + * is request header value matched with configured header value + * + * @param requestValue request header value + * @return isMatch + */ + boolean isMatch(String requestValue); +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/PrefixMatchStrategy.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/PrefixMatchStrategy.java new file mode 100644 index 0000000000..3c0c275ee7 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/PrefixMatchStrategy.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity.match; + +/** + * PrefixMatchStrategy + * + * @author daizhenyu + * @since 2024-08-15 + **/ +public class PrefixMatchStrategy implements MatchStrategy { + private final String prefix; + + /** + * parameterized constructor + * + * @param prefix prefix + */ + public PrefixMatchStrategy(String prefix) { + this.prefix = prefix == null ? "" : prefix; + } + + @Override + public boolean isMatch(String requestValue) { + return requestValue != null && requestValue.startsWith(prefix); + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/PresentMatchStrategy.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/PresentMatchStrategy.java new file mode 100644 index 0000000000..a4de182d01 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/PresentMatchStrategy.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity.match; + +/** + * Match ignore values + * + * @author daizhenyu + * @since 2024-08-15 + **/ +public class PresentMatchStrategy implements MatchStrategy { + @Override + public boolean isMatch(String requestValue) { + return true; + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/RegexMatchStrategy.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/RegexMatchStrategy.java new file mode 100644 index 0000000000..6c8893ef7f --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/RegexMatchStrategy.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity.match; + +import io.sermant.core.utils.StringUtils; + +import java.util.regex.Pattern; + +/** + * RegexMatchStrategy + * + * @author daizhenyu + * @since 2024-08-15 + **/ +public class RegexMatchStrategy implements MatchStrategy { + private final Pattern regex; + + /** + * parameterized constructor + * + * @param regex regex + */ + public RegexMatchStrategy(String regex) { + this.regex = StringUtils.isEmpty(regex) ? Pattern.compile(".*") : Pattern.compile(regex); + } + + @Override + public boolean isMatch(String requestValue) { + return requestValue != null && regex.matcher(requestValue).matches(); + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/SuffixMatchStrategy.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/SuffixMatchStrategy.java new file mode 100644 index 0000000000..d4af637d30 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/SuffixMatchStrategy.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity.match; + +/** + * SuffixMatchStrategy + * + * @author daizhenyu + * @since 2024-08-15 + **/ +public class SuffixMatchStrategy implements MatchStrategy { + private final String suffix; + + /** + * parameterized constructor + * + * @param suffix suffix + */ + public SuffixMatchStrategy(String suffix) { + this.suffix = suffix == null ? "" : suffix; + } + + @Override + public boolean isMatch(String requestValue) { + return requestValue != null && requestValue.endsWith(suffix); + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/UnknownMatchStrategy.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/UnknownMatchStrategy.java new file mode 100644 index 0000000000..0c7cffdf68 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/io/sermant/core/service/xds/entity/match/UnknownMatchStrategy.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity.match; + +/** + * unknown MatchStrategy + * + * @author daizhenyu + * @since 2024-08-20 + **/ +public class UnknownMatchStrategy implements MatchStrategy { + @Override + public boolean isMatch(String requestValue) { + return false; + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/TestServiceInstance.java b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/TestServiceInstance.java new file mode 100644 index 0000000000..942aeedd17 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/TestServiceInstance.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import java.util.Map; + +/** + * TestServiceInstance + * + * @author daizhenyu + * @since 2024-08-24 + **/ +public class TestServiceInstance implements ServiceInstance{ + public TestServiceInstance() { + + } + public TestServiceInstance(String cluster, String service, String host, int port) { + this.cluster = cluster; + this.service = service; + this.host = host; + this.port = port; + } + + private String cluster; + + private String service; + + private String host; + + private int port; + + @Override + public String getClusterName() { + return cluster; + } + + @Override + public String getServiceName() { + return service; + } + + @Override + public String getHost() { + return host; + } + + @Override + public int getPort() { + return port; + } + + @Override + public Map getMetaData() { + return null; + } + + @Override + public boolean isHealthy() { + return false; + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsClusterLoadAssigmentTest.java b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsClusterLoadAssigmentTest.java new file mode 100644 index 0000000000..980a39c05f --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsClusterLoadAssigmentTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * @author daizhenyu + * @since 2024-08-24 + **/ +public class XdsClusterLoadAssigmentTest { + @Test + public void testXdsClusterInstance() { + XdsLocality locality = new XdsLocality(); + Set instances = new HashSet<>(); + instances.add(new TestServiceInstance()); + Map> localityInstances = new HashMap<>(); + localityInstances.put(locality, instances); + XdsClusterLoadAssigment clusterInstance = new XdsClusterLoadAssigment(); + clusterInstance.setClusterName("outbound|8080||serviceA.default.svc.cluster.local"); + clusterInstance.setServiceName("serviceA"); + clusterInstance.setLocalityInstances(localityInstances); + Assert.assertEquals("serviceA", clusterInstance.getServiceName()); + Assert.assertEquals("outbound|8080||serviceA.default.svc.cluster.local", clusterInstance.getClusterName()); + Assert.assertEquals(localityInstances, clusterInstance.getLocalityInstances()); + } +} \ No newline at end of file diff --git a/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsClusterTest.java b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsClusterTest.java new file mode 100644 index 0000000000..d05576a5c4 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsClusterTest.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import org.junit.Assert; +import org.junit.Test; + +/** + * XdsClusterTest + * + * @author daizhenyu + * @since 2024-08-24 + **/ +public class XdsClusterTest { + @Test + public void testXdsCluster() { + XdsCluster cluster = new XdsCluster(); + cluster.setClusterName("outbound|8080||serviceA.default.svc.cluster.local"); + cluster.setLbPolicy(XdsLbPolicy.RANDOM); + cluster.setLocalityLb(true); + cluster.setServiceName("serviceA"); + Assert.assertTrue(cluster.isLocalityLb()); + Assert.assertEquals("outbound|8080||serviceA.default.svc.cluster.local", cluster.getClusterName()); + Assert.assertEquals("serviceA", cluster.getServiceName()); + Assert.assertEquals(XdsLbPolicy.RANDOM, cluster.getLbPolicy()); + } +} \ No newline at end of file diff --git a/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsHeaderMatcherTest.java b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsHeaderMatcherTest.java new file mode 100644 index 0000000000..498ae8bf8f --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsHeaderMatcherTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import io.sermant.core.service.xds.entity.match.ExactMatchStrategy; +import io.sermant.core.service.xds.entity.match.MatchStrategy; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author daizhenyu + * @since 2024-08-24 + **/ +public class XdsHeaderMatcherTest { + private MatchStrategy matchStrategy; + + private XdsHeaderMatcher matcher; + + private Map headers; + + @Test + public void testIsMatchWithMatchingHeader() { + matchStrategy = new ExactMatchStrategy("test"); + matcher = new XdsHeaderMatcher("testHeader", matchStrategy); + headers = new HashMap<>(); + headers.put("testHeader", "test"); + Assert.assertTrue(matcher.isMatch(headers)); + } + + @Test + public void testIsMatchWithNonMatchingHeader() { + matchStrategy = new ExactMatchStrategy("test"); + matcher = new XdsHeaderMatcher("testHeader", matchStrategy); + headers = new HashMap<>(); + headers.put("testHeader", "noMatchTest"); + Assert.assertFalse(matcher.isMatch(headers)); + } + + @Test + public void testIsMatchWithMissingHeader() { + matchStrategy = new ExactMatchStrategy("test"); + matcher = new XdsHeaderMatcher("testHeader", matchStrategy); + headers = new HashMap<>(); + headers.put("otherHeader", "noMatchTest"); + Assert.assertFalse(matcher.isMatch(headers)); + } +} \ No newline at end of file diff --git a/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsHttpConnectionManagerTest.java b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsHttpConnectionManagerTest.java new file mode 100644 index 0000000000..dcda11a0c6 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsHttpConnectionManagerTest.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import org.junit.Assert; +import org.junit.Test; + +/** + * XdsHttpConnectionManagerTest + * + * @author daizhenyu + * @since 2024-08-24 + **/ +public class XdsHttpConnectionManagerTest { + @Test + public void testXdsHttpConnectionManager() { + XdsHttpConnectionManager manager = new XdsHttpConnectionManager(); + manager.setRouteConfigName("test"); + Assert.assertEquals("test", manager.getRouteConfigName()); + } +} \ No newline at end of file diff --git a/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsLocalityTest.java b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsLocalityTest.java new file mode 100644 index 0000000000..25488383e9 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsLocalityTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import org.junit.Assert; +import org.junit.Test; + +/** + * XdsLocalityTest + * + * @author daizhenyu + * @since 2024-08-24 + **/ +public class XdsLocalityTest { + @Test + public void testXdsLocality() { + XdsLocality locality = new XdsLocality(); + locality.setRegion("region"); + locality.setZone("zone"); + locality.setSubZone("subzone"); + locality.setLocalityPriority(5); + locality.setLoadBalanceWeight(5); + Assert.assertEquals("region", locality.getRegion()); + Assert.assertEquals("zone", locality.getZone()); + Assert.assertEquals("subzone", locality.getSubZone()); + Assert.assertEquals(5, locality.getLocalityPriority()); + Assert.assertEquals(5, locality.getLoadBalanceWeight()); + } + + @Test + public void testEquals() { + XdsLocality comparedXdsLocality = new XdsLocality(); + comparedXdsLocality.setRegion("region"); + comparedXdsLocality.setZone("zone"); + comparedXdsLocality.setSubZone("subzone"); + + // equals with null + Assert.assertFalse(comparedXdsLocality.equals(null)); + + // equal with zone is null + XdsLocality xdsLocality = new XdsLocality(); + xdsLocality.setRegion("region"); + xdsLocality.setSubZone("subzone"); + Assert.assertFalse(comparedXdsLocality.equals(xdsLocality)); + + // equal with same locality + xdsLocality.setZone("zone"); + Assert.assertTrue(comparedXdsLocality.equals(xdsLocality)); + } +} \ No newline at end of file diff --git a/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsPathMatcherTest.java b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsPathMatcherTest.java new file mode 100644 index 0000000000..695912ed4e --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsPathMatcherTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import io.sermant.core.service.xds.entity.match.ExactMatchStrategy; +import io.sermant.core.service.xds.entity.match.MatchStrategy; + +import org.junit.Assert; +import org.junit.Test; + +/** + * XdsPathMatcherTest + * + * @author daizhenyu + * @since 2024-08-24 + **/ +public class XdsPathMatcherTest { + @Test + public void testIsMatchCaseSensitiveMatching() { + MatchStrategy matchStrategy = new ExactMatchStrategy("/test/path"); + XdsPathMatcher matcher = new XdsPathMatcher(matchStrategy, true); + Assert.assertTrue(matcher.isCaseSensitive()); + Assert.assertTrue(matcher.isMatch("/test/path")); + Assert.assertFalse(matcher.isMatch("/TEST/PATH")); + } + + @Test + public void testIsMatchCaseInsensitiveMatching() { + MatchStrategy matchStrategy = new ExactMatchStrategy("/test/path"); + XdsPathMatcher matcher = new XdsPathMatcher(matchStrategy, false); + Assert.assertFalse(matcher.isCaseSensitive()); + Assert.assertTrue(matcher.isMatch("/test/path")); + Assert.assertTrue(matcher.isMatch("/TEST/PATH")); + } + + @Test + public void testIsMatchWithNullPath() { + MatchStrategy matchStrategy = new ExactMatchStrategy("/test/path"); + XdsPathMatcher matcher = new XdsPathMatcher(matchStrategy, true); + Assert.assertFalse(matcher.isMatch(null)); + } + + @Test + public void testIsMatchWithEmptyPath() { + MatchStrategy matchStrategy = new ExactMatchStrategy(""); + XdsPathMatcher matcher = new XdsPathMatcher(matchStrategy, true); + + Assert.assertTrue(matcher.isMatch("")); + Assert.assertFalse(matcher.isMatch("/nonempty/path")); + } +} \ No newline at end of file diff --git a/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsServiceClusterLoadAssigmentTest.java b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsServiceClusterLoadAssigmentTest.java new file mode 100644 index 0000000000..d0089d03fd --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsServiceClusterLoadAssigmentTest.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * XdsServiceClusterInstanceTest + * + * @author daizhenyu + * @since 2024-08-24 + **/ +public class XdsServiceClusterLoadAssigmentTest { + private static XdsServiceClusterLoadAssigment serviceClusterInstance; + + private static XdsClusterLoadAssigment clusterInstance1; + + private static XdsClusterLoadAssigment clusterInstance2; + + private static ServiceInstance serviceInstance1; + + private static ServiceInstance serviceInstance2; + + private static ServiceInstance serviceInstance3; + + private static Map clusterInstances; + + @BeforeClass + public static void setUp() { + serviceClusterInstance = new XdsServiceClusterLoadAssigment(); + + serviceInstance1 = new TestServiceInstance("outbound|8080||serviceA.default.svc.cluster.local", "serviceA", + "localhost", 8080); + serviceInstance2 = new TestServiceInstance("outbound|8080||serviceA.default.svc.cluster.local", "serviceA", + "localhost", 9090); + serviceInstance3 = new TestServiceInstance("outbound|8080|subset1|serviceA.default.svc.cluster.local", + "serviceA", + "localhost", 7070); + + clusterInstance1 = new XdsClusterLoadAssigment(); + clusterInstance2 = new XdsClusterLoadAssigment(); + + Map> localityInstances1 = new HashMap<>(); + XdsLocality locality1 = new XdsLocality(); + locality1.setRegion("region1"); + locality1.setZone("zone1"); + locality1.setSubZone("subZone1"); + localityInstances1.put(locality1, new HashSet<>(Arrays.asList(serviceInstance1, serviceInstance2))); + + Map> localityInstances2 = new HashMap<>(); + XdsLocality locality2 = new XdsLocality(); + locality2.setRegion("region2"); + locality2.setZone("zone2"); + locality2.setSubZone("subZone2"); + localityInstances2.put(locality2, new HashSet<>(Collections.singletonList(serviceInstance3))); + + clusterInstance1.setLocalityInstances(localityInstances1); + clusterInstance2.setLocalityInstances(localityInstances2); + + Map clusterInstances = new HashMap<>(); + clusterInstances.put("outbound|8080||serviceA.default.svc.cluster.local", clusterInstance1); + clusterInstances.put("outbound|8080|subset1|serviceA.default.svc.cluster.local", clusterInstance2); + + serviceClusterInstance.setClusterLoadAssigments(clusterInstances); + serviceClusterInstance.setBaseClusterName("outbound|8080||serviceA.default.svc.cluster.local"); + } + + @Test + public void testGetClusterInstances() { + Map clusterInstances = serviceClusterInstance.getClusterLoadAssigments(); + Assert.assertNotNull(clusterInstances); + Assert.assertEquals(2, clusterInstances.size()); + Assert.assertTrue(clusterInstances.containsKey("outbound|8080||serviceA.default.svc.cluster.local")); + Assert.assertTrue(clusterInstances.containsKey("outbound|8080|subset1|serviceA.default.svc.cluster.local")); + } + + @Test + public void testGetBaseClusterName() { + Assert.assertEquals("outbound|8080||serviceA.default.svc.cluster.local", + serviceClusterInstance.getBaseClusterName()); + } + + @Test + public void testGetServiceInstance() { + Set serviceInstances = serviceClusterInstance.getServiceInstance(); + Assert.assertNotNull(serviceInstances); + Assert.assertEquals(2, serviceInstances.size()); + Assert.assertTrue(serviceInstances.contains(serviceInstance1)); + Assert.assertTrue(serviceInstances.contains(serviceInstance2)); + } + + @Test + public void testGetServiceInstanceWithClusterName() { + Set serviceInstances = serviceClusterInstance + .getServiceInstance("outbound|8080|subset1|serviceA.default.svc.cluster.local"); + Assert.assertNotNull(serviceInstances); + Assert.assertEquals(1, serviceInstances.size()); + Assert.assertTrue(serviceInstances.contains(serviceInstance3)); + } + + @Test + public void testGetServiceInstanceWithNonExistentCluster() { + Set serviceInstances = serviceClusterInstance.getServiceInstance("nonexistentCluster"); + Assert.assertNotNull(serviceInstances); + Assert.assertTrue(serviceInstances.isEmpty()); + } + + @Test + public void testGetXdsClusterInstance() { + XdsClusterLoadAssigment clusterInstance = serviceClusterInstance + .getXdsClusterLoadAssigment("outbound|8080||serviceA.default.svc.cluster.local"); + Assert.assertNotNull(clusterInstance); + Assert.assertEquals(clusterInstance1, clusterInstance); + + XdsClusterLoadAssigment nonExistentInstance = serviceClusterInstance.getXdsClusterLoadAssigment("nonexistentCluster"); + Assert.assertNull(nonExistentInstance); + } +} \ No newline at end of file diff --git a/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsServiceClusterTest.java b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsServiceClusterTest.java new file mode 100644 index 0000000000..b80f68a3f7 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/XdsServiceClusterTest.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * @author daizhenyu + * @since 2024-08-24 + **/ +public class XdsServiceClusterTest { + private XdsServiceCluster serviceCluster; + private XdsCluster xdsCluster1; + private XdsCluster xdsCluster2; + + @Before + public void setUp() { + serviceCluster = new XdsServiceCluster(); + + xdsCluster1 = new XdsCluster(); + xdsCluster1.setClusterName("outbound|8080||serviceA.default.svc.cluster.local"); + xdsCluster1.setLocalityLb(true); + xdsCluster1.setLbPolicy(XdsLbPolicy.ROUND_ROBIN); + + xdsCluster2 = new XdsCluster(); + xdsCluster2.setLocalityLb(false); + xdsCluster2.setLbPolicy(XdsLbPolicy.LEAST_REQUEST); + xdsCluster1.setClusterName("outbound|8080|subset1|serviceA.default.svc.cluster.local"); + + Map clusters = new HashMap<>(); + clusters.put("outbound|8080||serviceA.default.svc.cluster.local", xdsCluster1); + clusters.put("outbound|8080|subset1|serviceA.default.svc.cluster.local", xdsCluster2); + + serviceCluster.setClusters(clusters); + serviceCluster.setBaseClusterName("outbound|8080||serviceA.default.svc.cluster.local"); + } + + @Test + public void testGetBaseClusterName() { + Assert.assertEquals("outbound|8080||serviceA.default.svc.cluster.local", serviceCluster.getBaseClusterName()); + } + + @Test + public void testGetClusterResources() { + Set clusterResources = serviceCluster.getClusterResources(); + Assert.assertNotNull(clusterResources); + Assert.assertEquals(2, clusterResources.size()); + Assert.assertTrue(clusterResources.contains("outbound|8080||serviceA.default.svc.cluster.local")); + Assert.assertTrue(clusterResources.contains("outbound|8080|subset1|serviceA.default.svc.cluster.local")); + + // cluster is null + serviceCluster.setClusters(null); + clusterResources = serviceCluster.getClusterResources(); + Assert.assertNotNull(clusterResources); + Assert.assertTrue(clusterResources.isEmpty()); + } + + @Test + public void testIsClusterLocalityLb() { + Assert.assertTrue(serviceCluster.isClusterLocalityLb("outbound|8080||serviceA.default.svc.cluster.local")); + Assert.assertFalse(serviceCluster.isClusterLocalityLb("outbound|8080|subset1|serviceA.default.svc.cluster.local")); + } + + @Test + public void testGetPolicyOfCluster() { + Assert.assertEquals(XdsLbPolicy.ROUND_ROBIN, serviceCluster.getLbPolicyOfCluster("outbound|8080||serviceA.default.svc.cluster.local")); + Assert.assertEquals(XdsLbPolicy.LEAST_REQUEST, serviceCluster.getLbPolicyOfCluster("outbound|8080|subset1|serviceA.default.svc.cluster.local")); + Assert.assertEquals(XdsLbPolicy.UNRECOGNIZED, serviceCluster.getLbPolicyOfCluster("nonexistentCluster")); + } + + @Test + public void testGetBaseLbPolicyOfService() { + Assert.assertEquals(XdsLbPolicy.ROUND_ROBIN, serviceCluster.getBaseLbPolicyOfService()); + } +} \ No newline at end of file diff --git a/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/ExactMatchStrategyTest.java b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/ExactMatchStrategyTest.java new file mode 100644 index 0000000000..8bdf138d78 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/ExactMatchStrategyTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity.match; + +import org.junit.Assert; +import org.junit.Test; + +/** + * ExactMatchStrategyTest + * + * @author daizhenyu + * @since 2024-08-24 + **/ +public class ExactMatchStrategyTest { + private ExactMatchStrategy strategy; + + @Test + public void testConstructorWithNonNullValue() { + String expectedValue = "test"; + strategy = new ExactMatchStrategy(expectedValue); + Assert.assertEquals(expectedValue, strategy.isMatch("test") ? "test" : ""); + } + + @Test + public void testConstructorWithNullValue() { + strategy = new ExactMatchStrategy(null); + Assert.assertFalse(strategy.isMatch("test")); + Assert.assertTrue(strategy.isMatch("")); + } + + @Test + public void testIsMatchWithMatchingValue() { + strategy = new ExactMatchStrategy("exact"); + Assert.assertTrue(strategy.isMatch("exact")); + } + + @Test + public void testIsMatchWithNonMatchingValue() { + strategy = new ExactMatchStrategy("exact"); + Assert.assertFalse(strategy.isMatch("notExact")); + } + + @Test + public void testIsMatchWithEmptyValue() { + strategy = new ExactMatchStrategy(""); + Assert.assertTrue(strategy.isMatch("")); + } + + @Test + public void testIsMatchWithNullRequestValue() { + strategy = new ExactMatchStrategy("exact"); + boolean result = strategy.isMatch(null); + Assert.assertFalse(strategy.isMatch(null)); + } +} \ No newline at end of file diff --git a/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/PrefixMatchStrategyTest.java b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/PrefixMatchStrategyTest.java new file mode 100644 index 0000000000..f8d6c5ab04 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/PrefixMatchStrategyTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity.match; + +import org.junit.Assert; +import org.junit.Test; + +/** + * PrefixMatchStrategyTest + * + * @author daizhenyu + * @since 2024-08-24 + **/ +public class PrefixMatchStrategyTest { + private PrefixMatchStrategy strategy; + + @Test + public void testConstructorWithNonNullPrefix() { + String expectedPrefix = "test"; + strategy = new PrefixMatchStrategy(expectedPrefix); + Assert.assertTrue(strategy.isMatch("testValue")); + } + + @Test + public void testConstructorWithNullPrefix() { + strategy = new PrefixMatchStrategy(null); + Assert.assertTrue(strategy.isMatch("anyValue")); + Assert.assertTrue(strategy.isMatch("")); + } + + @Test + public void testIsMatchWithMatchingPrefix() { + strategy = new PrefixMatchStrategy("pre"); + Assert.assertTrue(strategy.isMatch("prefixValue")); + } + + @Test + public void testIsMatchWithNonMatchingPrefix() { + strategy = new PrefixMatchStrategy("pre"); + Assert.assertFalse(strategy.isMatch("valuePrefix")); + } + + @Test + public void testIsMatchWithEmptyPrefix() { + strategy = new PrefixMatchStrategy(""); + Assert.assertTrue(strategy.isMatch("anyValue")); + Assert.assertTrue(strategy.isMatch("")); + } + + @Test + public void testIsMatchWithNullRequestValue() { + strategy = new PrefixMatchStrategy("pre"); + Assert.assertFalse(strategy.isMatch(null)); + } + + @Test + public void testIsMatchWithExactMatch() { + strategy = new PrefixMatchStrategy("exact"); + Assert.assertTrue(strategy.isMatch("exact")); + } +} \ No newline at end of file diff --git a/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/PresentMatchStrategyTest.java b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/PresentMatchStrategyTest.java new file mode 100644 index 0000000000..d96c222fec --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/PresentMatchStrategyTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity.match; + +import org.junit.Assert; +import org.junit.Test; + +/** + * PresentMatchStrategyTest + * + * @author daizhenyu + * @since 2024-08-24 + **/ +public class PresentMatchStrategyTest { + private PresentMatchStrategy strategy; + + @Test + public void testIsMatchWithNonNullValue() { + strategy = new PresentMatchStrategy(); + Assert.assertTrue(strategy.isMatch("anyValue")); + } + + @Test + public void testIsMatchWithEmptyValue() { + strategy = new PresentMatchStrategy(); + Assert.assertTrue(strategy.isMatch("")); + } + + @Test + public void testIsMatchWithNullValue() { + strategy = new PresentMatchStrategy(); + Assert.assertTrue(strategy.isMatch(null)); + } +} \ No newline at end of file diff --git a/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/RegexMatchStrategyTest.java b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/RegexMatchStrategyTest.java new file mode 100644 index 0000000000..13cf5c3682 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/RegexMatchStrategyTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity.match; + +import org.junit.Assert; +import org.junit.Test; + +/** + * RegexMatchStrategyTest + * + * @author daizhenyu + * @since 2024-08-24 + **/ +public class RegexMatchStrategyTest { + private RegexMatchStrategy strategy; + + @Test + public void testIsMatchWithValidRegex() { + strategy = new RegexMatchStrategy("^[a-z]+$"); + Assert.assertTrue(strategy.isMatch("abc")); + Assert.assertFalse(strategy.isMatch("abc123")); + } + + @Test + public void testIsMatchWithNullRegex() { + strategy = new RegexMatchStrategy(null); + Assert.assertTrue(strategy.isMatch("anyValue")); + Assert.assertTrue(strategy.isMatch("")); + } + + @Test + public void testIsMatchWithEmptyRegex() { + strategy = new RegexMatchStrategy(""); + Assert.assertTrue(strategy.isMatch("anyValue")); + Assert.assertTrue(strategy.isMatch("")); + Assert.assertFalse(strategy.isMatch(null)); + } + + @Test + public void testIsMatchWithNullRequestValue() { + strategy = new RegexMatchStrategy(".*"); + Assert.assertFalse(strategy.isMatch(null)); + } + + @Test + public void testIsMatchWithComplexRegex() { + strategy = new RegexMatchStrategy("^\\d{3}-\\d{2}-\\d{4}$"); + Assert.assertTrue(strategy.isMatch("123-45-6789")); + Assert.assertFalse(strategy.isMatch("123-456-789")); + } +} \ No newline at end of file diff --git a/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/SuffixMatchStrategyTest.java b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/SuffixMatchStrategyTest.java new file mode 100644 index 0000000000..5107bb8273 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/SuffixMatchStrategyTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity.match; + +import org.junit.Assert; +import org.junit.Test; + +/** + * SuffixMatchStrategyTest + * + * @author daizhenyu + * @since 2024-08-24 + **/ +public class SuffixMatchStrategyTest { + private SuffixMatchStrategy strategy; + + @Test + public void testIsMatchWithValidSuffix() { + strategy = new SuffixMatchStrategy("suffix"); + Assert.assertTrue(strategy.isMatch("testsuffix")); + Assert.assertFalse(strategy.isMatch("suffixTest")); + } + + @Test + public void testIsMatchWithNullSuffix() { + strategy = new SuffixMatchStrategy(null); + Assert.assertTrue(strategy.isMatch("anyValue")); + Assert.assertTrue(strategy.isMatch("")); + } + + @Test + public void testIsMatchWithEmptySuffix() { + strategy = new SuffixMatchStrategy(""); + Assert.assertTrue(strategy.isMatch("anyValue")); + Assert.assertTrue(strategy.isMatch("")); + Assert.assertFalse(strategy.isMatch(null)); + } + + @Test + public void testIsMatchWithNullRequestValue() { + strategy = new SuffixMatchStrategy("suffix"); + Assert.assertFalse(strategy.isMatch(null)); + } + + @Test + public void testIsMatchWithExactMatch() { + strategy = new SuffixMatchStrategy("exact"); + Assert.assertTrue(strategy.isMatch("exact")); + } + + @Test + public void testIsMatchWithNonMatchingSuffix() { + strategy = new SuffixMatchStrategy("suffix"); + Assert.assertFalse(strategy.isMatch("test")); + } +} \ No newline at end of file diff --git a/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/UnknownMatchStrategyTest.java b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/UnknownMatchStrategyTest.java new file mode 100644 index 0000000000..aaecc4f301 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/test/java/io/sermant/core/service/xds/entity/match/UnknownMatchStrategyTest.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024-2024 Sermant Authors. All rights reserved. + * + * 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 io.sermant.core.service.xds.entity.match; + +import org.junit.Assert; +import org.junit.Test; + +/** + * UnknownMatchStrategyTest + * + * @author daizhenyu + * @since 2024-08-24 + **/ +public class UnknownMatchStrategyTest { + @Test + public void testIsMatchWithAnyValue() { + UnknownMatchStrategy strategy = new UnknownMatchStrategy(); + Assert.assertFalse(strategy.isMatch("anyValue")); + Assert.assertFalse(strategy.isMatch("")); + Assert.assertFalse(strategy.isMatch(null)); + } +} \ No newline at end of file