Browse Source
* pr/18287: Polish 'Add @LocalRSocketServerPort support' Add @LocalRSocketServerPort support Closes gh-18287pull/18413/head
6 changed files with 209 additions and 3 deletions
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
/* |
||||
* Copyright 2012-2019 the original author or authors. |
||||
* |
||||
* 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 |
||||
* |
||||
* https://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 org.springframework.boot.rsocket.context; |
||||
|
||||
import java.lang.annotation.Documented; |
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
import org.springframework.beans.factory.annotation.Value; |
||||
|
||||
/** |
||||
* Annotation at the field or method/constructor parameter level that injects the RSocket |
||||
* port that got allocated at runtime. Provides a convenient alternative for |
||||
* <code>@Value("${local.rsocket.server.port}")</code>. |
||||
* |
||||
* @author Verónica Vásquez |
||||
* @author Eddú Meléndez |
||||
* @since 2.2.0 |
||||
*/ |
||||
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Documented |
||||
@Value("${local.rsocket.server.port}") |
||||
public @interface LocalRSocketServerPort { |
||||
|
||||
} |
||||
@ -0,0 +1,95 @@
@@ -0,0 +1,95 @@
|
||||
/* |
||||
* Copyright 2012-2019 the original author or authors. |
||||
* |
||||
* 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 |
||||
* |
||||
* https://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 org.springframework.boot.rsocket.context; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
import org.springframework.beans.factory.annotation.Value; |
||||
import org.springframework.boot.rsocket.server.RSocketServer; |
||||
import org.springframework.context.ApplicationContext; |
||||
import org.springframework.context.ApplicationContextInitializer; |
||||
import org.springframework.context.ApplicationListener; |
||||
import org.springframework.context.ConfigurableApplicationContext; |
||||
import org.springframework.core.env.ConfigurableEnvironment; |
||||
import org.springframework.core.env.Environment; |
||||
import org.springframework.core.env.MapPropertySource; |
||||
import org.springframework.core.env.MutablePropertySources; |
||||
import org.springframework.core.env.PropertySource; |
||||
|
||||
/** |
||||
* {@link ApplicationContextInitializer} that sets {@link Environment} properties for the |
||||
* ports that {@link RSocketServer} servers are actually listening on. The property |
||||
* {@literal "local.rsocket.server.port"} can be injected directly into tests using |
||||
* {@link Value @Value} or obtained via the {@link Environment}. |
||||
* <p> |
||||
* Properties are automatically propagated up to any parent context. |
||||
* |
||||
* @author Verónica Vásquez |
||||
* @author Eddú Meléndez |
||||
* @since 2.2.0 |
||||
*/ |
||||
public class RSocketPortInfoApplicationContextInitializer |
||||
implements ApplicationContextInitializer<ConfigurableApplicationContext> { |
||||
|
||||
@Override |
||||
public void initialize(ConfigurableApplicationContext applicationContext) { |
||||
applicationContext.addApplicationListener(new Listener(applicationContext)); |
||||
} |
||||
|
||||
private static class Listener implements ApplicationListener<RSocketServerInitializedEvent> { |
||||
|
||||
private static final String PROPERTY_NAME = "local.rsocket.server.port"; |
||||
|
||||
private ConfigurableApplicationContext applicationContext; |
||||
|
||||
Listener(ConfigurableApplicationContext applicationContext) { |
||||
this.applicationContext = applicationContext; |
||||
} |
||||
|
||||
@Override |
||||
public void onApplicationEvent(RSocketServerInitializedEvent event) { |
||||
setPortProperty(this.applicationContext, event.getrSocketServer().address().getPort()); |
||||
} |
||||
|
||||
private void setPortProperty(ApplicationContext context, int port) { |
||||
if (context instanceof ConfigurableApplicationContext) { |
||||
setPortProperty(((ConfigurableApplicationContext) context).getEnvironment(), port); |
||||
} |
||||
if (context.getParent() != null) { |
||||
setPortProperty(context.getParent(), port); |
||||
} |
||||
} |
||||
|
||||
private void setPortProperty(ConfigurableEnvironment environment, int port) { |
||||
MutablePropertySources sources = environment.getPropertySources(); |
||||
PropertySource<?> source = sources.get("server.ports"); |
||||
if (source == null) { |
||||
source = new MapPropertySource("server.ports", new HashMap<>()); |
||||
sources.addFirst(source); |
||||
} |
||||
setPortProperty(port, source); |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
private void setPortProperty(int port, PropertySource<?> source) { |
||||
((Map<String, Object>) source.getSource()).put(PROPERTY_NAME, port); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
/* |
||||
* Copyright 2012-2019 the original author or authors. |
||||
* |
||||
* 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 |
||||
* |
||||
* https://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 org.springframework.boot.rsocket.context; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
import org.junit.jupiter.api.extension.ExtendWith; |
||||
|
||||
import org.springframework.beans.factory.annotation.Value; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.test.context.TestPropertySource; |
||||
import org.springframework.test.context.junit.jupiter.SpringExtension; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link LocalRSocketServerPort @LocalRSocketServerPort}. |
||||
* |
||||
* @author Verónica Vásquez |
||||
* @author Eddú Meléndez |
||||
*/ |
||||
@ExtendWith(SpringExtension.class) |
||||
@TestPropertySource(properties = "local.rsocket.server.port=8181") |
||||
class LocalRSocketServerPortTests { |
||||
|
||||
@Value("${local.rsocket.server.port}") |
||||
private String fromValue; |
||||
|
||||
@LocalRSocketServerPort |
||||
private String fromAnnotation; |
||||
|
||||
@Test |
||||
void testLocalRSocketServerPortAnnotation() { |
||||
assertThat(this.fromAnnotation).isNotNull().isEqualTo(this.fromValue); |
||||
} |
||||
|
||||
@Configuration(proxyBeanMethods = false) |
||||
static class Config { |
||||
|
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue