package eu.europeana.cloud.service.coordination.provider; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Random; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import eu.europeana.cloud.service.coordination.ServiceProperties; import eu.europeana.cloud.service.coordination.discovery.EcloudServiceDiscovery; /** * Returns random service instances from the list of all available services, * but will always prefer services from {@link #preferredDatacenter} if possible. * * @author emmanouil.koufakis@theeuropeanlibrary.org * */ public class ServiceProviderImpl implements ServiceProvider { /** Used to discover a list of all available services */ private EcloudServiceDiscovery serviceDiscovery; /** This service provider will always prefer service instances located in the preferredDatacenter */ private final String preferredDatacenter; /** In case many services are found, one will randomly be selected */ private final Random random = new Random(); /** Logging */ private static final Logger LOGGER = LoggerFactory.getLogger(ServiceProviderImpl.class); public ServiceProviderImpl(final EcloudServiceDiscovery serviceDiscovery, final String preferredDatacenter) { LOGGER.info("Starting ServiceProviderImpl..."); this.serviceDiscovery = serviceDiscovery; this.preferredDatacenter = preferredDatacenter; LOGGER.info("ServiceProviderImpl started succesfully."); } @Override public ServiceProperties getService() { List<ServiceProperties> services = serviceDiscovery.getServices(); return getRandomLocalService(services, preferredDatacenter); } /** * @return A random service from the specified preferredDatacenter (if possible), * otherwise a random service from allServices. */ private ServiceProperties getRandomLocalService(final List<ServiceProperties> allServices, final String preferredDatacenter) { final int allServicesSize = allServices.size(); if (allServicesSize == 0) { LOGGER.warn("getRandomLocalService() no service found!"); return null; } final List<ServiceProperties> localServices = new ArrayList<ServiceProperties>(); final Iterator<ServiceProperties> i = allServices.iterator(); while (i.hasNext()) { final ServiceProperties currentService = i.next(); if (currentService.getDatacenterLocation().equals(preferredDatacenter)) { localServices.add(currentService); } } final int localServicesSize = localServices.size(); if (localServicesSize == 0) { final int randomIndex = random.nextInt(allServicesSize); LOGGER.info("getRandomLocalService() no service available from datacenter={}", preferredDatacenter); allServices.get(randomIndex); } final int randomIndex = random.nextInt(localServicesSize); return localServices.get(randomIndex); } }