/***************************************************************************
* Copyright (c) 2013 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.vhadoop.vhm;
import java.util.Set;
import java.util.logging.Logger;
import com.vmware.vhadoop.api.vhm.ClusterMap;
import com.vmware.vhadoop.api.vhm.ClusterMapReader;
import com.vmware.vhadoop.util.CompoundStatus;
import com.vmware.vhadoop.util.ThreadLocalCompoundStatus;
public abstract class AbstractClusterMapReader implements ClusterMapReader {
private static final Logger _log = Logger.getLogger(AbstractClusterMapReader.class.getName());
ClusterMapAccess _clusterMapAccess;
private ThreadLocalCompoundStatus _threadLocalStatus;
private boolean _initialized;
/* To be used purely to allow the parent to initialize these values */
protected AbstractClusterMapReader(ClusterMapAccess clusterMapAccess, ThreadLocalCompoundStatus tlcs) {
_clusterMapAccess = clusterMapAccess;
_threadLocalStatus = tlcs;
_initialized = true;
}
public AbstractClusterMapReader() {
_initialized = false;
}
protected CompoundStatus getCompoundStatus() {
if (_threadLocalStatus == null) {
return new CompoundStatus("DUMMY_STATUS");
}
return _threadLocalStatus.get();
}
/* Any subclass wishing to add status to this thread's execution should call this method */
protected ThreadLocalCompoundStatus getThreadLocalCompoundStatus() {
return _threadLocalStatus;
}
@Override
public void initialize(final ClusterMapReader parent) {
if (parent instanceof AbstractClusterMapReader) {
_clusterMapAccess = ((AbstractClusterMapReader)parent)._clusterMapAccess;
_threadLocalStatus = ((AbstractClusterMapReader)parent)._threadLocalStatus;
_initialized = true;
} else {
_log.severe("Unrecognized ClusterMapReader implementation");
}
}
private boolean checkInitialized() {
if (!_initialized) {
_log.severe("Method invocation failed due to uninitialized ClusterMapReader");
}
return _initialized;
}
@Override
/* Gets a read lock on ClusterMap - call unlock when done */
public ClusterMap getAndReadLockClusterMap() {
ClusterMap result = null;
if (checkInitialized()) {
result = _clusterMapAccess.lockClusterMap();
}
return (result != null) ? result : new NullClusterMap();
}
@Override
public void unlockClusterMap(final ClusterMap clusterMap) {
if (clusterMap instanceof NullClusterMap) {
return;
}
_clusterMapAccess.unlockClusterMap(clusterMap);
}
public void blockOnPowerStateChange(final Set<String> vmIds, final boolean expectedPowerState, final long timeout) {
CompoundStatus status = new CompoundStatus(POWER_STATE_CHANGE_STATUS_KEY);
long timeoutTime = System.currentTimeMillis() + timeout;
long pollSleepTime = 500;
boolean timedOut = false;
ClusterMap clusterMap = null;
if (vmIds == null || vmIds.isEmpty()) {
return;
}
do {
boolean completed = true;
try {
clusterMap = getAndReadLockClusterMap(); /* Initialization check here */
for (String vmId : vmIds) {
Boolean result = clusterMap.checkPowerStateOfVm(vmId, expectedPowerState);
if (result == null) {
_log.fine("checkPowerState cannot find VM <%V"+vmId);
} else if (!result) {
completed = false;
break;
}
}
} finally {
unlockClusterMap(clusterMap);
}
if (completed) {
status.registerTaskSucceeded();
break;
}
try {
Thread.sleep(Math.min(pollSleepTime, timeout));
} catch (InterruptedException e) {
status.registerTaskIncomplete(false, "blockOnPowerStateChange was interrupted unexpectedly");
}
timedOut = System.currentTimeMillis() > timeoutTime;
} while (!timedOut);
if (timedOut) {
status.registerTaskFailed(false, "Timeout waiting for powerStateChange");
}
getCompoundStatus().addStatus(status);
}
public String getMasterVmIdForCluster(String clusterId) {
ClusterMap clusterMap = null;
try {
clusterMap = getAndReadLockClusterMap(); /* Initialization check here */
return clusterMap.getMasterVmIdForCluster(clusterId);
} finally {
unlockClusterMap(clusterMap);
}
}
}