Skip to content

Commit c79e9ad

Browse files
committed
Adds RouteDeletedEvent used in WeightCalculatorWebFilter
Fixes gh-922
1 parent f0ad75a commit c79e9ad

File tree

4 files changed

+63
-3
lines changed

4 files changed

+63
-3
lines changed

spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/actuate/AbstractGatewayControllerEndpoint.java

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

3535
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
3636
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
37+
import org.springframework.cloud.gateway.event.RouteDeletedEvent;
3738
import org.springframework.cloud.gateway.filter.FilterDefinition;
3839
import org.springframework.cloud.gateway.filter.GlobalFilter;
3940
import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;
@@ -307,9 +308,10 @@ private boolean isAvailable(PredicateDefinition predicateDefinition) {
307308

308309
@DeleteMapping("/routes/{id}")
309310
public Mono<ResponseEntity<Object>> delete(@PathVariable String id) {
310-
return this.routeDefinitionWriter.delete(Mono.just(id))
311-
.then(Mono.defer(() -> Mono.just(ResponseEntity.ok().build())))
312-
.onErrorResume(t -> t instanceof NotFoundException, t -> Mono.just(ResponseEntity.notFound().build()));
311+
return this.routeDefinitionWriter.delete(Mono.just(id)).then(Mono.defer(() -> {
312+
publisher.publishEvent(new RouteDeletedEvent(this, id));
313+
return Mono.just(ResponseEntity.ok().build());
314+
})).onErrorResume(t -> t instanceof NotFoundException, t -> Mono.just(ResponseEntity.notFound().build()));
313315
}
314316

315317
@GetMapping("/routes/{id}/combinedfilters")
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2013-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.gateway.event;
18+
19+
import org.springframework.context.ApplicationEvent;
20+
21+
public class RouteDeletedEvent extends ApplicationEvent {
22+
23+
private final String routeId;
24+
25+
public RouteDeletedEvent(Object source, String routeId) {
26+
super(source);
27+
this.routeId = routeId;
28+
}
29+
30+
public String getRouteId() {
31+
return routeId;
32+
}
33+
34+
}

spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/WeightCalculatorWebFilter.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,15 @@
3535
import org.springframework.beans.factory.ObjectProvider;
3636
import org.springframework.cloud.gateway.event.PredicateArgsEvent;
3737
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
38+
import org.springframework.cloud.gateway.event.RouteDeletedEvent;
3839
import org.springframework.cloud.gateway.event.WeightDefinedEvent;
3940
import org.springframework.cloud.gateway.route.RouteLocator;
4041
import org.springframework.cloud.gateway.support.ConfigurationService;
4142
import org.springframework.cloud.gateway.support.WeightConfig;
4243
import org.springframework.context.ApplicationEvent;
4344
import org.springframework.context.event.SmartApplicationListener;
4445
import org.springframework.core.Ordered;
46+
import org.springframework.core.log.LogMessage;
4547
import org.springframework.core.style.ToStringCreator;
4648
import org.springframework.util.Assert;
4749
import org.springframework.web.server.ServerWebExchange;
@@ -123,6 +125,8 @@ public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
123125
return PredicateArgsEvent.class.isAssignableFrom(eventType) ||
124126
// from java dsl
125127
WeightDefinedEvent.class.isAssignableFrom(eventType) ||
128+
// from actuator or custom call
129+
RouteDeletedEvent.class.isAssignableFrom(eventType) ||
126130
// force initialization
127131
RefreshRoutesEvent.class.isAssignableFrom(eventType);
128132
}
@@ -140,6 +144,9 @@ public void onApplicationEvent(ApplicationEvent event) {
140144
else if (event instanceof WeightDefinedEvent) {
141145
addWeightConfig(((WeightDefinedEvent) event).getWeightConfig());
142146
}
147+
else if (event instanceof RouteDeletedEvent) {
148+
removeWeightConfig(((RouteDeletedEvent) event).getRouteId());
149+
}
143150
else if (event instanceof RefreshRoutesEvent && routeLocator != null) {
144151
// forces initialization
145152
if (routeLocatorInitialized.compareAndSet(false, true)) {
@@ -229,6 +236,16 @@ private boolean hasRelevantKey(Map<String, Object> args) {
229236
groupWeights.put(group, config);
230237
}
231238

239+
private void removeWeightConfig(String routeId) {
240+
log.trace(LogMessage.format("Removing weight config for route %s", routeId));
241+
groupWeights.forEach((group, weightConfig) -> {
242+
if (weightConfig.normalizedWeights.containsKey(routeId)) {
243+
weightConfig.normalizedWeights.remove(routeId);
244+
weightConfig.weights.remove(routeId);
245+
}
246+
});
247+
}
248+
232249
/* for testing */ Map<String, GroupWeightConfig> getGroupWeights() {
233250
return groupWeights;
234251
}

spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/WeightCalculatorWebFilterTests.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.junit.jupiter.api.Test;
2525

2626
import org.springframework.cloud.gateway.event.PredicateArgsEvent;
27+
import org.springframework.cloud.gateway.event.RouteDeletedEvent;
2728
import org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter.GroupWeightConfig;
2829
import org.springframework.cloud.gateway.support.ConfigurationService;
2930
import org.springframework.cloud.gateway.support.WeightConfig;
@@ -121,6 +122,12 @@ public void testChooseRouteWithRandom() {
121122
filter.filter(exchange, filterChain);
122123
weights = WeightCalculatorWebFilter.getWeights(exchange);
123124
assertThat(weights).containsEntry("groupa", "route3");
125+
126+
filter.onApplicationEvent(new RouteDeletedEvent(this, "route3"));
127+
assertThat(filter.getGroupWeights()).containsKey("groupa");
128+
GroupWeightConfig groupa = filter.getGroupWeights().get("groupa");
129+
assertThat(groupa.normalizedWeights).doesNotContainKey("route3");
130+
assertThat(groupa.weights).doesNotContainKey("route3");
124131
}
125132

126133
@Test

0 commit comments

Comments
 (0)