de.mklinger.qetcher.liferay.client.impl.QetcherClientServiceImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of qetcher-adapter-liferay-71 Show documentation
Show all versions of qetcher-adapter-liferay-71 Show documentation
Qetcher Liferay 7.1.x Adapter
The newest version!
package de.mklinger.qetcher.liferay.client.impl;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Path;
import java.security.KeyStore;
import java.util.Map;
import java.util.function.Supplier;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.liferay.portal.configuration.metatype.bnd.util.ConfigurableUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.PropsUtil;
import de.mklinger.micro.annotations.VisibleForTesting;
import de.mklinger.micro.keystores.KeyStores;
import de.mklinger.qetcher.client.InputConversionFile;
import de.mklinger.qetcher.client.InputJob;
import de.mklinger.qetcher.client.QetcherClient;
import de.mklinger.qetcher.client.QetcherClient.Builder;
import de.mklinger.qetcher.client.QetcherClientBuilders;
import de.mklinger.qetcher.client.QetcherClientException;
import de.mklinger.qetcher.client.QetcherClientVersion;
import de.mklinger.qetcher.client.httpclient.BodyProviders;
import de.mklinger.qetcher.liferay.client.QetcherClientService;
/**
* @author Marc Klinger - mklinger[at]mklinger[dot]de
*/
@Component(configurationPid = QetcherConfiguration.ID, configurationPolicy = ConfigurationPolicy.REQUIRE)
public class QetcherClientServiceImpl implements QetcherClientService {
private static final Logger LOG = LoggerFactory.getLogger(QetcherClientServiceImpl.class);
private QetcherTrustStoreSupplier trustStoreSupplier;
private Map configurationProperties;
private QetcherClient client;
@Reference(policy = ReferencePolicy.DYNAMIC)
public synchronized void setTrustStoreSupplier(final QetcherTrustStoreSupplier trustStoreSupplier) {
LOG.info("Trust store supplier was set");
this.trustStoreSupplier = trustStoreSupplier;
resetClient();
}
// Called by OSGi framework by naming convention
public synchronized void unsetTrustStoreSupplier(final QetcherTrustStoreSupplier trustStoreSupplier) {
LOG.info("Trust store supplier was unset");
this.trustStoreSupplier = null;
resetClient();
}
// Called by OSGi framework by naming convention
public synchronized void updatedTrustStoreSupplier(final QetcherTrustStoreSupplier trustStoreSupplier) {
LOG.info("Trust store supplier was updated");
this.trustStoreSupplier = trustStoreSupplier;
resetClient();
}
@Activate
@Modified
public synchronized void activate(final Map properties) {
LOG.info("Configuration was set");
this.configurationProperties = properties;
resetClient();
}
private synchronized void resetClient() {
closeClient();
if (configurationProperties == null) {
LOG.error("Could not create Qetcher client as no configuration is available");
client = new DefunctQetcherClient("Qetcher client is not functional. No configuration available");
return;
}
if (trustStoreSupplier == null) {
LOG.error("Could not create Qetcher client as no trust store supplier is available");
client = new DefunctQetcherClient("Qetcher client is not functional. No trust store supplier available");
return;
}
QetcherConfiguration configuration;
try {
configuration = ConfigurableUtil.createConfigurable(QetcherConfiguration.class, configurationProperties);
} catch (final Exception e) {
final String causeMessages = getCauseMessages(e);
LOG.error("Error creating Qetcher configuration: {}", causeMessages);
client = new DefunctQetcherClient("Qetcher client is not functional. There was an error creating Qetcher configuration: " + causeMessages);
return;
}
try {
client = newClient(configuration);
LOG.info("Successfully created new Qetcher client");
} catch (final Exception e) {
final String causeMessages = getCauseMessages(e);
LOG.error("Error creating Qetcher client: {}", causeMessages, e);
client = new DefunctQetcherClient("Qetcher client is not functional. There was an error creating Qetcher client instance: " + causeMessages);
return;
}
}
private static String getCauseMessages(final Throwable e) {
return getCauseMessages(e, ": ");
}
private static String getCauseMessages(final Throwable e, final String separator) {
final StringBuilder sb = new StringBuilder();
Throwable cause = e;
while (cause != null) {
final String message = cause.getMessage();
if (message != null) {
if (sb.length() > 0) {
sb.append(separator);
}
sb.append(message);
}
cause = cause.getCause();
}
return sb.toString();
}
@Deactivate
public synchronized void closeClient() {
try {
if (client != null) {
final QetcherClient oldClient = client;
client = null;
if (oldClient instanceof NonClosingQetcherClient) {
((NonClosingQetcherClient) oldClient).reallyClose();
} else {
oldClient.close();
}
}
} catch (final Exception e) {
LOG.warn("Error closing Qetcher client", e);
}
}
private NonClosingQetcherClient newClient(final QetcherConfiguration configuration) {
final String[] serviceAddresses = configuration.serviceAddresses();
if (serviceAddresses == null || serviceAddresses.length == 0) {
throw new QetcherClientException("No Qetcher service addresses configured");
}
final KeyStore keyStore = loadKeyStore(configuration);
final String keyPassword = emptyToNull(configuration.keyPassword());
final KeyStore trustStore = trustStoreSupplier.get();
final QetcherClient qetcherClient = newClientBuilder()
.serviceAddresses(serviceAddresses)
.keyStore(keyStore, keyPassword)
.trustStore(trustStore)
.build();
LOG.info("Initialized new Qetcher client, version {}", QetcherClientVersion.getVersion());
LOG.info("Using Qetcher service addresses: {}", (Object)configuration.serviceAddresses());
new QetcherClientCertificateInfo(keyStore).log();
return new NonClosingQetcherClient(qetcherClient);
}
@VisibleForTesting
protected Builder newClientBuilder() {
return QetcherClientBuilders.client();
}
private KeyStore loadKeyStore(final QetcherConfiguration configuration) {
final String keyStoreLocation = getKeyStoreLocation(configuration);
final String keyStorePassword = emptyToNull(configuration.keyStorePassword());
final String keyStoreType = emptyToNull(configuration.keyStoreType());
return KeyStores.load(
keyStoreLocation,
keyStorePassword,
keyStoreType);
}
private String getKeyStoreLocation(final QetcherConfiguration configuration) {
String keyStoreLocation = configuration.keyStoreLocation();
if (keyStoreLocation == null || keyStoreLocation.isEmpty()) {
keyStoreLocation = PropsUtil.get(PropsKeys.LIFERAY_HOME) + "/data/qetcher/qetcher-key.p12";
LOG.info("No Qetcher key store location configured. Using default location: {}", keyStoreLocation);
}
return keyStoreLocation;
}
private String emptyToNull(final String s) {
if (s != null && s.trim().isEmpty()) {
return null;
}
return s;
}
@Override
public synchronized QetcherClient client() {
if (client == null) {
throw new QetcherClientException("Qetcher client is not initialized. Check configuration and previous log.");
}
return client;
}
@Override
public InputConversionFile.Builder inputFileFor(final File inputFile) {
return QetcherClientBuilders.inputFileFor(inputFile);
}
@Override
public InputConversionFile.Builder inputFileFor(final Path inputFile) {
return QetcherClientBuilders.inputFileFor(inputFile);
}
@Override
public InputConversionFile.Builder inputFileFor(final Supplier inputStreamSupplier) {
return QetcherClientBuilders.inputFile()
.bodyProvider(BodyProviders.fromInputStream(inputStreamSupplier));
}
@Override
public InputJob.Builder job() {
return QetcherClientBuilders.job();
}
}