package cz.cuni.mff.d3s.been.swrepository; import static cz.cuni.mff.d3s.been.swrepository.SWRepositoryServiceInfoConstants.*; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import cz.cuni.mff.d3s.been.cluster.*; import cz.cuni.mff.d3s.been.cluster.context.ClusterContext; import cz.cuni.mff.d3s.been.core.service.ServiceInfo; import cz.cuni.mff.d3s.been.core.service.ServiceState; import cz.cuni.mff.d3s.been.datastore.SoftwareStore; import cz.cuni.mff.d3s.been.swrepository.httpserver.HttpServer; /** * A cluster node that can store and provide BPKs and Maven artifacts through a * simple HTTP server. * * @author darklight */ public class SoftwareRepository implements IClusterService { private static final Logger log = LoggerFactory.getLogger(SoftwareRepository.class); private final String beenId; private HttpServer httpServer; private SoftwareStore softwareStore; private ServiceInfo info; private final ClusterContext clusterCtx; SoftwareRepository(ClusterContext clusterCtx, String beenId) { this.clusterCtx = clusterCtx; this.beenId = beenId; } /** * Initialize the repository. HTTP server and data store must be set. */ public void init() { BpkRequestHandler bpkRequestHandler = new BpkRequestHandler(softwareStore); httpServer.getResolver().register(UrlPaths.BPK_LIST_URI, bpkRequestHandler); httpServer.getResolver().register(UrlPaths.BPK_URI, bpkRequestHandler); httpServer.getResolver().register(UrlPaths.TASK_DESCRIPTOR_LIST_URI, bpkRequestHandler); httpServer.getResolver().register(UrlPaths.TASK_CONTEXT_DESCRIPTOR_LIST_URI, bpkRequestHandler); httpServer.getResolver().register(UrlPaths.ARTIFACT_URI, new ArtifactRequestHandler(softwareStore)); } @Override public void start() throws ServiceException { log.info("Starting Software Repository..."); if (httpServer == null) { log.error("Cannot start Software Repository - HTTP server is null."); return; } if (softwareStore == null) { log.error("Cannot start Software Repository - Software Store is null."); return; } info = new ServiceInfo(SERVICE_NAME, beenId); final String hostName = httpServer.getHost().getHostAddress(); final int port = httpServer.getPort(); info.setParam(PARAM_HOST_NAME, hostName); info.setParam(PARAM_PORT, port); info.setServiceInfo(hostName + ":" + port); info.setServiceState(ServiceState.OK); info.setHazelcastUuid(clusterCtx.getInstanceType() != NodeType.NATIVE ? clusterCtx.getCluster().getLocalMember().getUuid() : null); httpServer.start(); int period = 30; int timeout = 45; Runnable serviceInfoUpdater = new ServiceInfoUpdater(clusterCtx, info, timeout); clusterCtx.schedule(serviceInfoUpdater, 0, period, TimeUnit.SECONDS); log.info("Software Repository started."); } @Override public void stop() { log.info("Stopping Software repository..."); try { clusterCtx.removeServiceInfo(info); } catch (IllegalStateException e) { // unregistering over a Hazelcast instance that is no longer active log.warn("Failed to unhook SoftwareRepository from the cluster. SoftwareRepository info is likely to linger.", e); } httpServer.stop(); log.info("Software repository stopped."); clusterCtx.stop(); } @Override public Reaper createReaper() { return new Reaper() { @Override protected void reap() throws InterruptedException { SoftwareRepository.this.stop(); } }; } /** * Set the HTTP server * * @param httpServer * HTTP server to set */ public void setHttpServer(HttpServer httpServer) { this.httpServer = httpServer; } /** * Set the persistence layer * * @param softwareStore * Data store to set */ public void setDataStore(SoftwareStore softwareStore) { this.softwareStore = softwareStore; } }