package fi.otavanopisto.muikku.plugins.schooldatapyramus.rest;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Singleton;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.ext.ContextResolver;
import org.jboss.resteasy.client.jaxrs.cache.BrowserCacheFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JSR310Module;
@ApplicationScoped
@Singleton
@Lock(LockType.WRITE)
public class ClientPool {
@Inject
private Logger logger;
@PostConstruct
public void init() {
pooledClients = new ArrayList<>();
}
@PreDestroy
public void deinit() {
for (Client pooledClient : pooledClients) {
pooledClient.close();
}
}
@Lock(LockType.WRITE)
public Client obtainClient() {
if (pooledClients.isEmpty()) {
return buildClient();
}
return pooledClients.remove(pooledClients.size() - 1);
}
@Lock(LockType.WRITE)
public void releaseClient(Client client) {
pooledClients.add(client);
}
private Client buildClient() {
// TODO: trust all only on development environment
ClientBuilder clientBuilder = ClientBuilder.newBuilder();
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
} };
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
} catch (NoSuchAlgorithmException | KeyManagementException e) {
logger.log(Level.SEVERE, "Failed to initialize trust all certificate manager", e);
}
HostnameVerifier fakeHostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
ClientBuilder builder = clientBuilder
.sslContext(sslContext)
.hostnameVerifier(fakeHostnameVerifier)
.register(new JacksonConfigurator())
.register(new BrowserCacheFeature());
return builder.build();
}
private List<Client> pooledClients;
private class JacksonConfigurator implements ContextResolver<ObjectMapper> {
@Override
public ObjectMapper getContext(Class<?> type) {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JSR310Module());
return objectMapper;
}
}
}