package com.constellio.model.services.contents.icap; import com.constellio.data.threads.ConstellioJob; import com.constellio.data.threads.ConstellioJobManager; import com.constellio.model.services.factories.ModelLayerFactory; import org.apache.commons.lang.StringUtils; import org.joda.time.DateTime; import org.joda.time.DateTimeConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.util.Arrays; import java.util.Date; import java.util.Set; import java.util.TreeSet; /** * */ public class IcapService { public final static class IcapPreviewLengthReaderJob extends ConstellioJob { private static Runnable action; @Override protected String name() { return IcapPreviewLengthReaderJob.class.getSimpleName(); } @Override protected Runnable action() { return action; } @Override protected boolean unscheduleOnException() { return false; } @Override protected Set<Integer> intervals() { return new TreeSet<>(Arrays.asList(new Integer[] { DateTimeConstants.SECONDS_PER_HOUR })); } @Override protected Set<String> cronExpressions() { return null; } @Override protected Date startTime() { return DateTime.now().toDate(); } } private static final Logger LOGGER = LoggerFactory.getLogger(ConstellioJob.class); private final ModelLayerFactory modelLayerFactory; private final ConstellioJobManager constellioJobManager; private String icapServerUrl; private Integer icapPreviewLength = 30; public IcapService(final ModelLayerFactory modelLayerFactory) { this.modelLayerFactory = modelLayerFactory; constellioJobManager = modelLayerFactory.getDataLayerFactory().getConstellioJobManager(); } public void init() { // IcapPreviewLengthReaderJob.action = new Runnable() { @Override public void run() { readPreviewLengthFromIcapServer(); } }; // constellioJobManager.addJob(new IcapPreviewLengthReaderJob(), true); } void readPreviewLengthFromIcapServer() { if (modelLayerFactory.getSystemConfigs().getIcapScanActivated()) { icapServerUrl = modelLayerFactory.getSystemConfigs().getIcapServerUrl(); if (StringUtils.isBlank(icapServerUrl)) { LOGGER.error("ICAP is activated while its server URL is missing"); } else { final int icapResponseTimeout = modelLayerFactory.getSystemConfigs().getIcapResponseTimeout(); Integer icapPreviewLengthNewValue = null; try { icapPreviewLengthNewValue = new IcapClient(URI.create(icapServerUrl), icapResponseTimeout) .getIcapConfigurationsFromServer().getPreviewLength(); } catch (final IOException e) { LOGGER.warn("communication error while reading preview length from ICAP server"); } if (icapPreviewLengthNewValue == null) { LOGGER.warn("missing preview header in ICAP OPTIONS method response"); } else { icapPreviewLength = icapPreviewLengthNewValue; } } } } public void scan(final String filename, final InputStream fileContent) { if (modelLayerFactory.getSystemConfigs().getIcapScanActivated()) { icapServerUrl = modelLayerFactory.getSystemConfigs().getIcapServerUrl(); if (StringUtils.isBlank(icapServerUrl)) { LOGGER.error("ICAP is activated while its server URL is missing"); } else { try { IcapResponse icapResponse = tryScan(filename, fileContent); if (icapResponse.isScanTimedout()) { final IcapException.TimeoutException timeoutException = new IcapException.TimeoutException(filename); LOGGER.info(timeoutException.getMessage() + " - " + filename); throw timeoutException; } if (icapResponse.isNoThreatFound()) { return; } String threatDescription = icapResponse.getThreatDescription(); if (StringUtils.isEmpty(threatDescription)) { return; } final IcapException.ThreatFoundException threatFoundException = new IcapException.ThreatFoundException( icapResponse.getThreatDescription(), filename); LOGGER.info(threatFoundException.getMessage() + " " + threatFoundException.getThreatName() + " - " + filename); throw threatFoundException; } catch (final IOException e) { final IcapException.CommunicationFailure communicationFailureException = new IcapException.CommunicationFailure( e, filename); LOGGER.warn(communicationFailureException.getMessage() + " - " + filename, communicationFailureException); throw communicationFailureException; } } } } public IcapResponse tryScan(String filename, InputStream fileContent) throws IOException { final String constellioServerHostname = URI.create(modelLayerFactory.getSystemConfigs().getConstellioUrl()).getHost(); final int icapResponseTimeout = modelLayerFactory.getSystemConfigs().getIcapResponseTimeout(); return new IcapClient(URI.create(icapServerUrl), icapResponseTimeout) .scanFile(filename, fileContent, constellioServerHostname, icapPreviewLength); } }