/*************************************************************************** * Copyright (c) 2012-2014 VMware, Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ package com.vmware.bdd.service.impl; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import org.apache.log4j.Logger; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.vmware.bdd.entity.ClusterEntity; import com.vmware.bdd.manager.SoftwareManagerCollector; import com.vmware.bdd.manager.intf.IExclusiveLockedClusterEntityManager; import com.vmware.bdd.manager.intf.ILockedClusterEntityManager; import com.vmware.bdd.service.ISoftwareSyncUpService; import com.vmware.bdd.software.mgmt.plugin.intf.SoftwareManager; import com.vmware.bdd.software.mgmt.plugin.model.ClusterBlueprint; import com.vmware.bdd.software.mgmt.plugin.monitor.ClusterReport; @Service public class SoftwareSyncupService implements ISoftwareSyncUpService, InitializingBean { private static final int SYNCUP_INTERVAL_MILLISECONDS = 300000; // every 5 minutes private static final Logger logger = Logger .getLogger(SoftwareSyncupService.class); private static final int MAX_QUEUE_SIZE = 1000; private static final String SERVICE_SYNCUP_THREAD_NAME = "ServiceSyncup"; private SoftwareManagerCollector softwareManagerCollector; private IExclusiveLockedClusterEntityManager lockedEntityManager; private BlockingQueue<String> requestQueue = new ArrayBlockingQueue<String>( MAX_QUEUE_SIZE); private Timer syncupTimer; public SoftwareManagerCollector getSoftwareManagerCollector() { return softwareManagerCollector; } @Autowired public void setSoftwareManagerCollector( SoftwareManagerCollector softwareManagerCollector) { this.softwareManagerCollector = softwareManagerCollector; } public IExclusiveLockedClusterEntityManager getLockedEntityManager() { return lockedEntityManager; } @Autowired public void setLockedEntityManager( IExclusiveLockedClusterEntityManager lockedEntityManager) { this.lockedEntityManager = lockedEntityManager; } @Override public void afterPropertiesSet() throws Exception { List<ClusterEntity> clusters = lockedEntityManager.getClusterEntityMgr().findAllClusters(); for (ClusterEntity cluster : clusters) { requestQueue.add(cluster.getName()); logger.info("Start service sync up for cluster " + cluster.getName()); } syncupTimer = new Timer(SERVICE_SYNCUP_THREAD_NAME, true); StatusSyncUpTask task = new StatusSyncUpTask(lockedEntityManager, softwareManagerCollector, requestQueue); syncupTimer.scheduleAtFixedRate(task, new Date(), SYNCUP_INTERVAL_MILLISECONDS); } @Override public void syncUp(String clusterName) { requestQueue.add(clusterName); } @Override public void syncUpOnce(String clusterName) { // TODO Auto-generated method stub } private static class StatusSyncUpTask extends TimerTask { private ILockedClusterEntityManager lockedEntityManager; private SoftwareManagerCollector softwareManagerCollector; private BlockingQueue<String> requestQueue; public StatusSyncUpTask(ILockedClusterEntityManager lockedEntityManager, SoftwareManagerCollector softwareManagerCollector, BlockingQueue<String> requestQueue) { this.lockedEntityManager = lockedEntityManager; this.softwareManagerCollector = softwareManagerCollector; this.requestQueue = requestQueue; } @Override public void run() { // using set to remove duplicate Set<String> clusterList = new HashSet<String>(); requestQueue.drainTo(clusterList); if (clusterList.isEmpty()) { logger.debug("No cluster need to be sync up for service status."); return; } for (Iterator<String> ite = clusterList.iterator(); ite.hasNext(); ) { String clusterName = ite.next(); try { ClusterEntity cluster = lockedEntityManager.getClusterEntityMgr().findByName( clusterName); if (cluster == null) { logger.info("Cluster " + clusterName + " does not exist, stop sync up for it."); ite.remove(); continue; } if (!cluster.getStatus().isSyncServiceStatus()) { logger.debug("Cluster " + clusterName + " is in status " + cluster.getStatus()); logger.debug("Stop sync up for it"); ite.remove(); continue; } ClusterBlueprint blueprint = lockedEntityManager.getClusterEntityMgr() .toClusterBluePrint(clusterName); SoftwareManager softMgr = softwareManagerCollector .getSoftwareManagerByClusterName(clusterName); if (softMgr == null) { logger.error("No software manager for cluster " + clusterName + " available."); continue; } ClusterReport report = softMgr.queryClusterStatus(blueprint); if (report == null) { logger.debug("No service status got from software manager, ignore it."); continue; } logger.debug("Got cluster status: " + report.getStatus()); lockedEntityManager.getClusterEntityMgr().setClusterStatus( clusterName, report); } catch (Throwable e) { logger.error("Failed to syncup status for cluster " + clusterName + ". Error message: " + e.getMessage(), e); } } //add back all clusters for next time sync up. requestQueue.addAll(clusterList); logger.debug("queued cluster names: " + requestQueue); } } }