72 changed files with 96 additions and 3072 deletions
@ -1,63 +0,0 @@
@@ -1,63 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.actuate.autoconfigure.influx; |
||||
|
||||
import java.util.Map; |
||||
|
||||
import org.influxdb.InfluxDB; |
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; |
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; |
||||
import org.springframework.boot.actuate.health.HealthContributor; |
||||
import org.springframework.boot.actuate.influx.InfluxDbHealthIndicator; |
||||
import org.springframework.boot.autoconfigure.AutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
||||
import org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration; |
||||
import org.springframework.context.annotation.Bean; |
||||
|
||||
/** |
||||
* {@link EnableAutoConfiguration Auto-configuration} for {@link InfluxDbHealthIndicator}. |
||||
* |
||||
* @author Eddú Meléndez |
||||
* @since 2.0.0 |
||||
* @deprecated since 3.2.0 for removal in 3.4.0 in favor of the |
||||
* <a href="https://github.com/influxdata/influxdb-client-java">new client</a> and its own |
||||
* Spring Boot integration. |
||||
*/ |
||||
@SuppressWarnings("removal") |
||||
@AutoConfiguration(after = InfluxDbAutoConfiguration.class) |
||||
@ConditionalOnClass(InfluxDB.class) |
||||
@ConditionalOnBean(InfluxDB.class) |
||||
@ConditionalOnEnabledHealthIndicator("influxdb") |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
public class InfluxDbHealthContributorAutoConfiguration |
||||
extends CompositeHealthContributorConfiguration<InfluxDbHealthIndicator, InfluxDB> { |
||||
|
||||
public InfluxDbHealthContributorAutoConfiguration() { |
||||
super(InfluxDbHealthIndicator::new); |
||||
} |
||||
|
||||
@Bean |
||||
@ConditionalOnMissingBean(name = { "influxDbHealthIndicator", "influxDbHealthContributor" }) |
||||
public HealthContributor influxDbHealthContributor(Map<String, InfluxDB> influxDbs) { |
||||
return createContributor(influxDbs); |
||||
} |
||||
|
||||
} |
||||
@ -1,20 +0,0 @@
@@ -1,20 +0,0 @@
|
||||
/* |
||||
* 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. |
||||
*/ |
||||
|
||||
/** |
||||
* Auto-configuration for actuator InfluxDB concerns. |
||||
*/ |
||||
package org.springframework.boot.actuate.autoconfigure.influx; |
||||
@ -1,55 +0,0 @@
@@ -1,55 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.actuate.autoconfigure.influx; |
||||
|
||||
import org.influxdb.InfluxDB; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; |
||||
import org.springframework.boot.actuate.influx.InfluxDbHealthIndicator; |
||||
import org.springframework.boot.autoconfigure.AutoConfigurations; |
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.mockito.Mockito.mock; |
||||
|
||||
/** |
||||
* Tests for {@link InfluxDbHealthContributorAutoConfiguration}. |
||||
* |
||||
* @author Eddú Meléndez |
||||
*/ |
||||
@SuppressWarnings("removal") |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
class InfluxDbHealthContributorAutoConfigurationTests { |
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() |
||||
.withBean(InfluxDB.class, () -> mock(InfluxDB.class)) |
||||
.withConfiguration(AutoConfigurations.of(InfluxDbHealthContributorAutoConfiguration.class, |
||||
HealthContributorAutoConfiguration.class)); |
||||
|
||||
@Test |
||||
void runShouldCreateIndicator() { |
||||
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(InfluxDbHealthIndicator.class)); |
||||
} |
||||
|
||||
@Test |
||||
void runWhenDisabledShouldNotCreateIndicator() { |
||||
this.contextRunner.withPropertyValues("management.health.influxdb.enabled:false") |
||||
.run((context) -> assertThat(context).doesNotHaveBean(InfluxDbHealthIndicator.class)); |
||||
} |
||||
|
||||
} |
||||
@ -1,53 +0,0 @@
@@ -1,53 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.actuate.influx; |
||||
|
||||
import org.influxdb.InfluxDB; |
||||
import org.influxdb.dto.Pong; |
||||
|
||||
import org.springframework.boot.actuate.health.AbstractHealthIndicator; |
||||
import org.springframework.boot.actuate.health.Health; |
||||
import org.springframework.boot.actuate.health.HealthIndicator; |
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* {@link HealthIndicator} for InfluxDB. |
||||
* |
||||
* @author Eddú Meléndez |
||||
* @since 2.0.0 |
||||
* @deprecated since 3.2.0 for removal in 3.4.0 in favor of the |
||||
* <a href="https://github.com/influxdata/influxdb-client-java">new client</a> and its own |
||||
* Spring Boot integration. |
||||
*/ |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
public class InfluxDbHealthIndicator extends AbstractHealthIndicator { |
||||
|
||||
private final InfluxDB influxDb; |
||||
|
||||
public InfluxDbHealthIndicator(InfluxDB influxDb) { |
||||
super("InfluxDB health check failed"); |
||||
Assert.notNull(influxDb, "InfluxDB must not be null"); |
||||
this.influxDb = influxDb; |
||||
} |
||||
|
||||
@Override |
||||
protected void doHealthCheck(Health.Builder builder) { |
||||
Pong pong = this.influxDb.ping(); |
||||
builder.up().withDetail("version", pong.getVersion()); |
||||
} |
||||
|
||||
} |
||||
@ -1,20 +0,0 @@
@@ -1,20 +0,0 @@
|
||||
/* |
||||
* 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. |
||||
*/ |
||||
|
||||
/** |
||||
* Actuator support for InfluxDB. |
||||
*/ |
||||
package org.springframework.boot.actuate.influx; |
||||
@ -1,67 +0,0 @@
@@ -1,67 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.actuate.influx; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
import org.influxdb.InfluxDB; |
||||
import org.influxdb.InfluxDBException; |
||||
import org.influxdb.dto.Pong; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.boot.actuate.health.Health; |
||||
import org.springframework.boot.actuate.health.Status; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.mockito.BDDMockito.given; |
||||
import static org.mockito.BDDMockito.then; |
||||
import static org.mockito.Mockito.mock; |
||||
|
||||
/** |
||||
* Tests for {@link InfluxDbHealthIndicator}. |
||||
* |
||||
* @author Eddú Meléndez |
||||
*/ |
||||
@SuppressWarnings("removal") |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
class InfluxDbHealthIndicatorTests { |
||||
|
||||
@Test |
||||
void influxDbIsUp() { |
||||
Pong pong = mock(Pong.class); |
||||
given(pong.getVersion()).willReturn("0.9"); |
||||
InfluxDB influxDb = mock(InfluxDB.class); |
||||
given(influxDb.ping()).willReturn(pong); |
||||
InfluxDbHealthIndicator healthIndicator = new InfluxDbHealthIndicator(influxDb); |
||||
Health health = healthIndicator.health(); |
||||
assertThat(health.getStatus()).isEqualTo(Status.UP); |
||||
assertThat(health.getDetails()).containsEntry("version", "0.9"); |
||||
then(influxDb).should().ping(); |
||||
} |
||||
|
||||
@Test |
||||
void influxDbIsDown() { |
||||
InfluxDB influxDb = mock(InfluxDB.class); |
||||
given(influxDb.ping()).willThrow(new InfluxDBException(new IOException("Connection failed"))); |
||||
InfluxDbHealthIndicator healthIndicator = new InfluxDbHealthIndicator(influxDb); |
||||
Health health = healthIndicator.health(); |
||||
assertThat(health.getStatus()).isEqualTo(Status.DOWN); |
||||
assertThat((String) health.getDetails().get("error")).contains("Connection failed"); |
||||
then(influxDb).should().ping(); |
||||
} |
||||
|
||||
} |
||||
@ -1,71 +0,0 @@
@@ -1,71 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.autoconfigure.influx; |
||||
|
||||
import okhttp3.OkHttpClient; |
||||
import org.influxdb.InfluxDB; |
||||
import org.influxdb.impl.InfluxDBImpl; |
||||
|
||||
import org.springframework.beans.factory.ObjectProvider; |
||||
import org.springframework.boot.autoconfigure.AutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties; |
||||
import org.springframework.context.annotation.Bean; |
||||
|
||||
/** |
||||
* {@link EnableAutoConfiguration Auto-configuration} for InfluxDB. |
||||
* |
||||
* @author Sergey Kuptsov |
||||
* @author Stephane Nicoll |
||||
* @author Eddú Meléndez |
||||
* @author Moritz Halbritter |
||||
* @author Andy Wilkinson |
||||
* @author Phillip Webb |
||||
* @since 2.0.0 |
||||
* @deprecated since 3.2.0 for removal in 3.4.0 in favor of the |
||||
* <a href="https://github.com/influxdata/influxdb-client-java">new client</a> and its own |
||||
* Spring Boot integration. |
||||
*/ |
||||
@AutoConfiguration |
||||
@ConditionalOnClass(InfluxDB.class) |
||||
@EnableConfigurationProperties(InfluxDbProperties.class) |
||||
@ConditionalOnProperty("spring.influx.url") |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
@SuppressWarnings("removal") |
||||
public class InfluxDbAutoConfiguration { |
||||
|
||||
@Bean |
||||
@ConditionalOnMissingBean |
||||
public InfluxDB influxDb(InfluxDbProperties properties, ObjectProvider<InfluxDbOkHttpClientBuilderProvider> builder, |
||||
ObjectProvider<InfluxDbCustomizer> customizers) { |
||||
InfluxDB influxDb = new InfluxDBImpl(properties.getUrl().toString(), properties.getUser(), |
||||
properties.getPassword(), determineBuilder(builder.getIfAvailable())); |
||||
customizers.orderedStream().forEach((customizer) -> customizer.customize(influxDb)); |
||||
return influxDb; |
||||
} |
||||
|
||||
private static OkHttpClient.Builder determineBuilder(InfluxDbOkHttpClientBuilderProvider builder) { |
||||
if (builder != null) { |
||||
return builder.get(); |
||||
} |
||||
return new OkHttpClient.Builder(); |
||||
} |
||||
|
||||
} |
||||
@ -1,41 +0,0 @@
@@ -1,41 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.autoconfigure.influx; |
||||
|
||||
import org.influxdb.InfluxDB; |
||||
|
||||
/** |
||||
* Callback interface that can be implemented by beans wishing to further customize |
||||
* {@code InfluxDB} whilst retaining default auto-configuration. |
||||
* |
||||
* @author Eddú Meléndez |
||||
* @since 2.5.0 |
||||
* @deprecated since 3.2.0 for removal in 3.4.0 in favor of the |
||||
* <a href="https://github.com/influxdata/influxdb-client-java">new client</a> and its own |
||||
* Spring Boot integration. |
||||
*/ |
||||
@FunctionalInterface |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
public interface InfluxDbCustomizer { |
||||
|
||||
/** |
||||
* Customize the {@link InfluxDB}. |
||||
* @param influxDb the InfluxDB instance to customize |
||||
*/ |
||||
void customize(InfluxDB influxDb); |
||||
|
||||
} |
||||
@ -1,38 +0,0 @@
@@ -1,38 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.autoconfigure.influx; |
||||
|
||||
import java.util.function.Supplier; |
||||
|
||||
import okhttp3.OkHttpClient; |
||||
import org.influxdb.InfluxDB; |
||||
|
||||
/** |
||||
* Provide the {@link okhttp3.OkHttpClient.Builder OkHttpClient.Builder} to use to |
||||
* customize the auto-configured {@link InfluxDB} instance. |
||||
* |
||||
* @author Stephane Nicoll |
||||
* @since 2.1.0 |
||||
* @deprecated since 3.2.0 for removal in 3.4.0 in favor of the |
||||
* <a href="https://github.com/influxdata/influxdb-client-java">new client</a> and its own |
||||
* Spring Boot integration. |
||||
*/ |
||||
@FunctionalInterface |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
public interface InfluxDbOkHttpClientBuilderProvider extends Supplier<OkHttpClient.Builder> { |
||||
|
||||
} |
||||
@ -1,81 +0,0 @@
@@ -1,81 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.autoconfigure.influx; |
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; |
||||
|
||||
/** |
||||
* Configuration properties for InfluxDB. |
||||
* |
||||
* @author Sergey Kuptsov |
||||
* @author Stephane Nicoll |
||||
* @since 2.0.0 |
||||
* @deprecated since 3.2.0 for removal in 3.4.0 in favor of the |
||||
* <a href="https://github.com/influxdata/influxdb-client-java">new InfluxDB Java |
||||
* client</a> and its own Spring Boot integration. |
||||
*/ |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
@ConfigurationProperties(prefix = "spring.influx") |
||||
public class InfluxDbProperties { |
||||
|
||||
/** |
||||
* URL of the InfluxDB instance to which to connect. |
||||
*/ |
||||
private String url; |
||||
|
||||
/** |
||||
* Login user. |
||||
*/ |
||||
private String user; |
||||
|
||||
/** |
||||
* Login password. |
||||
*/ |
||||
private String password; |
||||
|
||||
@DeprecatedConfigurationProperty(reason = "the new InfluxDb Java client provides Spring Boot integration", |
||||
since = "3.2.0") |
||||
public String getUrl() { |
||||
return this.url; |
||||
} |
||||
|
||||
public void setUrl(String url) { |
||||
this.url = url; |
||||
} |
||||
|
||||
@DeprecatedConfigurationProperty(reason = "the new InfluxDb Java client provides Spring Boot integration", |
||||
since = "3.2.0") |
||||
public String getUser() { |
||||
return this.user; |
||||
} |
||||
|
||||
public void setUser(String user) { |
||||
this.user = user; |
||||
} |
||||
|
||||
@DeprecatedConfigurationProperty(reason = "the new InfluxDb Java client provides Spring Boot integration", |
||||
since = "3.2.0") |
||||
public String getPassword() { |
||||
return this.password; |
||||
} |
||||
|
||||
public void setPassword(String password) { |
||||
this.password = password; |
||||
} |
||||
|
||||
} |
||||
@ -1,20 +0,0 @@
@@ -1,20 +0,0 @@
|
||||
/* |
||||
* 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. |
||||
*/ |
||||
|
||||
/** |
||||
* Auto-configuration for InfluxDB. |
||||
*/ |
||||
package org.springframework.boot.autoconfigure.influx; |
||||
@ -1,37 +0,0 @@
@@ -1,37 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.autoconfigure.transaction; |
||||
|
||||
import org.springframework.transaction.PlatformTransactionManager; |
||||
|
||||
/** |
||||
* Callback interface that can be implemented by beans wishing to customize |
||||
* {@link PlatformTransactionManager PlatformTransactionManagers} whilst retaining default |
||||
* auto-configuration. |
||||
* |
||||
* @param <T> the transaction manager type |
||||
* @author Phillip Webb |
||||
* @since 1.5.0 |
||||
* @deprecated since 3.2.0 for removal in 3.4.0 in favor of |
||||
* {@link TransactionManagerCustomizer}. |
||||
*/ |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
@FunctionalInterface |
||||
public interface PlatformTransactionManagerCustomizer<T extends PlatformTransactionManager> |
||||
extends TransactionManagerCustomizer<T> { |
||||
|
||||
} |
||||
@ -1,114 +0,0 @@
@@ -1,114 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.autoconfigure.influx; |
||||
|
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
import okhttp3.OkHttpClient; |
||||
import org.influxdb.InfluxDB; |
||||
import org.junit.jupiter.api.Test; |
||||
import retrofit2.Retrofit; |
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations; |
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext; |
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.test.util.ReflectionTestUtils; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link InfluxDbAutoConfiguration}. |
||||
* |
||||
* @author Sergey Kuptsov |
||||
* @author Stephane Nicoll |
||||
* @author Eddú Meléndez |
||||
* @author Moritz Halbritter |
||||
* @author Andy Wilkinson |
||||
* @author Phillip Webb |
||||
*/ |
||||
@SuppressWarnings("removal") |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
class InfluxDbAutoConfigurationTests { |
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() |
||||
.withConfiguration(AutoConfigurations.of(InfluxDbAutoConfiguration.class)); |
||||
|
||||
@Test |
||||
void influxDbRequiresUrl() { |
||||
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(InfluxDB.class)); |
||||
} |
||||
|
||||
@Test |
||||
void influxDbCanBeCustomized() { |
||||
this.contextRunner |
||||
.withPropertyValues("spring.influx.url=http://localhost", "spring.influx.user=user", |
||||
"spring.influx.password=password") |
||||
.run((context) -> assertThat(context).hasSingleBean(InfluxDB.class)); |
||||
} |
||||
|
||||
@Test |
||||
void influxDbCanBeCreatedWithoutCredentials() { |
||||
this.contextRunner.withPropertyValues("spring.influx.url=http://localhost").run((context) -> { |
||||
assertThat(context).hasSingleBean(InfluxDB.class); |
||||
int readTimeout = getReadTimeoutProperty(context); |
||||
assertThat(readTimeout).isEqualTo(10_000); |
||||
}); |
||||
} |
||||
|
||||
@Test |
||||
void influxDbWithOkHttpClientBuilderProvider() { |
||||
this.contextRunner.withUserConfiguration(CustomOkHttpClientBuilderProviderConfig.class) |
||||
.withPropertyValues("spring.influx.url=http://localhost") |
||||
.run((context) -> { |
||||
assertThat(context).hasSingleBean(InfluxDB.class); |
||||
int readTimeout = getReadTimeoutProperty(context); |
||||
assertThat(readTimeout).isEqualTo(40_000); |
||||
}); |
||||
} |
||||
|
||||
@Test |
||||
void influxDbWithCustomizer() { |
||||
this.contextRunner.withBean(InfluxDbCustomizer.class, () -> (influxDb) -> influxDb.setDatabase("test")) |
||||
.withPropertyValues("spring.influx.url=http://localhost") |
||||
.run((context) -> { |
||||
assertThat(context).hasSingleBean(InfluxDB.class); |
||||
InfluxDB influxDb = context.getBean(InfluxDB.class); |
||||
assertThat(influxDb).hasFieldOrPropertyWithValue("database", "test"); |
||||
}); |
||||
} |
||||
|
||||
private int getReadTimeoutProperty(AssertableApplicationContext context) { |
||||
InfluxDB influxDb = context.getBean(InfluxDB.class); |
||||
Retrofit retrofit = (Retrofit) ReflectionTestUtils.getField(influxDb, "retrofit"); |
||||
OkHttpClient callFactory = (OkHttpClient) retrofit.callFactory(); |
||||
return callFactory.readTimeoutMillis(); |
||||
} |
||||
|
||||
@Configuration(proxyBeanMethods = false) |
||||
static class CustomOkHttpClientBuilderProviderConfig { |
||||
|
||||
@Bean |
||||
@SuppressWarnings("removal") |
||||
InfluxDbOkHttpClientBuilderProvider influxDbOkHttpClientBuilderProvider() { |
||||
return () -> new OkHttpClient.Builder().readTimeout(40, TimeUnit.SECONDS); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -1,50 +0,0 @@
@@ -1,50 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2024 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.testcontainers.properties; |
||||
|
||||
import java.util.function.Supplier; |
||||
|
||||
import org.springframework.boot.testcontainers.lifecycle.BeforeTestcontainerUsedEvent; |
||||
|
||||
/** |
||||
* Event published just before the {@link Supplier value supplier} of a |
||||
* {@link TestcontainersPropertySource} property is called. |
||||
* |
||||
* @author Phillip Webb |
||||
* @since 3.2.2 |
||||
* @deprecated since 3.2.6 for removal in 3.4.0 in favor of |
||||
* {@link BeforeTestcontainerUsedEvent} |
||||
*/ |
||||
@Deprecated(since = "3.2.6", forRemoval = true) |
||||
public class BeforeTestcontainersPropertySuppliedEvent extends BeforeTestcontainerUsedEvent { |
||||
|
||||
private final String propertyName; |
||||
|
||||
BeforeTestcontainersPropertySuppliedEvent(TestcontainersPropertySource source, String propertyName) { |
||||
super(source); |
||||
this.propertyName = propertyName; |
||||
} |
||||
|
||||
/** |
||||
* Return the name of the property about to be supplied. |
||||
* @return the propertyName the property name |
||||
*/ |
||||
public String getPropertyName() { |
||||
return this.propertyName; |
||||
} |
||||
|
||||
} |
||||
@ -1,27 +0,0 @@
@@ -1,27 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
<groupId>org.springframework.boot.maven.it</groupId> |
||||
<artifactId>run-directories</artifactId> |
||||
<version>0.0.1.BUILD-SNAPSHOT</version> |
||||
<properties> |
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
<maven.compiler.source>@java.version@</maven.compiler.source> |
||||
<maven.compiler.target>@java.version@</maven.compiler.target> |
||||
</properties> |
||||
<build> |
||||
<plugins> |
||||
<plugin> |
||||
<groupId>@project.groupId@</groupId> |
||||
<artifactId>@project.artifactId@</artifactId> |
||||
<version>@project.version@</version> |
||||
<configuration> |
||||
<directories> |
||||
<directory>src/main/additional-elements/</directory> |
||||
</directories> |
||||
</configuration> |
||||
</plugin> |
||||
</plugins> |
||||
</build> |
||||
</project> |
||||
@ -1 +0,0 @@
@@ -1 +0,0 @@
|
||||
2 |
||||
@ -1 +0,0 @@
@@ -1 +0,0 @@
|
||||
1 |
||||
@ -1,45 +0,0 @@
@@ -1,45 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.test; |
||||
|
||||
import java.io.InputStream; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.Scanner; |
||||
|
||||
public class SampleApplication { |
||||
|
||||
public static void main(String[] args) { |
||||
if (!readContent("one.txt").contains("1")) { |
||||
throw new IllegalArgumentException("Invalid content for one.txt"); |
||||
} |
||||
if (!readContent("another/two.txt").contains("2")) { |
||||
throw new IllegalArgumentException("Invalid content for another/two.txt"); |
||||
} |
||||
System.out.println("I haz been run"); |
||||
} |
||||
|
||||
private static String readContent(String location) { |
||||
InputStream in = SampleApplication.class.getClassLoader().getResourceAsStream(location); |
||||
if (in == null) { |
||||
throw new IllegalArgumentException("Not found: '" + location + "'"); |
||||
} |
||||
try (Scanner scanner = new Scanner(in, StandardCharsets.UTF_8)) { |
||||
return scanner.useDelimiter("\\A").next(); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,123 +0,0 @@
@@ -1,123 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.context.config; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.beans.BeanUtils; |
||||
import org.springframework.context.ApplicationContextException; |
||||
import org.springframework.context.ApplicationContextInitializer; |
||||
import org.springframework.context.ConfigurableApplicationContext; |
||||
import org.springframework.core.GenericTypeResolver; |
||||
import org.springframework.core.Ordered; |
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator; |
||||
import org.springframework.core.env.ConfigurableEnvironment; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.ClassUtils; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* {@link ApplicationContextInitializer} that delegates to other initializers that are |
||||
* specified under a {@literal context.initializer.classes} environment property. |
||||
* |
||||
* @author Dave Syer |
||||
* @author Phillip Webb |
||||
* @since 1.0.0 |
||||
* @deprecated since 3.2.0 for removal in 3.4.0 as property based initialization is no |
||||
* longer recommended |
||||
*/ |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
public class DelegatingApplicationContextInitializer |
||||
implements ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered { |
||||
|
||||
// NOTE: Similar to org.springframework.web.context.ContextLoader
|
||||
|
||||
private static final String PROPERTY_NAME = "context.initializer.classes"; |
||||
|
||||
private int order = 0; |
||||
|
||||
@Override |
||||
public void initialize(ConfigurableApplicationContext context) { |
||||
ConfigurableEnvironment environment = context.getEnvironment(); |
||||
List<Class<?>> initializerClasses = getInitializerClasses(environment); |
||||
if (!initializerClasses.isEmpty()) { |
||||
applyInitializerClasses(context, initializerClasses); |
||||
} |
||||
} |
||||
|
||||
private List<Class<?>> getInitializerClasses(ConfigurableEnvironment env) { |
||||
String classNames = env.getProperty(PROPERTY_NAME); |
||||
List<Class<?>> classes = new ArrayList<>(); |
||||
if (StringUtils.hasLength(classNames)) { |
||||
for (String className : StringUtils.tokenizeToStringArray(classNames, ",")) { |
||||
classes.add(getInitializerClass(className)); |
||||
} |
||||
} |
||||
return classes; |
||||
} |
||||
|
||||
private Class<?> getInitializerClass(String className) throws LinkageError { |
||||
try { |
||||
Class<?> initializerClass = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader()); |
||||
Assert.isAssignable(ApplicationContextInitializer.class, initializerClass); |
||||
return initializerClass; |
||||
} |
||||
catch (ClassNotFoundException ex) { |
||||
throw new ApplicationContextException("Failed to load context initializer class [" + className + "]", ex); |
||||
} |
||||
} |
||||
|
||||
private void applyInitializerClasses(ConfigurableApplicationContext context, List<Class<?>> initializerClasses) { |
||||
Class<?> contextClass = context.getClass(); |
||||
List<ApplicationContextInitializer<?>> initializers = new ArrayList<>(); |
||||
for (Class<?> initializerClass : initializerClasses) { |
||||
initializers.add(instantiateInitializer(contextClass, initializerClass)); |
||||
} |
||||
applyInitializers(context, initializers); |
||||
} |
||||
|
||||
private ApplicationContextInitializer<?> instantiateInitializer(Class<?> contextClass, Class<?> initializerClass) { |
||||
Class<?> requireContextClass = GenericTypeResolver.resolveTypeArgument(initializerClass, |
||||
ApplicationContextInitializer.class); |
||||
Assert.isAssignable(requireContextClass, contextClass, |
||||
() -> String.format( |
||||
"Could not add context initializer [%s] as its generic parameter [%s] is not assignable " |
||||
+ "from the type of application context used by this context loader [%s]: ", |
||||
initializerClass.getName(), requireContextClass.getName(), contextClass.getName())); |
||||
return (ApplicationContextInitializer<?>) BeanUtils.instantiateClass(initializerClass); |
||||
} |
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" }) |
||||
private void applyInitializers(ConfigurableApplicationContext context, |
||||
List<ApplicationContextInitializer<?>> initializers) { |
||||
initializers.sort(new AnnotationAwareOrderComparator()); |
||||
for (ApplicationContextInitializer initializer : initializers) { |
||||
initializer.initialize(context); |
||||
} |
||||
} |
||||
|
||||
public void setOrder(int order) { |
||||
this.order = order; |
||||
} |
||||
|
||||
@Override |
||||
public int getOrder() { |
||||
return this.order; |
||||
} |
||||
|
||||
} |
||||
@ -1,108 +0,0 @@
@@ -1,108 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.context.config; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.beans.BeanUtils; |
||||
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; |
||||
import org.springframework.context.ApplicationContextException; |
||||
import org.springframework.context.ApplicationEvent; |
||||
import org.springframework.context.ApplicationListener; |
||||
import org.springframework.context.event.SimpleApplicationEventMulticaster; |
||||
import org.springframework.core.Ordered; |
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator; |
||||
import org.springframework.core.env.ConfigurableEnvironment; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.ClassUtils; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* {@link ApplicationListener} that delegates to other listeners that are specified under |
||||
* a {@literal context.listener.classes} environment property. |
||||
* |
||||
* @author Dave Syer |
||||
* @author Phillip Webb |
||||
* @since 1.0.0 |
||||
* @deprecated since 3.2.0 for removal in 3.4.0 as property based initialization is no |
||||
* longer recommended |
||||
*/ |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
public class DelegatingApplicationListener implements ApplicationListener<ApplicationEvent>, Ordered { |
||||
|
||||
// NOTE: Similar to org.springframework.web.context.ContextLoader
|
||||
|
||||
private static final String PROPERTY_NAME = "context.listener.classes"; |
||||
|
||||
private int order = 0; |
||||
|
||||
private SimpleApplicationEventMulticaster multicaster; |
||||
|
||||
@Override |
||||
public void onApplicationEvent(ApplicationEvent event) { |
||||
if (event instanceof ApplicationEnvironmentPreparedEvent preparedEvent) { |
||||
List<ApplicationListener<ApplicationEvent>> delegates = getListeners(preparedEvent.getEnvironment()); |
||||
if (delegates.isEmpty()) { |
||||
return; |
||||
} |
||||
this.multicaster = new SimpleApplicationEventMulticaster(); |
||||
for (ApplicationListener<ApplicationEvent> listener : delegates) { |
||||
this.multicaster.addApplicationListener(listener); |
||||
} |
||||
} |
||||
if (this.multicaster != null) { |
||||
this.multicaster.multicastEvent(event); |
||||
} |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
private List<ApplicationListener<ApplicationEvent>> getListeners(ConfigurableEnvironment environment) { |
||||
if (environment == null) { |
||||
return Collections.emptyList(); |
||||
} |
||||
String classNames = environment.getProperty(PROPERTY_NAME); |
||||
List<ApplicationListener<ApplicationEvent>> listeners = new ArrayList<>(); |
||||
if (StringUtils.hasLength(classNames)) { |
||||
for (String className : StringUtils.commaDelimitedListToSet(classNames)) { |
||||
try { |
||||
Class<?> clazz = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader()); |
||||
Assert.isAssignable(ApplicationListener.class, clazz, |
||||
() -> "class [" + className + "] must implement ApplicationListener"); |
||||
listeners.add((ApplicationListener<ApplicationEvent>) BeanUtils.instantiateClass(clazz)); |
||||
} |
||||
catch (Exception ex) { |
||||
throw new ApplicationContextException("Failed to load context listener class [" + className + "]", |
||||
ex); |
||||
} |
||||
} |
||||
} |
||||
AnnotationAwareOrderComparator.sort(listeners); |
||||
return listeners; |
||||
} |
||||
|
||||
public void setOrder(int order) { |
||||
this.order = order; |
||||
} |
||||
|
||||
@Override |
||||
public int getOrder() { |
||||
return this.order; |
||||
} |
||||
|
||||
} |
||||
@ -1,330 +0,0 @@
@@ -1,330 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.task; |
||||
|
||||
import java.time.Duration; |
||||
import java.util.Arrays; |
||||
import java.util.Collections; |
||||
import java.util.LinkedHashSet; |
||||
import java.util.Set; |
||||
|
||||
import org.springframework.beans.BeanUtils; |
||||
import org.springframework.boot.context.properties.PropertyMapper; |
||||
import org.springframework.core.task.TaskDecorator; |
||||
import org.springframework.core.task.TaskExecutor; |
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.CollectionUtils; |
||||
|
||||
/** |
||||
* Builder that can be used to configure and create a {@link TaskExecutor}. Provides |
||||
* convenience methods to set common {@link ThreadPoolTaskExecutor} settings and register |
||||
* {@link #taskDecorator(TaskDecorator)}). For advanced configuration, consider using |
||||
* {@link TaskExecutorCustomizer}. |
||||
* <p> |
||||
* In a typical auto-configured Spring Boot application this builder is available as a |
||||
* bean and can be injected whenever a {@link TaskExecutor} is needed. |
||||
* |
||||
* @author Stephane Nicoll |
||||
* @author Filip Hrisafov |
||||
* @since 2.1.0 |
||||
* @deprecated since 3.2.0 for removal in 3.4.0 in favor of |
||||
* {@link ThreadPoolTaskExecutorBuilder} |
||||
*/ |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
@SuppressWarnings("removal") |
||||
public class TaskExecutorBuilder { |
||||
|
||||
private final Integer queueCapacity; |
||||
|
||||
private final Integer corePoolSize; |
||||
|
||||
private final Integer maxPoolSize; |
||||
|
||||
private final Boolean allowCoreThreadTimeOut; |
||||
|
||||
private final Duration keepAlive; |
||||
|
||||
private final Boolean awaitTermination; |
||||
|
||||
private final Duration awaitTerminationPeriod; |
||||
|
||||
private final String threadNamePrefix; |
||||
|
||||
private final TaskDecorator taskDecorator; |
||||
|
||||
private final Set<TaskExecutorCustomizer> customizers; |
||||
|
||||
public TaskExecutorBuilder() { |
||||
this.queueCapacity = null; |
||||
this.corePoolSize = null; |
||||
this.maxPoolSize = null; |
||||
this.allowCoreThreadTimeOut = null; |
||||
this.keepAlive = null; |
||||
this.awaitTermination = null; |
||||
this.awaitTerminationPeriod = null; |
||||
this.threadNamePrefix = null; |
||||
this.taskDecorator = null; |
||||
this.customizers = null; |
||||
} |
||||
|
||||
private TaskExecutorBuilder(Integer queueCapacity, Integer corePoolSize, Integer maxPoolSize, |
||||
Boolean allowCoreThreadTimeOut, Duration keepAlive, Boolean awaitTermination, |
||||
Duration awaitTerminationPeriod, String threadNamePrefix, TaskDecorator taskDecorator, |
||||
Set<TaskExecutorCustomizer> customizers) { |
||||
this.queueCapacity = queueCapacity; |
||||
this.corePoolSize = corePoolSize; |
||||
this.maxPoolSize = maxPoolSize; |
||||
this.allowCoreThreadTimeOut = allowCoreThreadTimeOut; |
||||
this.keepAlive = keepAlive; |
||||
this.awaitTermination = awaitTermination; |
||||
this.awaitTerminationPeriod = awaitTerminationPeriod; |
||||
this.threadNamePrefix = threadNamePrefix; |
||||
this.taskDecorator = taskDecorator; |
||||
this.customizers = customizers; |
||||
} |
||||
|
||||
/** |
||||
* Set the capacity of the queue. An unbounded capacity does not increase the pool and |
||||
* therefore ignores {@link #maxPoolSize(int) maxPoolSize}. |
||||
* @param queueCapacity the queue capacity to set |
||||
* @return a new builder instance |
||||
*/ |
||||
public TaskExecutorBuilder queueCapacity(int queueCapacity) { |
||||
return new TaskExecutorBuilder(queueCapacity, this.corePoolSize, this.maxPoolSize, this.allowCoreThreadTimeOut, |
||||
this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, this.threadNamePrefix, |
||||
this.taskDecorator, this.customizers); |
||||
} |
||||
|
||||
/** |
||||
* Set the core number of threads. Effectively that maximum number of threads as long |
||||
* as the queue is not full. |
||||
* <p> |
||||
* Core threads can grow and shrink if {@link #allowCoreThreadTimeOut(boolean)} is |
||||
* enabled. |
||||
* @param corePoolSize the core pool size to set |
||||
* @return a new builder instance |
||||
*/ |
||||
public TaskExecutorBuilder corePoolSize(int corePoolSize) { |
||||
return new TaskExecutorBuilder(this.queueCapacity, corePoolSize, this.maxPoolSize, this.allowCoreThreadTimeOut, |
||||
this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, this.threadNamePrefix, |
||||
this.taskDecorator, this.customizers); |
||||
} |
||||
|
||||
/** |
||||
* Set the maximum allowed number of threads. When the {@link #queueCapacity(int) |
||||
* queue} is full, the pool can expand up to that size to accommodate the load. |
||||
* <p> |
||||
* If the {@link #queueCapacity(int) queue capacity} is unbounded, this setting is |
||||
* ignored. |
||||
* @param maxPoolSize the max pool size to set |
||||
* @return a new builder instance |
||||
*/ |
||||
public TaskExecutorBuilder maxPoolSize(int maxPoolSize) { |
||||
return new TaskExecutorBuilder(this.queueCapacity, this.corePoolSize, maxPoolSize, this.allowCoreThreadTimeOut, |
||||
this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, this.threadNamePrefix, |
||||
this.taskDecorator, this.customizers); |
||||
} |
||||
|
||||
/** |
||||
* Set whether core threads are allowed to time out. When enabled, this enables |
||||
* dynamic growing and shrinking of the pool. |
||||
* @param allowCoreThreadTimeOut if core threads are allowed to time out |
||||
* @return a new builder instance |
||||
*/ |
||||
public TaskExecutorBuilder allowCoreThreadTimeOut(boolean allowCoreThreadTimeOut) { |
||||
return new TaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, allowCoreThreadTimeOut, |
||||
this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, this.threadNamePrefix, |
||||
this.taskDecorator, this.customizers); |
||||
} |
||||
|
||||
/** |
||||
* Set the time limit for which threads may remain idle before being terminated. |
||||
* @param keepAlive the keep alive to set |
||||
* @return a new builder instance |
||||
*/ |
||||
public TaskExecutorBuilder keepAlive(Duration keepAlive) { |
||||
return new TaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, |
||||
this.allowCoreThreadTimeOut, keepAlive, this.awaitTermination, this.awaitTerminationPeriod, |
||||
this.threadNamePrefix, this.taskDecorator, this.customizers); |
||||
} |
||||
|
||||
/** |
||||
* Set whether the executor should wait for scheduled tasks to complete on shutdown, |
||||
* not interrupting running tasks and executing all tasks in the queue. |
||||
* @param awaitTermination whether the executor needs to wait for the tasks to |
||||
* complete on shutdown |
||||
* @return a new builder instance |
||||
* @see #awaitTerminationPeriod(Duration) |
||||
*/ |
||||
public TaskExecutorBuilder awaitTermination(boolean awaitTermination) { |
||||
return new TaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, |
||||
this.allowCoreThreadTimeOut, this.keepAlive, awaitTermination, this.awaitTerminationPeriod, |
||||
this.threadNamePrefix, this.taskDecorator, this.customizers); |
||||
} |
||||
|
||||
/** |
||||
* Set the maximum time the executor is supposed to block on shutdown. When set, the |
||||
* executor blocks on shutdown in order to wait for remaining tasks to complete their |
||||
* execution before the rest of the container continues to shut down. This is |
||||
* particularly useful if your remaining tasks are likely to need access to other |
||||
* resources that are also managed by the container. |
||||
* @param awaitTerminationPeriod the await termination period to set |
||||
* @return a new builder instance |
||||
*/ |
||||
public TaskExecutorBuilder awaitTerminationPeriod(Duration awaitTerminationPeriod) { |
||||
return new TaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, |
||||
this.allowCoreThreadTimeOut, this.keepAlive, this.awaitTermination, awaitTerminationPeriod, |
||||
this.threadNamePrefix, this.taskDecorator, this.customizers); |
||||
} |
||||
|
||||
/** |
||||
* Set the prefix to use for the names of newly created threads. |
||||
* @param threadNamePrefix the thread name prefix to set |
||||
* @return a new builder instance |
||||
*/ |
||||
public TaskExecutorBuilder threadNamePrefix(String threadNamePrefix) { |
||||
return new TaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, |
||||
this.allowCoreThreadTimeOut, this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, |
||||
threadNamePrefix, this.taskDecorator, this.customizers); |
||||
} |
||||
|
||||
/** |
||||
* Set the {@link TaskDecorator} to use or {@code null} to not use any. |
||||
* @param taskDecorator the task decorator to use |
||||
* @return a new builder instance |
||||
*/ |
||||
public TaskExecutorBuilder taskDecorator(TaskDecorator taskDecorator) { |
||||
return new TaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, |
||||
this.allowCoreThreadTimeOut, this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, |
||||
this.threadNamePrefix, taskDecorator, this.customizers); |
||||
} |
||||
|
||||
/** |
||||
* Set the {@link TaskExecutorCustomizer TaskExecutorCustomizers} that should be |
||||
* applied to the {@link ThreadPoolTaskExecutor}. Customizers are applied in the order |
||||
* that they were added after builder configuration has been applied. Setting this |
||||
* value will replace any previously configured customizers. |
||||
* @param customizers the customizers to set |
||||
* @return a new builder instance |
||||
* @see #additionalCustomizers(TaskExecutorCustomizer...) |
||||
*/ |
||||
public TaskExecutorBuilder customizers(TaskExecutorCustomizer... customizers) { |
||||
Assert.notNull(customizers, "Customizers must not be null"); |
||||
return customizers(Arrays.asList(customizers)); |
||||
} |
||||
|
||||
/** |
||||
* Set the {@link TaskExecutorCustomizer TaskExecutorCustomizers} that should be |
||||
* applied to the {@link ThreadPoolTaskExecutor}. Customizers are applied in the order |
||||
* that they were added after builder configuration has been applied. Setting this |
||||
* value will replace any previously configured customizers. |
||||
* @param customizers the customizers to set |
||||
* @return a new builder instance |
||||
* @see #additionalCustomizers(TaskExecutorCustomizer...) |
||||
*/ |
||||
public TaskExecutorBuilder customizers(Iterable<TaskExecutorCustomizer> customizers) { |
||||
Assert.notNull(customizers, "Customizers must not be null"); |
||||
return new TaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, |
||||
this.allowCoreThreadTimeOut, this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, |
||||
this.threadNamePrefix, this.taskDecorator, append(null, customizers)); |
||||
} |
||||
|
||||
/** |
||||
* Add {@link TaskExecutorCustomizer TaskExecutorCustomizers} that should be applied |
||||
* to the {@link ThreadPoolTaskExecutor}. Customizers are applied in the order that |
||||
* they were added after builder configuration has been applied. |
||||
* @param customizers the customizers to add |
||||
* @return a new builder instance |
||||
* @see #customizers(TaskExecutorCustomizer...) |
||||
*/ |
||||
public TaskExecutorBuilder additionalCustomizers(TaskExecutorCustomizer... customizers) { |
||||
Assert.notNull(customizers, "Customizers must not be null"); |
||||
return additionalCustomizers(Arrays.asList(customizers)); |
||||
} |
||||
|
||||
/** |
||||
* Add {@link TaskExecutorCustomizer TaskExecutorCustomizers} that should be applied |
||||
* to the {@link ThreadPoolTaskExecutor}. Customizers are applied in the order that |
||||
* they were added after builder configuration has been applied. |
||||
* @param customizers the customizers to add |
||||
* @return a new builder instance |
||||
* @see #customizers(TaskExecutorCustomizer...) |
||||
*/ |
||||
public TaskExecutorBuilder additionalCustomizers(Iterable<TaskExecutorCustomizer> customizers) { |
||||
Assert.notNull(customizers, "Customizers must not be null"); |
||||
return new TaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, |
||||
this.allowCoreThreadTimeOut, this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, |
||||
this.threadNamePrefix, this.taskDecorator, append(this.customizers, customizers)); |
||||
} |
||||
|
||||
/** |
||||
* Build a new {@link ThreadPoolTaskExecutor} instance and configure it using this |
||||
* builder. |
||||
* @return a configured {@link ThreadPoolTaskExecutor} instance. |
||||
* @see #build(Class) |
||||
* @see #configure(ThreadPoolTaskExecutor) |
||||
*/ |
||||
public ThreadPoolTaskExecutor build() { |
||||
return configure(new ThreadPoolTaskExecutor()); |
||||
} |
||||
|
||||
/** |
||||
* Build a new {@link ThreadPoolTaskExecutor} instance of the specified type and |
||||
* configure it using this builder. |
||||
* @param <T> the type of task executor |
||||
* @param taskExecutorClass the template type to create |
||||
* @return a configured {@link ThreadPoolTaskExecutor} instance. |
||||
* @see #build() |
||||
* @see #configure(ThreadPoolTaskExecutor) |
||||
*/ |
||||
public <T extends ThreadPoolTaskExecutor> T build(Class<T> taskExecutorClass) { |
||||
return configure(BeanUtils.instantiateClass(taskExecutorClass)); |
||||
} |
||||
|
||||
/** |
||||
* Configure the provided {@link ThreadPoolTaskExecutor} instance using this builder. |
||||
* @param <T> the type of task executor |
||||
* @param taskExecutor the {@link ThreadPoolTaskExecutor} to configure |
||||
* @return the task executor instance |
||||
* @see #build() |
||||
* @see #build(Class) |
||||
*/ |
||||
public <T extends ThreadPoolTaskExecutor> T configure(T taskExecutor) { |
||||
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); |
||||
map.from(this.queueCapacity).to(taskExecutor::setQueueCapacity); |
||||
map.from(this.corePoolSize).to(taskExecutor::setCorePoolSize); |
||||
map.from(this.maxPoolSize).to(taskExecutor::setMaxPoolSize); |
||||
map.from(this.keepAlive).asInt(Duration::getSeconds).to(taskExecutor::setKeepAliveSeconds); |
||||
map.from(this.allowCoreThreadTimeOut).to(taskExecutor::setAllowCoreThreadTimeOut); |
||||
map.from(this.awaitTermination).to(taskExecutor::setWaitForTasksToCompleteOnShutdown); |
||||
map.from(this.awaitTerminationPeriod).as(Duration::toMillis).to(taskExecutor::setAwaitTerminationMillis); |
||||
map.from(this.threadNamePrefix).whenHasText().to(taskExecutor::setThreadNamePrefix); |
||||
map.from(this.taskDecorator).to(taskExecutor::setTaskDecorator); |
||||
if (!CollectionUtils.isEmpty(this.customizers)) { |
||||
this.customizers.forEach((customizer) -> customizer.customize(taskExecutor)); |
||||
} |
||||
return taskExecutor; |
||||
} |
||||
|
||||
private <T> Set<T> append(Set<T> set, Iterable<? extends T> additions) { |
||||
Set<T> result = new LinkedHashSet<>((set != null) ? set : Collections.emptySet()); |
||||
additions.forEach(result::add); |
||||
return Collections.unmodifiableSet(result); |
||||
} |
||||
|
||||
} |
||||
@ -1,40 +0,0 @@
@@ -1,40 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.task; |
||||
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
||||
|
||||
/** |
||||
* Callback interface that can be used to customize a {@link ThreadPoolTaskExecutor}. |
||||
* |
||||
* @author Stephane Nicoll |
||||
* @since 2.1.0 |
||||
* @see TaskExecutorBuilder |
||||
* @deprecated since 3.2.0 for removal in 3.4.0 in favor of |
||||
* {@link ThreadPoolTaskExecutorCustomizer} |
||||
*/ |
||||
@FunctionalInterface |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
public interface TaskExecutorCustomizer { |
||||
|
||||
/** |
||||
* Callback to customize a {@link ThreadPoolTaskExecutor} instance. |
||||
* @param taskExecutor the task executor to customize |
||||
*/ |
||||
void customize(ThreadPoolTaskExecutor taskExecutor); |
||||
|
||||
} |
||||
@ -1,213 +0,0 @@
@@ -1,213 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.task; |
||||
|
||||
import java.time.Duration; |
||||
import java.util.Arrays; |
||||
import java.util.Collections; |
||||
import java.util.LinkedHashSet; |
||||
import java.util.Set; |
||||
|
||||
import org.springframework.boot.context.properties.PropertyMapper; |
||||
import org.springframework.scheduling.TaskScheduler; |
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.CollectionUtils; |
||||
|
||||
/** |
||||
* Builder that can be used to configure and create a {@link TaskScheduler}. Provides |
||||
* convenience methods to set common {@link ThreadPoolTaskScheduler} settings. For |
||||
* advanced configuration, consider using {@link TaskSchedulerCustomizer}. |
||||
* <p> |
||||
* In a typical auto-configured Spring Boot application this builder is available as a |
||||
* bean and can be injected whenever a {@link TaskScheduler} is needed. |
||||
* |
||||
* @author Stephane Nicoll |
||||
* @since 2.1.0 |
||||
* @deprecated since 3.2.0 for removal in 3.4.0 in favor of |
||||
* {@link ThreadPoolTaskSchedulerBuilder} |
||||
*/ |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
@SuppressWarnings("removal") |
||||
public class TaskSchedulerBuilder { |
||||
|
||||
private final Integer poolSize; |
||||
|
||||
private final Boolean awaitTermination; |
||||
|
||||
private final Duration awaitTerminationPeriod; |
||||
|
||||
private final String threadNamePrefix; |
||||
|
||||
private final Set<TaskSchedulerCustomizer> customizers; |
||||
|
||||
public TaskSchedulerBuilder() { |
||||
this.poolSize = null; |
||||
this.awaitTermination = null; |
||||
this.awaitTerminationPeriod = null; |
||||
this.threadNamePrefix = null; |
||||
this.customizers = null; |
||||
} |
||||
|
||||
public TaskSchedulerBuilder(Integer poolSize, Boolean awaitTermination, Duration awaitTerminationPeriod, |
||||
String threadNamePrefix, Set<TaskSchedulerCustomizer> taskSchedulerCustomizers) { |
||||
this.poolSize = poolSize; |
||||
this.awaitTermination = awaitTermination; |
||||
this.awaitTerminationPeriod = awaitTerminationPeriod; |
||||
this.threadNamePrefix = threadNamePrefix; |
||||
this.customizers = taskSchedulerCustomizers; |
||||
} |
||||
|
||||
/** |
||||
* Set the maximum allowed number of threads. |
||||
* @param poolSize the pool size to set |
||||
* @return a new builder instance |
||||
*/ |
||||
public TaskSchedulerBuilder poolSize(int poolSize) { |
||||
return new TaskSchedulerBuilder(poolSize, this.awaitTermination, this.awaitTerminationPeriod, |
||||
this.threadNamePrefix, this.customizers); |
||||
} |
||||
|
||||
/** |
||||
* Set whether the executor should wait for scheduled tasks to complete on shutdown, |
||||
* not interrupting running tasks and executing all tasks in the queue. |
||||
* @param awaitTermination whether the executor needs to wait for the tasks to |
||||
* complete on shutdown |
||||
* @return a new builder instance |
||||
* @see #awaitTerminationPeriod(Duration) |
||||
*/ |
||||
public TaskSchedulerBuilder awaitTermination(boolean awaitTermination) { |
||||
return new TaskSchedulerBuilder(this.poolSize, awaitTermination, this.awaitTerminationPeriod, |
||||
this.threadNamePrefix, this.customizers); |
||||
} |
||||
|
||||
/** |
||||
* Set the maximum time the executor is supposed to block on shutdown. When set, the |
||||
* executor blocks on shutdown in order to wait for remaining tasks to complete their |
||||
* execution before the rest of the container continues to shut down. This is |
||||
* particularly useful if your remaining tasks are likely to need access to other |
||||
* resources that are also managed by the container. |
||||
* @param awaitTerminationPeriod the await termination period to set |
||||
* @return a new builder instance |
||||
*/ |
||||
public TaskSchedulerBuilder awaitTerminationPeriod(Duration awaitTerminationPeriod) { |
||||
return new TaskSchedulerBuilder(this.poolSize, this.awaitTermination, awaitTerminationPeriod, |
||||
this.threadNamePrefix, this.customizers); |
||||
} |
||||
|
||||
/** |
||||
* Set the prefix to use for the names of newly created threads. |
||||
* @param threadNamePrefix the thread name prefix to set |
||||
* @return a new builder instance |
||||
*/ |
||||
public TaskSchedulerBuilder threadNamePrefix(String threadNamePrefix) { |
||||
return new TaskSchedulerBuilder(this.poolSize, this.awaitTermination, this.awaitTerminationPeriod, |
||||
threadNamePrefix, this.customizers); |
||||
} |
||||
|
||||
/** |
||||
* Set the {@link TaskSchedulerCustomizer TaskSchedulerCustomizers} that should be |
||||
* applied to the {@link ThreadPoolTaskScheduler}. Customizers are applied in the |
||||
* order that they were added after builder configuration has been applied. Setting |
||||
* this value will replace any previously configured customizers. |
||||
* @param customizers the customizers to set |
||||
* @return a new builder instance |
||||
* @see #additionalCustomizers(TaskSchedulerCustomizer...) |
||||
*/ |
||||
public TaskSchedulerBuilder customizers(TaskSchedulerCustomizer... customizers) { |
||||
Assert.notNull(customizers, "Customizers must not be null"); |
||||
return customizers(Arrays.asList(customizers)); |
||||
} |
||||
|
||||
/** |
||||
* Set the {@link TaskSchedulerCustomizer taskSchedulerCustomizers} that should be |
||||
* applied to the {@link ThreadPoolTaskScheduler}. Customizers are applied in the |
||||
* order that they were added after builder configuration has been applied. Setting |
||||
* this value will replace any previously configured customizers. |
||||
* @param customizers the customizers to set |
||||
* @return a new builder instance |
||||
* @see #additionalCustomizers(TaskSchedulerCustomizer...) |
||||
*/ |
||||
public TaskSchedulerBuilder customizers(Iterable<TaskSchedulerCustomizer> customizers) { |
||||
Assert.notNull(customizers, "Customizers must not be null"); |
||||
return new TaskSchedulerBuilder(this.poolSize, this.awaitTermination, this.awaitTerminationPeriod, |
||||
this.threadNamePrefix, append(null, customizers)); |
||||
} |
||||
|
||||
/** |
||||
* Add {@link TaskSchedulerCustomizer taskSchedulerCustomizers} that should be applied |
||||
* to the {@link ThreadPoolTaskScheduler}. Customizers are applied in the order that |
||||
* they were added after builder configuration has been applied. |
||||
* @param customizers the customizers to add |
||||
* @return a new builder instance |
||||
* @see #customizers(TaskSchedulerCustomizer...) |
||||
*/ |
||||
public TaskSchedulerBuilder additionalCustomizers(TaskSchedulerCustomizer... customizers) { |
||||
Assert.notNull(customizers, "Customizers must not be null"); |
||||
return additionalCustomizers(Arrays.asList(customizers)); |
||||
} |
||||
|
||||
/** |
||||
* Add {@link TaskSchedulerCustomizer taskSchedulerCustomizers} that should be applied |
||||
* to the {@link ThreadPoolTaskScheduler}. Customizers are applied in the order that |
||||
* they were added after builder configuration has been applied. |
||||
* @param customizers the customizers to add |
||||
* @return a new builder instance |
||||
* @see #customizers(TaskSchedulerCustomizer...) |
||||
*/ |
||||
public TaskSchedulerBuilder additionalCustomizers(Iterable<TaskSchedulerCustomizer> customizers) { |
||||
Assert.notNull(customizers, "Customizers must not be null"); |
||||
return new TaskSchedulerBuilder(this.poolSize, this.awaitTermination, this.awaitTerminationPeriod, |
||||
this.threadNamePrefix, append(this.customizers, customizers)); |
||||
} |
||||
|
||||
/** |
||||
* Build a new {@link ThreadPoolTaskScheduler} instance and configure it using this |
||||
* builder. |
||||
* @return a configured {@link ThreadPoolTaskScheduler} instance. |
||||
* @see #configure(ThreadPoolTaskScheduler) |
||||
*/ |
||||
public ThreadPoolTaskScheduler build() { |
||||
return configure(new ThreadPoolTaskScheduler()); |
||||
} |
||||
|
||||
/** |
||||
* Configure the provided {@link ThreadPoolTaskScheduler} instance using this builder. |
||||
* @param <T> the type of task scheduler |
||||
* @param taskScheduler the {@link ThreadPoolTaskScheduler} to configure |
||||
* @return the task scheduler instance |
||||
* @see #build() |
||||
*/ |
||||
public <T extends ThreadPoolTaskScheduler> T configure(T taskScheduler) { |
||||
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); |
||||
map.from(this.poolSize).to(taskScheduler::setPoolSize); |
||||
map.from(this.awaitTermination).to(taskScheduler::setWaitForTasksToCompleteOnShutdown); |
||||
map.from(this.awaitTerminationPeriod).asInt(Duration::getSeconds).to(taskScheduler::setAwaitTerminationSeconds); |
||||
map.from(this.threadNamePrefix).to(taskScheduler::setThreadNamePrefix); |
||||
if (!CollectionUtils.isEmpty(this.customizers)) { |
||||
this.customizers.forEach((customizer) -> customizer.customize(taskScheduler)); |
||||
} |
||||
return taskScheduler; |
||||
} |
||||
|
||||
private <T> Set<T> append(Set<T> set, Iterable<? extends T> additions) { |
||||
Set<T> result = new LinkedHashSet<>((set != null) ? set : Collections.emptySet()); |
||||
additions.forEach(result::add); |
||||
return Collections.unmodifiableSet(result); |
||||
} |
||||
|
||||
} |
||||
@ -1,39 +0,0 @@
@@ -1,39 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.task; |
||||
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; |
||||
|
||||
/** |
||||
* Callback interface that can be used to customize a {@link ThreadPoolTaskScheduler}. |
||||
* |
||||
* @author Stephane Nicoll |
||||
* @since 2.1.0 |
||||
* @deprecated since 3.2.0 for removal in 3.4.0 in favor of |
||||
* {@link ThreadPoolTaskSchedulerCustomizer} |
||||
*/ |
||||
@FunctionalInterface |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
public interface TaskSchedulerCustomizer { |
||||
|
||||
/** |
||||
* Callback to customize a {@link ThreadPoolTaskScheduler} instance. |
||||
* @param taskScheduler the task scheduler to customize |
||||
*/ |
||||
void customize(ThreadPoolTaskScheduler taskScheduler); |
||||
|
||||
} |
||||
@ -1,123 +0,0 @@
@@ -1,123 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.context.config; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.context.ApplicationContextException; |
||||
import org.springframework.context.ApplicationContextInitializer; |
||||
import org.springframework.context.ConfigurableApplicationContext; |
||||
import org.springframework.context.support.StaticApplicationContext; |
||||
import org.springframework.core.Ordered; |
||||
import org.springframework.core.annotation.Order; |
||||
import org.springframework.test.context.support.TestPropertySourceUtils; |
||||
import org.springframework.web.context.ConfigurableWebApplicationContext; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; |
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; |
||||
|
||||
/** |
||||
* Tests for {@link DelegatingApplicationContextInitializer}. |
||||
* |
||||
* @author Phillip Webb |
||||
*/ |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
@SuppressWarnings("removal") |
||||
class DelegatingApplicationContextInitializerTests { |
||||
|
||||
private final DelegatingApplicationContextInitializer initializer = new DelegatingApplicationContextInitializer(); |
||||
|
||||
@Test |
||||
void orderedInitialize() { |
||||
StaticApplicationContext context = new StaticApplicationContext(); |
||||
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(context, |
||||
"context.initializer.classes=" + MockInitB.class.getName() + "," + MockInitA.class.getName()); |
||||
this.initializer.initialize(context); |
||||
assertThat(context.getBeanFactory().getSingleton("a")).isEqualTo("a"); |
||||
assertThat(context.getBeanFactory().getSingleton("b")).isEqualTo("b"); |
||||
} |
||||
|
||||
@Test |
||||
void noInitializers() { |
||||
StaticApplicationContext context = new StaticApplicationContext(); |
||||
this.initializer.initialize(context); |
||||
} |
||||
|
||||
@Test |
||||
void emptyInitializers() { |
||||
StaticApplicationContext context = new StaticApplicationContext(); |
||||
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(context, "context.initializer.classes:"); |
||||
this.initializer.initialize(context); |
||||
} |
||||
|
||||
@Test |
||||
void noSuchInitializerClass() { |
||||
StaticApplicationContext context = new StaticApplicationContext(); |
||||
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(context, |
||||
"context.initializer.classes=missing.madeup.class"); |
||||
assertThatExceptionOfType(ApplicationContextException.class) |
||||
.isThrownBy(() -> this.initializer.initialize(context)); |
||||
} |
||||
|
||||
@Test |
||||
void notAnInitializerClass() { |
||||
StaticApplicationContext context = new StaticApplicationContext(); |
||||
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(context, |
||||
"context.initializer.classes=" + Object.class.getName()); |
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.initializer.initialize(context)); |
||||
} |
||||
|
||||
@Test |
||||
void genericNotSuitable() { |
||||
StaticApplicationContext context = new StaticApplicationContext(); |
||||
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(context, |
||||
"context.initializer.classes=" + NotSuitableInit.class.getName()); |
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.initializer.initialize(context)) |
||||
.withMessageContaining("generic parameter"); |
||||
} |
||||
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE) |
||||
static class MockInitA implements ApplicationContextInitializer<ConfigurableApplicationContext> { |
||||
|
||||
@Override |
||||
public void initialize(ConfigurableApplicationContext applicationContext) { |
||||
applicationContext.getBeanFactory().registerSingleton("a", "a"); |
||||
} |
||||
|
||||
} |
||||
|
||||
@Order(Ordered.LOWEST_PRECEDENCE) |
||||
static class MockInitB implements ApplicationContextInitializer<ConfigurableApplicationContext> { |
||||
|
||||
@Override |
||||
public void initialize(ConfigurableApplicationContext applicationContext) { |
||||
assertThat(applicationContext.getBeanFactory().getSingleton("a")).isEqualTo("a"); |
||||
applicationContext.getBeanFactory().registerSingleton("b", "b"); |
||||
} |
||||
|
||||
} |
||||
|
||||
static class NotSuitableInit implements ApplicationContextInitializer<ConfigurableWebApplicationContext> { |
||||
|
||||
@Override |
||||
public void initialize(ConfigurableWebApplicationContext applicationContext) { |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -1,105 +0,0 @@
@@ -1,105 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.context.config; |
||||
|
||||
import org.junit.jupiter.api.AfterEach; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.boot.DefaultBootstrapContext; |
||||
import org.springframework.boot.SpringApplication; |
||||
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; |
||||
import org.springframework.context.ApplicationListener; |
||||
import org.springframework.context.ConfigurableApplicationContext; |
||||
import org.springframework.context.event.ContextRefreshedEvent; |
||||
import org.springframework.context.support.StaticApplicationContext; |
||||
import org.springframework.core.Ordered; |
||||
import org.springframework.core.annotation.Order; |
||||
import org.springframework.test.context.support.TestPropertySourceUtils; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link DelegatingApplicationListener}. |
||||
* |
||||
* @author Dave Syer |
||||
*/ |
||||
@Deprecated(since = "3.2.0", forRemoval = true) |
||||
@SuppressWarnings("removal") |
||||
class DelegatingApplicationListenerTests { |
||||
|
||||
private final DelegatingApplicationListener listener = new DelegatingApplicationListener(); |
||||
|
||||
private final StaticApplicationContext context = new StaticApplicationContext(); |
||||
|
||||
@AfterEach |
||||
void close() { |
||||
if (this.context != null) { |
||||
this.context.close(); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
void orderedInitialize() { |
||||
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.context, |
||||
"context.listener.classes=" + MockInitB.class.getName() + "," + MockInitA.class.getName()); |
||||
this.listener.onApplicationEvent(new ApplicationEnvironmentPreparedEvent(new DefaultBootstrapContext(), |
||||
new SpringApplication(), new String[0], this.context.getEnvironment())); |
||||
this.context.getBeanFactory().registerSingleton("testListener", this.listener); |
||||
this.context.refresh(); |
||||
assertThat(this.context.getBeanFactory().getSingleton("a")).isEqualTo("a"); |
||||
assertThat(this.context.getBeanFactory().getSingleton("b")).isEqualTo("b"); |
||||
} |
||||
|
||||
@Test |
||||
void noInitializers() { |
||||
this.listener.onApplicationEvent(new ApplicationEnvironmentPreparedEvent(new DefaultBootstrapContext(), |
||||
new SpringApplication(), new String[0], this.context.getEnvironment())); |
||||
} |
||||
|
||||
@Test |
||||
void emptyInitializers() { |
||||
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.context, "context.listener.classes:"); |
||||
this.listener.onApplicationEvent(new ApplicationEnvironmentPreparedEvent(new DefaultBootstrapContext(), |
||||
new SpringApplication(), new String[0], this.context.getEnvironment())); |
||||
} |
||||
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE) |
||||
static class MockInitA implements ApplicationListener<ContextRefreshedEvent> { |
||||
|
||||
@Override |
||||
public void onApplicationEvent(ContextRefreshedEvent event) { |
||||
ConfigurableApplicationContext applicationContext = (ConfigurableApplicationContext) event |
||||
.getApplicationContext(); |
||||
applicationContext.getBeanFactory().registerSingleton("a", "a"); |
||||
} |
||||
|
||||
} |
||||
|
||||
@Order(Ordered.LOWEST_PRECEDENCE) |
||||
static class MockInitB implements ApplicationListener<ContextRefreshedEvent> { |
||||
|
||||
@Override |
||||
public void onApplicationEvent(ContextRefreshedEvent event) { |
||||
ConfigurableApplicationContext applicationContext = (ConfigurableApplicationContext) event |
||||
.getApplicationContext(); |
||||
assertThat(applicationContext.getBeanFactory().getSingleton("a")).isEqualTo("a"); |
||||
applicationContext.getBeanFactory().registerSingleton("b", "b"); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -1,169 +0,0 @@
@@ -1,169 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.task; |
||||
|
||||
import java.time.Duration; |
||||
import java.util.Collections; |
||||
import java.util.Set; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.core.task.TaskDecorator; |
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; |
||||
import static org.mockito.BDDMockito.then; |
||||
import static org.mockito.Mockito.mock; |
||||
import static org.mockito.Mockito.spy; |
||||
|
||||
/** |
||||
* Tests for {@link TaskExecutorBuilder}. |
||||
* |
||||
* @author Stephane Nicoll |
||||
* @author Filip Hrisafov |
||||
*/ |
||||
@SuppressWarnings("removal") |
||||
class TaskExecutorBuilderTests { |
||||
|
||||
private final TaskExecutorBuilder builder = new TaskExecutorBuilder(); |
||||
|
||||
@Test |
||||
void poolSettingsShouldApply() { |
||||
ThreadPoolTaskExecutor executor = this.builder.queueCapacity(10) |
||||
.corePoolSize(4) |
||||
.maxPoolSize(8) |
||||
.allowCoreThreadTimeOut(true) |
||||
.keepAlive(Duration.ofMinutes(1)) |
||||
.build(); |
||||
assertThat(executor).hasFieldOrPropertyWithValue("queueCapacity", 10); |
||||
assertThat(executor.getCorePoolSize()).isEqualTo(4); |
||||
assertThat(executor.getMaxPoolSize()).isEqualTo(8); |
||||
assertThat(executor).hasFieldOrPropertyWithValue("allowCoreThreadTimeOut", true); |
||||
assertThat(executor.getKeepAliveSeconds()).isEqualTo(60); |
||||
} |
||||
|
||||
@Test |
||||
void awaitTerminationShouldApply() { |
||||
ThreadPoolTaskExecutor executor = this.builder.awaitTermination(true).build(); |
||||
assertThat(executor).hasFieldOrPropertyWithValue("waitForTasksToCompleteOnShutdown", true); |
||||
} |
||||
|
||||
@Test |
||||
void awaitTerminationPeriodShouldApplyWithMillisecondPrecision() { |
||||
Duration period = Duration.ofMillis(50); |
||||
ThreadPoolTaskExecutor executor = this.builder.awaitTerminationPeriod(period).build(); |
||||
assertThat(executor).hasFieldOrPropertyWithValue("awaitTerminationMillis", period.toMillis()); |
||||
} |
||||
|
||||
@Test |
||||
void threadNamePrefixShouldApply() { |
||||
ThreadPoolTaskExecutor executor = this.builder.threadNamePrefix("test-").build(); |
||||
assertThat(executor.getThreadNamePrefix()).isEqualTo("test-"); |
||||
} |
||||
|
||||
@Test |
||||
void taskDecoratorShouldApply() { |
||||
TaskDecorator taskDecorator = mock(TaskDecorator.class); |
||||
ThreadPoolTaskExecutor executor = this.builder.taskDecorator(taskDecorator).build(); |
||||
assertThat(executor).extracting("taskDecorator").isSameAs(taskDecorator); |
||||
} |
||||
|
||||
@Test |
||||
void customizersWhenCustomizersAreNullShouldThrowException() { |
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.builder.customizers((TaskExecutorCustomizer[]) null)) |
||||
.withMessageContaining("Customizers must not be null"); |
||||
} |
||||
|
||||
@Test |
||||
void customizersCollectionWhenCustomizersAreNullShouldThrowException() { |
||||
assertThatIllegalArgumentException() |
||||
.isThrownBy(() -> this.builder.customizers((Set<TaskExecutorCustomizer>) null)) |
||||
.withMessageContaining("Customizers must not be null"); |
||||
} |
||||
|
||||
@Test |
||||
void customizersShouldApply() { |
||||
TaskExecutorCustomizer customizer = mock(TaskExecutorCustomizer.class); |
||||
ThreadPoolTaskExecutor executor = this.builder.customizers(customizer).build(); |
||||
then(customizer).should().customize(executor); |
||||
} |
||||
|
||||
@Test |
||||
void customizersShouldBeAppliedLast() { |
||||
TaskDecorator taskDecorator = mock(TaskDecorator.class); |
||||
ThreadPoolTaskExecutor executor = spy(new ThreadPoolTaskExecutor()); |
||||
this.builder.queueCapacity(10) |
||||
.corePoolSize(4) |
||||
.maxPoolSize(8) |
||||
.allowCoreThreadTimeOut(true) |
||||
.keepAlive(Duration.ofMinutes(1)) |
||||
.awaitTermination(true) |
||||
.awaitTerminationPeriod(Duration.ofSeconds(30)) |
||||
.threadNamePrefix("test-") |
||||
.taskDecorator(taskDecorator) |
||||
.additionalCustomizers((taskExecutor) -> { |
||||
then(taskExecutor).should().setQueueCapacity(10); |
||||
then(taskExecutor).should().setCorePoolSize(4); |
||||
then(taskExecutor).should().setMaxPoolSize(8); |
||||
then(taskExecutor).should().setAllowCoreThreadTimeOut(true); |
||||
then(taskExecutor).should().setKeepAliveSeconds(60); |
||||
then(taskExecutor).should().setWaitForTasksToCompleteOnShutdown(true); |
||||
then(taskExecutor).should().setAwaitTerminationSeconds(30); |
||||
then(taskExecutor).should().setThreadNamePrefix("test-"); |
||||
then(taskExecutor).should().setTaskDecorator(taskDecorator); |
||||
}); |
||||
this.builder.configure(executor); |
||||
} |
||||
|
||||
@Test |
||||
void customizersShouldReplaceExisting() { |
||||
TaskExecutorCustomizer customizer1 = mock(TaskExecutorCustomizer.class); |
||||
TaskExecutorCustomizer customizer2 = mock(TaskExecutorCustomizer.class); |
||||
ThreadPoolTaskExecutor executor = this.builder.customizers(customizer1) |
||||
.customizers(Collections.singleton(customizer2)) |
||||
.build(); |
||||
then(customizer1).shouldHaveNoInteractions(); |
||||
then(customizer2).should().customize(executor); |
||||
} |
||||
|
||||
@Test |
||||
void additionalCustomizersWhenCustomizersAreNullShouldThrowException() { |
||||
assertThatIllegalArgumentException() |
||||
.isThrownBy(() -> this.builder.additionalCustomizers((TaskExecutorCustomizer[]) null)) |
||||
.withMessageContaining("Customizers must not be null"); |
||||
} |
||||
|
||||
@Test |
||||
void additionalCustomizersCollectionWhenCustomizersAreNullShouldThrowException() { |
||||
assertThatIllegalArgumentException() |
||||
.isThrownBy(() -> this.builder.additionalCustomizers((Set<TaskExecutorCustomizer>) null)) |
||||
.withMessageContaining("Customizers must not be null"); |
||||
} |
||||
|
||||
@Test |
||||
void additionalCustomizersShouldAddToExisting() { |
||||
TaskExecutorCustomizer customizer1 = mock(TaskExecutorCustomizer.class); |
||||
TaskExecutorCustomizer customizer2 = mock(TaskExecutorCustomizer.class); |
||||
ThreadPoolTaskExecutor executor = this.builder.customizers(customizer1) |
||||
.additionalCustomizers(customizer2) |
||||
.build(); |
||||
then(customizer1).should().customize(executor); |
||||
then(customizer2).should().customize(executor); |
||||
} |
||||
|
||||
} |
||||
@ -1,135 +0,0 @@
@@ -1,135 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2023 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.task; |
||||
|
||||
import java.time.Duration; |
||||
import java.util.Collections; |
||||
import java.util.Set; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; |
||||
import static org.mockito.BDDMockito.then; |
||||
import static org.mockito.Mockito.mock; |
||||
import static org.mockito.Mockito.spy; |
||||
|
||||
/** |
||||
* Tests for {@link TaskSchedulerBuilder}. |
||||
* |
||||
* @author Stephane Nicoll |
||||
*/ |
||||
@SuppressWarnings("removal") |
||||
class TaskSchedulerBuilderTests { |
||||
|
||||
private final TaskSchedulerBuilder builder = new TaskSchedulerBuilder(); |
||||
|
||||
@Test |
||||
void poolSettingsShouldApply() { |
||||
ThreadPoolTaskScheduler scheduler = this.builder.poolSize(4).build(); |
||||
assertThat(scheduler.getPoolSize()).isEqualTo(4); |
||||
} |
||||
|
||||
@Test |
||||
void awaitTerminationShouldApply() { |
||||
ThreadPoolTaskScheduler executor = this.builder.awaitTermination(true).build(); |
||||
assertThat(executor).hasFieldOrPropertyWithValue("waitForTasksToCompleteOnShutdown", true); |
||||
} |
||||
|
||||
@Test |
||||
void awaitTerminationPeriodShouldApply() { |
||||
Duration period = Duration.ofMinutes(1); |
||||
ThreadPoolTaskScheduler executor = this.builder.awaitTerminationPeriod(period).build(); |
||||
assertThat(executor).hasFieldOrPropertyWithValue("awaitTerminationMillis", period.toMillis()); |
||||
} |
||||
|
||||
@Test |
||||
void threadNamePrefixShouldApply() { |
||||
ThreadPoolTaskScheduler scheduler = this.builder.threadNamePrefix("test-").build(); |
||||
assertThat(scheduler.getThreadNamePrefix()).isEqualTo("test-"); |
||||
} |
||||
|
||||
@Test |
||||
void customizersWhenCustomizersAreNullShouldThrowException() { |
||||
assertThatIllegalArgumentException() |
||||
.isThrownBy(() -> this.builder.customizers((TaskSchedulerCustomizer[]) null)) |
||||
.withMessageContaining("Customizers must not be null"); |
||||
} |
||||
|
||||
@Test |
||||
void customizersCollectionWhenCustomizersAreNullShouldThrowException() { |
||||
assertThatIllegalArgumentException() |
||||
.isThrownBy(() -> this.builder.customizers((Set<TaskSchedulerCustomizer>) null)) |
||||
.withMessageContaining("Customizers must not be null"); |
||||
} |
||||
|
||||
@Test |
||||
void customizersShouldApply() { |
||||
TaskSchedulerCustomizer customizer = mock(TaskSchedulerCustomizer.class); |
||||
ThreadPoolTaskScheduler scheduler = this.builder.customizers(customizer).build(); |
||||
then(customizer).should().customize(scheduler); |
||||
} |
||||
|
||||
@Test |
||||
void customizersShouldBeAppliedLast() { |
||||
ThreadPoolTaskScheduler scheduler = spy(new ThreadPoolTaskScheduler()); |
||||
this.builder.poolSize(4).threadNamePrefix("test-").additionalCustomizers((taskScheduler) -> { |
||||
then(taskScheduler).should().setPoolSize(4); |
||||
then(taskScheduler).should().setThreadNamePrefix("test-"); |
||||
}); |
||||
this.builder.configure(scheduler); |
||||
} |
||||
|
||||
@Test |
||||
void customizersShouldReplaceExisting() { |
||||
TaskSchedulerCustomizer customizer1 = mock(TaskSchedulerCustomizer.class); |
||||
TaskSchedulerCustomizer customizer2 = mock(TaskSchedulerCustomizer.class); |
||||
ThreadPoolTaskScheduler scheduler = this.builder.customizers(customizer1) |
||||
.customizers(Collections.singleton(customizer2)) |
||||
.build(); |
||||
then(customizer1).shouldHaveNoInteractions(); |
||||
then(customizer2).should().customize(scheduler); |
||||
} |
||||
|
||||
@Test |
||||
void additionalCustomizersWhenCustomizersAreNullShouldThrowException() { |
||||
assertThatIllegalArgumentException() |
||||
.isThrownBy(() -> this.builder.additionalCustomizers((TaskSchedulerCustomizer[]) null)) |
||||
.withMessageContaining("Customizers must not be null"); |
||||
} |
||||
|
||||
@Test |
||||
void additionalCustomizersCollectionWhenCustomizersAreNullShouldThrowException() { |
||||
assertThatIllegalArgumentException() |
||||
.isThrownBy(() -> this.builder.additionalCustomizers((Set<TaskSchedulerCustomizer>) null)) |
||||
.withMessageContaining("Customizers must not be null"); |
||||
} |
||||
|
||||
@Test |
||||
void additionalCustomizersShouldAddToExisting() { |
||||
TaskSchedulerCustomizer customizer1 = mock(TaskSchedulerCustomizer.class); |
||||
TaskSchedulerCustomizer customizer2 = mock(TaskSchedulerCustomizer.class); |
||||
ThreadPoolTaskScheduler scheduler = this.builder.customizers(customizer1) |
||||
.additionalCustomizers(customizer2) |
||||
.build(); |
||||
then(customizer1).should().customize(scheduler); |
||||
then(customizer2).should().customize(scheduler); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue