Skip to content

Commit fd13d7e

Browse files
committed
Introduce the foundations of the new endpoint infrastructure
1 parent 7cc4410 commit fd13d7e

20 files changed

+1676
-0
lines changed

spring-boot/src/main/java/org/springframework/boot/endpoint/AnnotationEndpointDiscoverer.java

Lines changed: 404 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2012-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.endpoint;
18+
19+
/**
20+
* Provide the caching configuration of an endpoint.
21+
*
22+
* @author Stephane Nicoll
23+
* @since 2.0.0
24+
*/
25+
public class CachingConfiguration {
26+
27+
private final long timeToLive;
28+
29+
/**
30+
* Create a new instance with the caching period to use.
31+
* @param timeToLive the time to live of an operation result in milliseconds
32+
*/
33+
public CachingConfiguration(long timeToLive) {
34+
this.timeToLive = timeToLive;
35+
}
36+
37+
/**
38+
* Return the operation caching period in milliseconds.
39+
* @return the time to live of an operation result
40+
*/
41+
public long getTimeToLive() {
42+
return this.timeToLive;
43+
}
44+
45+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright 2012-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.endpoint;
18+
19+
import java.util.Map;
20+
21+
import org.springframework.util.Assert;
22+
23+
/**
24+
* An {@link OperationInvoker} that caches the response of an operation with a
25+
* configurable time to live.
26+
*
27+
* @author Stephane Nicoll
28+
* @since 2.0.0
29+
*/
30+
public class CachingOperationInvoker implements OperationInvoker {
31+
32+
private final OperationInvoker target;
33+
34+
private final long timeToLive;
35+
36+
private volatile CachedResponse cachedResponse;
37+
38+
/**
39+
* Create a new instance with the target {@link OperationInvoker} to use to compute
40+
* the response and the time to live for the cache.
41+
* @param target the {@link OperationInvoker} this instance wraps
42+
* @param timeToLive the maximum time in milliseconds that a response can be cached
43+
*/
44+
public CachingOperationInvoker(OperationInvoker target, long timeToLive) {
45+
Assert.state(timeToLive > 0, "TimeToLive must be strictly positive");
46+
this.target = target;
47+
this.timeToLive = timeToLive;
48+
}
49+
50+
/**
51+
* Return the maximum time in milliseconds that a response can be cached.
52+
* @return the time to live of a response
53+
*/
54+
public long getTimeToLive() {
55+
return this.timeToLive;
56+
}
57+
58+
@Override
59+
public Object invoke(Map<String, Object> arguments) {
60+
long accessTime = System.currentTimeMillis();
61+
CachedResponse cached = this.cachedResponse;
62+
if (cached == null || cached.isStale(accessTime, this.timeToLive)) {
63+
Object response = this.target.invoke(arguments);
64+
this.cachedResponse = new CachedResponse(response, accessTime);
65+
return response;
66+
}
67+
return cached.getResponse();
68+
}
69+
70+
/**
71+
* A cached response that encapsulates the response itself and the time at which it
72+
* was created.
73+
*/
74+
static class CachedResponse {
75+
76+
private final Object response;
77+
78+
private final long creationTime;
79+
80+
CachedResponse(Object response, long creationTime) {
81+
this.response = response;
82+
this.creationTime = creationTime;
83+
}
84+
85+
public boolean isStale(long accessTime, long timeToLive) {
86+
return (accessTime - this.creationTime) >= timeToLive;
87+
}
88+
89+
public Object getResponse() {
90+
return this.response;
91+
}
92+
93+
}
94+
95+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2012-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.endpoint;
18+
19+
import org.springframework.boot.context.properties.bind.convert.BinderConversionService;
20+
import org.springframework.core.convert.ConversionService;
21+
22+
/**
23+
* {@link OperationParameterMapper} that uses a {@link ConversionService} to convert a
24+
* parameter value if necessary.
25+
*
26+
* @author Stephane Nicoll
27+
* @since 2.0.0
28+
*/
29+
public class ConversionServiceOperationParameterMapper
30+
implements OperationParameterMapper {
31+
32+
private final ConversionService conversionService;
33+
34+
/**
35+
* Create a new instance with the {@link ConversionService} to use.
36+
* @param conversionService the conversion service
37+
*/
38+
public ConversionServiceOperationParameterMapper(
39+
ConversionService conversionService) {
40+
this.conversionService = new BinderConversionService(conversionService);
41+
}
42+
43+
@Override
44+
public <T> T mapParameter(Object input, Class<T> parameterType) {
45+
if (input == null || parameterType.isAssignableFrom(input.getClass())) {
46+
return parameterType.cast(input);
47+
}
48+
try {
49+
return this.conversionService.convert(input, parameterType);
50+
}
51+
catch (Exception ex) {
52+
throw new ParameterMappingException(input, parameterType, ex);
53+
}
54+
}
55+
56+
protected final ConversionService getConversionService() {
57+
return this.conversionService;
58+
}
59+
60+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2012-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.endpoint;
18+
19+
import java.lang.annotation.Documented;
20+
import java.lang.annotation.ElementType;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.RetentionPolicy;
23+
import java.lang.annotation.Target;
24+
25+
/**
26+
* Identifies a type as being an endpoint.
27+
*
28+
* @author Andy Wilkinson
29+
* @since 2.0.0
30+
* @see EndpointDiscoverer
31+
*/
32+
@Target(ElementType.TYPE)
33+
@Retention(RetentionPolicy.RUNTIME)
34+
@Documented
35+
public @interface Endpoint {
36+
37+
/**
38+
* The id of the endpoint.
39+
* @return the id
40+
*/
41+
String id();
42+
43+
/**
44+
* Defines the endpoint {@link EndpointType types} that should be exposed. By default,
45+
* all types are exposed.
46+
* @return the endpoint types to expose
47+
*/
48+
EndpointType[] types() default {};
49+
50+
/**
51+
* Whether or not the endpoint is enabled by default.
52+
* @return {@code true} if the endpoint is enabled by default, otherwise {@code false}
53+
*/
54+
boolean enabledByDefault() default true;
55+
56+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2012-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.endpoint;
18+
19+
import java.util.Collection;
20+
21+
/**
22+
* Discovers endpoints and provides a {@link EndpointInfo} for each of them.
23+
*
24+
* @param <T> the type of the operation
25+
* @author Andy Wilkinson
26+
* @author Stephane Nicoll
27+
* @since 2.0.0
28+
*/
29+
public interface EndpointDiscoverer<T extends EndpointOperation> {
30+
31+
/**
32+
* Perform endpoint discovery.
33+
* @return the discovered endpoints
34+
*/
35+
Collection<EndpointInfo<T>> discoverEndpoints();
36+
37+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2012-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.endpoint;
18+
19+
import java.util.Collection;
20+
21+
/**
22+
* Information describing an endpoint.
23+
*
24+
* @param <T> the type of the endpoint operation info
25+
* @author Andy Wilkinson
26+
* @since 2.0.0
27+
*/
28+
public class EndpointInfo<T extends EndpointOperation> {
29+
30+
private final String id;
31+
32+
private final boolean enabledByDefault;
33+
34+
private final Collection<T> operations;
35+
36+
/**
37+
* Creates a new {@code EndpointInfo} describing an endpoint with the given {@code id}
38+
* and {@code operations}.
39+
* @param id the id of the endpoint
40+
* @param enabledByDefault whether or not the endpoint is enabled by default
41+
* @param operations the operations of the endpoint
42+
*/
43+
public EndpointInfo(String id, boolean enabledByDefault, Collection<T> operations) {
44+
this.id = id;
45+
this.enabledByDefault = enabledByDefault;
46+
this.operations = operations;
47+
}
48+
49+
/**
50+
* Returns the id of the endpoint.
51+
* @return the id
52+
*/
53+
public String getId() {
54+
return this.id;
55+
}
56+
57+
/**
58+
* Returns whether or not this endpoint is enabled by default.
59+
* @return {@code true} if it is enabled by default, otherwise {@code false}
60+
*/
61+
public boolean isEnabledByDefault() {
62+
return this.enabledByDefault;
63+
}
64+
65+
/**
66+
* Returns the operations of the endpoint.
67+
* @return the operations
68+
*/
69+
public Collection<T> getOperations() {
70+
return this.operations;
71+
}
72+
73+
}

0 commit comments

Comments
 (0)