package org.openstack.atlas.usage.thread;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openstack.atlas.atomhopper.exception.AtomHopperMappingException;
import org.openstack.atlas.cfg.Configuration;
import org.openstack.atlas.restclients.atomhopper.AtomHopperClient;
import org.openstack.atlas.restclients.atomhopper.config.AtomHopperConfiguration;
import org.openstack.atlas.restclients.atomhopper.config.AtomHopperConfigurationKeys;
import org.openstack.atlas.restclients.atomhopper.util.AtomHopperUtil;
import org.openstack.atlas.restclients.auth.IdentityAuthClient;
import org.openstack.atlas.service.domain.entities.Usage;
import org.openstack.atlas.service.domain.events.repository.AlertRepository;
import org.openstack.atlas.service.domain.events.repository.LoadBalancerEventRepository;
import org.openstack.atlas.usage.thread.helper.AHRecordHelper;
import java.util.Calendar;
import java.util.ConcurrentModificationException;
import java.util.List;
import java.util.Map;
import static org.openstack.atlas.restclients.atomhopper.util.AtomHopperUtil.getExtendedStackTrace;
public abstract class AbstractAtomHopperThread implements Runnable {
private final Log LOG = LogFactory.getLog(AbstractAtomHopperThread.class);
private Configuration configuration = new AtomHopperConfiguration();
protected List<Usage> usages;
protected AtomHopperClient client;
protected IdentityAuthClient identityAuthClient;
protected AlertRepository alertRepository;
protected LoadBalancerEventRepository loadBalancerEventRepository;
protected List<Usage> failedRecords;
public abstract String getThreadName();
public abstract Map<Object, Object> generateAtomHopperEntry(Usage usage) throws AtomHopperMappingException;
public abstract void updatePushedRecords(List<Usage> successfullyPushedRecordIds);
public AbstractAtomHopperThread(List<Usage> usages, AtomHopperClient client, IdentityAuthClient identityAuthClient,
LoadBalancerEventRepository loadBalancerEventRepository,
AlertRepository alertRepository) {
this.usages = usages;
this.client = client;
this.identityAuthClient = identityAuthClient;
this.loadBalancerEventRepository = loadBalancerEventRepository;
this.alertRepository = alertRepository;
}
@Override
public void run() {
Calendar startTime = AtomHopperUtil.getNow();
LOG.info(String.format("Load Balancer Atom Hopper USL Task Started at %s (Timezone: %s)",
startTime.getTime().toString(), startTime.getTimeZone().getDisplayName()));
AHRecordHelper ahelper = null;
try {
String authToken = identityAuthClient.getAuthToken();
ahelper = new AHRecordHelper(configuration.getString(AtomHopperConfigurationKeys
.ahusl_log_requests).equals("ENABLED"), client,
loadBalancerEventRepository, alertRepository);
for (Usage usageRecord : usages) {
Map<Object, Object> entryMap = generateAtomHopperEntry(usageRecord);
failedRecords = ahelper.handleUsageRecord(usageRecord, authToken, entryMap);
}
LOG.info(String.format("Batch updating: %d " +
"Atom Hopper usage entries in the database...", usages.size()));
updatePushedRecords(usages);
LOG.info(String.format("Successfully batch updated: %d " +
"Atom Hopper entries in the database...", usages.size()));
} catch (ConcurrentModificationException cme) {
System.out.printf("Exception: %s\n", getExtendedStackTrace(cme));
LOG.warn(String.format("Warning: %s\n", getExtendedStackTrace(cme)));
LOG.warn(String.format("Job attempted to access usage already being processed, " +
"continue processing next data set..."));
} catch (Throwable t) {
LOG.error(String.format("Exception during Atom-Hopper processing: %s\n", getExtendedStackTrace(t)));
ahelper.generateSevereAlert("Severe Failure processing Atom Hopper requests: ", getExtendedStackTrace(t));
}
Double elapsedMins = ((AtomHopperUtil.getNow()
.getTimeInMillis() - startTime.getTimeInMillis()) / 1000.0) / 60.0;
LOG.info(String.format("Load Balancer Atom Hopper USL Task: %s Completed at '%s' (Total Time: %f mins)",
getThreadName(), AtomHopperUtil.getNow().getTime().toString(), elapsedMins));
LOG.debug(String.format("Load Balancer Atom Hopper USL Task: %s Failed tasks count: %d out of %d",
getThreadName(), failedRecords.size(), usages.size()));
}
}