/* * Copyright 2014-2016 Hewlett-Packard Development Company, L.P. * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. */ package com.hp.autonomy.frontend.find.idol.stats; import com.autonomy.aci.client.services.AciService; import com.autonomy.aci.client.util.AciParameters; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.hp.autonomy.frontend.configuration.ConfigService; import com.hp.autonomy.frontend.find.core.stats.Event; import com.hp.autonomy.frontend.find.core.stats.StatsService; import com.hp.autonomy.frontend.find.idol.configuration.IdolFindConfig; import com.hp.autonomy.types.idol.marshalling.ProcessorFactory; import com.hp.autonomy.types.requests.idol.actions.stats.StatsServerActions; import com.hp.autonomy.types.requests.idol.actions.stats.params.EventParams; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.BooleanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @Service @Slf4j class IdolStatsService implements StatsService { private final BlockingQueue<Event> queue = new LinkedBlockingQueue<>(); private final AciService statsServerAciService; private final ProcessorFactory processorFactory; private final XmlMapper xmlMapper; private final ConfigService<IdolFindConfig> configService; @Autowired public IdolStatsService( final AciService statsServerAciService, final ProcessorFactory processorFactory, final XmlMapper xmlMapper, final ConfigService<IdolFindConfig> configService ) { this.statsServerAciService = statsServerAciService; this.processorFactory = processorFactory; this.xmlMapper = xmlMapper; this.configService = configService; } @Override public void recordEvent(final Event event) { // if not enabled, throw the event away if (isEnabled()) { queue.add(event); } } @Scheduled(fixedRate = 5000L) public void drainQueue() { final List<Event> eventsList = new ArrayList<>(); queue.drainTo(eventsList); // if no events, no work to do // if not enabled, throw the events away // (it's still useful to drain the queue if stats are disabled while the app is running) if (isEnabled() && !eventsList.isEmpty()) { final Events events = new Events(eventsList); try { final String xml = xmlMapper.writeValueAsString(events); final AciParameters parameters = new AciParameters(StatsServerActions.Event.name()); parameters.put(EventParams.Data.name(), xml); statsServerAciService.executeAction(parameters, processorFactory.getVoidProcessor()); } catch (final JsonProcessingException e) { // includes XML errors which should only occur during development // throwing won't result in the exception going anywhere useful anyway log.error("Error constructing XML: ", e); } } } private boolean isEnabled() { return BooleanUtils.isTrue(configService.getConfig().getStatsServer().getEnabled()); } }