package org.fluxtream.core.updaters.quartz;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.fluxtream.core.Configuration;
import org.fluxtream.core.aspects.FlxLogger;
import org.fluxtream.core.auth.FlxUserDetails;
import org.fluxtream.core.domain.Guest;
import org.fluxtream.core.services.ConnectorUpdateService;
import org.fluxtream.core.services.GuestService;
import org.fluxtream.core.utils.Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
/**
* This class' scheduleIncrementalUpdates is meant to be call at regular intervals by
* a quartz trigger (see spring-quartz.xml)
*/
public class Producer {
FlxLogger logger = FlxLogger.getLogger(Producer.class);
@Autowired
private ConnectorUpdateService connectorUpdateService;
@Autowired
private GuestService guestService;
@Autowired
private Configuration env;
private boolean contextStarted = false;
public void setContextStarted() {
contextStarted = true;
}
/**
* bluntly go through the list of all guests and attempt to update all of their connectors
* spacing them evenly around 3/4 of producer.trigger.repeatInterval so they don't all happen at once.
* The reason to use only 3/4 of the producer.trigger.repeatInterval is to allow the later users' connectors
* some time to complete before the next time scheduleIncrementalUpdates is called.
*/
public void scheduleIncrementalUpdates() throws InterruptedException {
while (!contextStarted) {
Thread.sleep(1000);
System.out.println("Context not started, delaying queue consumption...");
}
logger.debug("module=updateQueue component=producer action=scheduleIncrementalUpdates");
List<String> roles = new ArrayList<String>();
roles.add("ROLE_ADMIN");
roles.add("ROLE_ROOT");
as(roles);
try {
List<Guest> guests = guestService.getAllGuests();
// Prepare to calculate when to start the connector updates for each guest.
// updateTimespan is the span of time over which to space the guests' updates
// guestUpdateSpacing is updateTimespan/# guests, for how much to increment the
// time for each guest
// nextUpdateTime is the time to update the next guest. It starts at now,
// and is incremented for each guest
String producerRepeatInterval = env.get("producer.trigger.repeatInterval");
long updateTimespan = (producerRepeatInterval!=null)?((long)(Double.valueOf(producerRepeatInterval)*0.75)):0;
long guestUpdateSpacing = (guests.size()>0)?(updateTimespan/guests.size()):0;
long nextUpdateTime = System.currentTimeMillis();
for (Guest g : guests) {
connectorUpdateService.updateAllConnectors(g.getId(), false, nextUpdateTime);
nextUpdateTime += guestUpdateSpacing;
}
}
catch (Exception e) {
String stackTrace = Utils.stackTrace(e);
logger.error("module=updateQueue component=producer message=Could not update all connectors stackTrace=" + stackTrace);
}
}
private static void as(final List<String> roles) {
@SuppressWarnings("serial") Authentication auth = new Authentication() {
@Override
public String getName() {
return null;
}
@Override
public void setAuthenticated(boolean isAuthenticated)
throws IllegalArgumentException {
}
@Override
public boolean isAuthenticated() {
return true;
}
@Override
public Object getPrincipal() {
Guest guest = new Guest();
return new FlxUserDetails(guest);
}
@Override
public Object getDetails() {
return null;
}
@Override
public Object getCredentials() {
return null;
}
@Override
public Collection<GrantedAuthority> getAuthorities() {
List<GrantedAuthority> l = new ArrayList<GrantedAuthority>();
for (String role : roles) l.add(new SimpleGrantedAuthority(role));
return l;
}
};
SecurityContextHolder.getContext().setAuthentication(auth);
}
}