Injecting Remote Properties With Java EE 📎
In Java EE the meta data of an injection target is available as a an optional parameter. The instance javax.enterprise.inject.spi.InjectionPoint
holds the class-, field information as well as used annotations:
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
@Produces
public String getString(InjectionPoint ip) {}
The following field's metadata provides sufficient information to perform a HTTP-GET request and inject the fetched value
at runtime:
@Inject
@CacheEntry(host = "headlands", port = 8080, cache = "configuration", key = "message")
String notexisting;
The metadata extracted from above field is used to resolve the following HTTP template and access a remote HTTP-resource:
http://{host}:{port}/headlands/resources/caches/{cache}/entries/{key}
The JAX-RS 2+ client resolves the template and performs the request:
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
import javax.ws.rs.client.WebTarget;
private Client client;
@PostConstruct
public void init() {
this.client = ClientBuilder.newClient();
}
WebTarget resolve(CacheEntry cacheEntry) {
return this.resolve(cacheEntry.host(), cacheEntry.port(),
cacheEntry.cache(), cacheEntry.key());
}
WebTarget resolve(String host, int port, String cache, String key) {
return resolve(host, port, cache).path(key);
}
WebTarget resolve(String host, int port, String cache) {
StringBuilder builder = new StringBuilder();
String hostUri = builder.append("http://").
append(host).
append(":").
append(port).toString();
return this.client.target(hostUri +
"/headlands/resources/caches/{cache}/entries/").
resolveTemplate("cache", cache);
}
Now you only have to "produce" the value fetched from a remote HTTP-location:
@Produces
@CacheEntry(cache = "-")
public String getString(InjectionPoint ip) {
Annotated annotated = ip.getAnnotated();
CacheEntry cacheEntry = annotated.getAnnotation(CacheEntry.class);
return resolve(cacheEntry).request().get(String.class);
}
The URI used in this example is compatible with headlands -- a JCache exposed via REST.
Project marina comprises a single class (you will find 80% above) and the CacheEntry
annotation. Marina enables injection of entries stored in a remote headlandsinstance.
<dependency>
<groupId>com.airhacks</groupId>
<artifactId>marina</artifactId>
<version>0.0.1</version>
</dependency>
See you at Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io. Marina and headlands are used as an example in the Microservices with Java EE 7 and Java 8 on-demand workshop.