Skip to content

Commit

Permalink
Issue ReactiveX#430: Added timelimiter to spring modules (ReactiveX#810)
Browse files Browse the repository at this point in the history
  • Loading branch information
dlsrb6342 authored Feb 3, 2020
1 parent 52afaee commit 9ca459a
Show file tree
Hide file tree
Showing 60 changed files with 2,834 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2020 Ingyu Hwang
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.github.resilience4j.timelimiter.annotation;

import java.lang.annotation.*;

@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD, ElementType.TYPE})
@Documented
public @interface TimeLimiter {

/**
* Name of the sync timeLimiter.
*
* @return the name of the sync timeLimiter.
*/
String name();

/**
* fallbackMethod method name.
*
* @return fallbackMethod method name.
*/
String fallbackMethod() default "";

}
2 changes: 1 addition & 1 deletion resilience4j-framework-common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ dependencies {
compile project(':resilience4j-ratelimiter')
compile project(':resilience4j-retry')
compile project(':resilience4j-bulkhead')

compile project(':resilience4j-timelimiter')
}

ext.moduleName = 'io.github.resilience4j.framework-common'
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* Copyright 2020 Ingyu Hwang
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.github.resilience4j.common.timelimiter.configuration;

import io.github.resilience4j.common.utils.ConfigUtils;
import io.github.resilience4j.core.ConfigurationNotFoundException;
import io.github.resilience4j.core.StringUtils;
import io.github.resilience4j.core.lang.Nullable;
import io.github.resilience4j.timelimiter.TimeLimiterConfig;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class TimeLimiterConfigurationProperties {

private final Map<String, InstanceProperties> instances = new HashMap<>();
private final Map<String, InstanceProperties> configs = new HashMap<>();

public Map<String, InstanceProperties> getInstances() {
return instances;
}

public Map<String, InstanceProperties> getConfigs() {
return configs;
}

/**
* @param backend timeLimiter backend name
* @return the configured spring backend properties
*/
@Nullable
public InstanceProperties getInstanceProperties(String backend) {
return instances.get(backend);
}

public TimeLimiterConfig createTimeLimiterConfig(@Nullable InstanceProperties instanceProperties) {
if (instanceProperties == null) {
return TimeLimiterConfig.ofDefaults();
}
if (StringUtils.isNotEmpty(instanceProperties.getBaseConfig())) {
InstanceProperties baseProperties = configs.get(instanceProperties.getBaseConfig());
if (baseProperties == null) {
throw new ConfigurationNotFoundException(instanceProperties.getBaseConfig());
}
return buildConfigFromBaseConfig(baseProperties, instanceProperties);
}
return buildTimeLimiterConfig(TimeLimiterConfig.custom(), instanceProperties);
}

private static TimeLimiterConfig buildConfigFromBaseConfig(
InstanceProperties baseProperties, InstanceProperties instanceProperties) {
ConfigUtils.mergePropertiesIfAny(baseProperties, instanceProperties);
TimeLimiterConfig baseConfig = buildTimeLimiterConfig(TimeLimiterConfig.custom(), baseProperties);
return buildTimeLimiterConfig(TimeLimiterConfig.from(baseConfig), instanceProperties);
}

private static TimeLimiterConfig buildTimeLimiterConfig(
TimeLimiterConfig.Builder builder, @Nullable InstanceProperties instanceProperties) {
if (instanceProperties == null) {
return builder.build();
}

if (instanceProperties.getTimeoutDuration() != null) {
builder.timeoutDuration(instanceProperties.getTimeoutDuration());
}

if (instanceProperties.getCancelRunningFuture() != null) {
builder.cancelRunningFuture(instanceProperties.getCancelRunningFuture());
}

return builder.build();
}

public TimeLimiterConfig createTimeLimiterConfig(String limiter) {
return createTimeLimiterConfig(getInstanceProperties(limiter));
}

public static class InstanceProperties {

private Duration timeoutDuration;
private Boolean cancelRunningFuture;
@Nullable
private Integer eventConsumerBufferSize;

@Nullable
private String baseConfig;

public Duration getTimeoutDuration() {
return timeoutDuration;
}

public InstanceProperties setTimeoutDuration(Duration timeoutDuration) {
Objects.requireNonNull(timeoutDuration);
if (timeoutDuration.toMillis() < 0) {
throw new IllegalArgumentException(
"timeoutDuration must be greater than or equal to 0.");
}
this.timeoutDuration = timeoutDuration;
return this;
}

public Boolean getCancelRunningFuture() {
return cancelRunningFuture;
}

public InstanceProperties setCancelRunningFuture(Boolean cancelRunningFuture) {
this.cancelRunningFuture = cancelRunningFuture;
return this;
}

public Integer getEventConsumerBufferSize() {
return eventConsumerBufferSize;
}

public InstanceProperties setEventConsumerBufferSize(Integer eventConsumerBufferSize) {
Objects.requireNonNull(eventConsumerBufferSize);
if (eventConsumerBufferSize < 1) {
throw new IllegalArgumentException("eventConsumerBufferSize must be greater than or equal to 1.");
}

this.eventConsumerBufferSize = eventConsumerBufferSize;
return this;
}

@Nullable
public String getBaseConfig() {
return baseConfig;
}

public void setBaseConfig(@Nullable String baseConfig) {
this.baseConfig = baseConfig;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2020 Ingyu Hwang
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.github.resilience4j.common.timelimiter.monitoring.endpoint;

import io.github.resilience4j.core.lang.Nullable;

import java.util.List;

public class TimeLimiterEndpointResponse {

@Nullable
private List<String> timeLimiters;

public TimeLimiterEndpointResponse(){
}

public TimeLimiterEndpointResponse(List<String> timeLimiters){
this.timeLimiters = timeLimiters;
}

@Nullable
public List<String> getTimeLimiters() {
return timeLimiters;
}

public void setTimeLimiters(List<String> timeLimiters) {
this.timeLimiters = timeLimiters;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright 2020 Ingyu Hwang
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.github.resilience4j.common.timelimiter.monitoring.endpoint;

import io.github.resilience4j.core.lang.Nullable;
import io.github.resilience4j.timelimiter.event.TimeLimiterEvent;

public class TimeLimiterEventDTO {

@Nullable
private String timeLimiterName;
@Nullable private TimeLimiterEvent.Type type;
@Nullable private String creationTime;

public static TimeLimiterEventDTO createTimeLimiterEventDTO(TimeLimiterEvent timeLimiterEvent) {
TimeLimiterEventDTO dto = new TimeLimiterEventDTO();
dto.setTimeLimiterName(timeLimiterEvent.getTimeLimiterName());
dto.setType(timeLimiterEvent.getEventType());
dto.setCreationTime(timeLimiterEvent.getCreationTime().toString());
return dto;
}

@Nullable
public String getTimeLimiterName() {
return timeLimiterName;
}

public void setTimeLimiterName(@Nullable String timeLimiterName) {
this.timeLimiterName = timeLimiterName;
}

@Nullable
public TimeLimiterEvent.Type getType() {
return type;
}

public void setType(@Nullable TimeLimiterEvent.Type type) {
this.type = type;
}

@Nullable
public String getCreationTime() {
return creationTime;
}

public void setCreationTime(@Nullable String creationTime) {
this.creationTime = creationTime;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2020 Ingyu Hwang
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.github.resilience4j.common.timelimiter.monitoring.endpoint;

import io.github.resilience4j.core.lang.Nullable;

import java.util.List;

public class TimeLimiterEventsEndpointResponse {

@Nullable
private List<TimeLimiterEventDTO> timeLimiterEvents;

public TimeLimiterEventsEndpointResponse() {
}

public TimeLimiterEventsEndpointResponse(@Nullable List<TimeLimiterEventDTO> timeLimiterEvents) {
this.timeLimiterEvents = timeLimiterEvents;
}

@Nullable
public List<TimeLimiterEventDTO> getTimeLimiterEvents() {
return timeLimiterEvents;
}

public void setTimeLimiterEvents(@Nullable List<TimeLimiterEventDTO> timeLimiterEvents) {
this.timeLimiterEvents = timeLimiterEvents;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import io.github.resilience4j.common.circuitbreaker.configuration.CircuitBreakerConfigurationProperties;
import io.github.resilience4j.common.ratelimiter.configuration.RateLimiterConfigurationProperties;
import io.github.resilience4j.common.retry.configuration.RetryConfigurationProperties;
import io.github.resilience4j.common.timelimiter.configuration.TimeLimiterConfigurationProperties;

/**
* resilience4j configuration util
Expand Down Expand Up @@ -127,4 +128,18 @@ public static void mergePropertiesIfAny(
}
}

/**
* merge only properties that are not part of timeLimiter config if any match the conditions of merge
*
* @param baseProperties base config properties
* @param instanceProperties instance properties
*/
public static void mergePropertiesIfAny(TimeLimiterConfigurationProperties.InstanceProperties baseProperties,
TimeLimiterConfigurationProperties.InstanceProperties instanceProperties) {
if (instanceProperties.getEventConsumerBufferSize() == null
&& baseProperties.getEventConsumerBufferSize() != null) {
instanceProperties.setEventConsumerBufferSize(baseProperties.getEventConsumerBufferSize());
}
}

}
Loading

0 comments on commit 9ca459a

Please sign in to comment.