diff --git a/bundles/org.openhab.binding.tr064/src/main/java/org/openhab/binding/tr064/internal/util/Util.java b/bundles/org.openhab.binding.tr064/src/main/java/org/openhab/binding/tr064/internal/util/Util.java index 6aa65a13aac45..5da451a12e105 100644 --- a/bundles/org.openhab.binding.tr064/src/main/java/org/openhab/binding/tr064/internal/util/Util.java +++ b/bundles/org.openhab.binding.tr064/src/main/java/org/openhab/binding/tr064/internal/util/Util.java @@ -49,6 +49,7 @@ import org.openhab.binding.tr064.internal.dto.config.ParameterType; import org.openhab.binding.tr064.internal.dto.scpd.root.SCPDServiceType; import org.openhab.binding.tr064.internal.dto.scpd.service.*; +import org.openhab.core.cache.ExpiringCacheMap; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; import org.openhab.core.thing.binding.builder.ChannelBuilder; @@ -67,6 +68,12 @@ @NonNullByDefault public class Util { private static final Logger LOGGER = LoggerFactory.getLogger(Util.class); + private static final int HTTP_REQUEST_TIMEOUT = 5; // in s + private static final int XML_OBJECT_CACHE_EXPIRY_TIME = 3000; // in ms + + // cache XML content for 5s + private static final ExpiringCacheMap XML_OBJECT_CACHE = new ExpiringCacheMap<>( + XML_OBJECT_CACHE_EXPIRY_TIME); /** * read the channel config from the resource file (static initialization) @@ -317,23 +324,37 @@ public static Optional getSOAPElement(SOAPMessage soapMessage, String el * @param clazz the class describing the XML file * @return unmarshalling result */ + @SuppressWarnings("unchecked") public static @Nullable T getAndUnmarshalXML(HttpClient httpClient, String uri, Class clazz) { try { - ContentResponse contentResponse = httpClient.newRequest(uri).timeout(2, TimeUnit.SECONDS) - .method(HttpMethod.GET).send(); - byte[] response = contentResponse.getContent(); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("XML = {}", new String(response)); - } - InputStream xml = new ByteArrayInputStream(response); + T returnValue = (T) XML_OBJECT_CACHE.putIfAbsentAndGet(uri, () -> { + try { + LOGGER.trace("Refreshing cache for '{}'", uri); + ContentResponse contentResponse = httpClient.newRequest(uri) + .timeout(HTTP_REQUEST_TIMEOUT, TimeUnit.SECONDS).method(HttpMethod.GET).send(); + byte[] response = contentResponse.getContent(); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("XML = {}", new String(response)); + } + InputStream xml = new ByteArrayInputStream(response); - JAXBContext context = JAXBContext.newInstance(clazz); - Unmarshaller um = context.createUnmarshaller(); - return um.unmarshal(new StreamSource(xml), clazz).getValue(); - } catch (ExecutionException | InterruptedException | TimeoutException e) { - LOGGER.debug("HTTP Failed to GET uri '{}': {}", uri, e.getMessage()); - } catch (JAXBException e) { - LOGGER.debug("Unmarshalling failed: {}", e.getMessage()); + JAXBContext context = JAXBContext.newInstance(clazz); + Unmarshaller um = context.createUnmarshaller(); + T newValue = um.unmarshal(new StreamSource(xml), clazz).getValue(); + LOGGER.trace("Storing in cache {}", newValue); + return newValue; + } catch (ExecutionException | InterruptedException | TimeoutException e) { + LOGGER.debug("HTTP Failed to GET uri '{}': {}", uri, e.getMessage()); + throw new IllegalArgumentException(); + } catch (JAXBException e) { + LOGGER.debug("Unmarshalling failed: {}", e.getMessage()); + throw new IllegalArgumentException(); + } + }); + LOGGER.trace("Returning from cache: {}", returnValue); + return returnValue; + } catch (IllegalArgumentException e) { + // already logged } return null; }