use of org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore in project cloudstack by apache.
the class DataObjectManagerImpl method createAsync.
@Override
public void createAsync(DataObject data, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback, boolean noCopy) {
DataObjectInStore obj = objectInDataStoreMgr.findObject(data, store);
DataObject objInStore = null;
boolean freshNewTemplate = false;
if (obj == null) {
try {
objInStore = objectInDataStoreMgr.create(data, store);
freshNewTemplate = true;
} catch (Throwable e) {
obj = objectInDataStoreMgr.findObject(data, store);
if (obj == null) {
CreateCmdResult result = new CreateCmdResult(null, null);
result.setSuccess(false);
result.setResult(e.toString());
callback.complete(result);
return;
}
}
}
if (!freshNewTemplate && obj.getState() != ObjectInDataStoreStateMachine.State.Ready) {
try {
objInStore = waitingForCreated(data, store);
} catch (Exception e) {
CreateCmdResult result = new CreateCmdResult(null, null);
result.setSuccess(false);
result.setResult(e.toString());
callback.complete(result);
return;
}
CreateCmdResult result = new CreateCmdResult(null, null);
callback.complete(result);
return;
}
try {
ObjectInDataStoreStateMachine.Event event = null;
if (noCopy) {
event = ObjectInDataStoreStateMachine.Event.CreateOnlyRequested;
} else {
event = ObjectInDataStoreStateMachine.Event.CreateRequested;
}
objectInDataStoreMgr.update(objInStore, event);
} catch (NoTransitionException e) {
try {
objectInDataStoreMgr.update(objInStore, ObjectInDataStoreStateMachine.Event.OperationFailed);
} catch (Exception e1) {
s_logger.debug("state transation failed", e1);
}
CreateCmdResult result = new CreateCmdResult(null, null);
result.setSuccess(false);
result.setResult(e.toString());
callback.complete(result);
return;
} catch (ConcurrentOperationException e) {
try {
objectInDataStoreMgr.update(objInStore, ObjectInDataStoreStateMachine.Event.OperationFailed);
} catch (Exception e1) {
s_logger.debug("state transation failed", e1);
}
CreateCmdResult result = new CreateCmdResult(null, null);
result.setSuccess(false);
result.setResult(e.toString());
callback.complete(result);
return;
}
CreateContext<CreateCmdResult> context = new CreateContext<CreateCmdResult>(callback, objInStore);
AsyncCallbackDispatcher<DataObjectManagerImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().createAsynCallback(null, null)).setContext(context);
store.getDriver().createAsync(store, objInStore, caller);
return;
}
use of org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore in project cloudstack by apache.
the class DataObjectManagerImpl method waitingForCreated.
protected DataObject waitingForCreated(DataObject dataObj, DataStore dataStore) {
long retries = this.waitingRetries;
DataObjectInStore obj = null;
do {
try {
Thread.sleep(waitingTime);
} catch (InterruptedException e) {
s_logger.debug("sleep interrupted", e);
throw new CloudRuntimeException("sleep interrupted", e);
}
obj = objectInDataStoreMgr.findObject(dataObj, dataStore);
if (obj == null) {
s_logger.debug("can't find object in db, maybe it's cleaned up already, exit waiting");
break;
}
if (obj.getState() == ObjectInDataStoreStateMachine.State.Ready) {
break;
}
retries--;
} while (retries > 0);
if (obj == null || retries <= 0) {
s_logger.debug("waiting too long for template downloading, marked it as failed");
throw new CloudRuntimeException("waiting too long for template downloading, marked it as failed");
}
return objectInDataStoreMgr.get(dataObj, dataStore, null);
}
use of org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore in project cloudstack by apache.
the class DataObjectManagerImpl method createInternalStateOnly.
@Override
public DataObject createInternalStateOnly(DataObject data, DataStore store) {
DataObjectInStore obj = objectInDataStoreMgr.findObject(data, store);
DataObject objInStore = null;
if (obj == null) {
objInStore = objectInDataStoreMgr.create(data, store);
}
try {
ObjectInDataStoreStateMachine.Event event = null;
event = ObjectInDataStoreStateMachine.Event.CreateRequested;
objectInDataStoreMgr.update(objInStore, event);
objectInDataStoreMgr.update(objInStore, ObjectInDataStoreStateMachine.Event.OperationSuccessed);
} catch (NoTransitionException e) {
s_logger.debug("Failed to update state", e);
throw new CloudRuntimeException("Failed to update state", e);
} catch (ConcurrentOperationException e) {
s_logger.debug("Failed to update state", e);
throw new CloudRuntimeException("Failed to update state", e);
}
return objInStore;
}
use of org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore in project cloudstack by apache.
the class ObjectInDataStoreManagerImpl method update.
@Override
public boolean update(DataObject data, Event event) throws NoTransitionException, ConcurrentOperationException {
DataObjectInStore obj = this.findObject(data, data.getDataStore());
if (obj == null) {
throw new CloudRuntimeException("can't find mapping in ObjectInDataStore table for: " + data);
}
boolean result = true;
if (data.getDataStore().getRole() == DataStoreRole.Image || data.getDataStore().getRole() == DataStoreRole.ImageCache) {
switch(data.getType()) {
case TEMPLATE:
result = this.stateMachines.transitTo(obj, event, null, templateDataStoreDao);
break;
case SNAPSHOT:
result = this.stateMachines.transitTo(obj, event, null, snapshotDataStoreDao);
break;
case VOLUME:
result = this.stateMachines.transitTo(obj, event, null, volumeDataStoreDao);
break;
}
} else if (data.getType() == DataObjectType.TEMPLATE && data.getDataStore().getRole() == DataStoreRole.Primary) {
result = this.stateMachines.transitTo(obj, event, null, templatePoolDao);
} else if (data.getType() == DataObjectType.SNAPSHOT && data.getDataStore().getRole() == DataStoreRole.Primary) {
result = this.stateMachines.transitTo(obj, event, null, snapshotDataStoreDao);
} else {
throw new CloudRuntimeException("Invalid data or store type: " + data.getType() + " " + data.getDataStore().getRole());
}
if (!result) {
throw new ConcurrentOperationException("Multiple threads are trying to update data object state, racing condition");
}
return true;
}
use of org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore in project cloudstack by apache.
the class StorageCacheManagerImpl method createCacheObject.
@Override
public DataObject createCacheObject(DataObject data, DataStore store) {
DataObject objOnCacheStore = null;
final Object lock;
final DataObjectType type = data.getType();
final String typeName;
final long storeId = store.getId();
final long dataId = data.getId();
/*
* Make sure any thread knows own lock type.
*/
if (type == DataObjectType.TEMPLATE) {
lock = templateLock;
typeName = "template";
} else if (type == DataObjectType.VOLUME) {
lock = volumeLock;
typeName = "volume";
} else if (type == DataObjectType.SNAPSHOT) {
lock = snapshotLock;
typeName = "snapshot";
} else {
String msg = "unsupported DataObject comes, then can't acquire correct lock object";
throw new CloudRuntimeException(msg);
}
s_logger.debug("check " + typeName + " cache entry(id: " + dataId + ") on store(id: " + storeId + ")");
DataObject existingDataObj = null;
synchronized (lock) {
DataObjectInStore obj = objectInStoreMgr.findObject(data, store);
if (obj != null) {
State st = obj.getState();
long miliSeconds = 10000;
long timeoutSeconds = 3600;
long timeoutMiliSeconds = timeoutSeconds * 1000;
Date now = new Date();
long expiredEpoch = now.getTime() + timeoutMiliSeconds;
Date expiredDate = new Date(expiredEpoch);
/*
* Waiting for completion of cache copy.
*/
while (st == ObjectInDataStoreStateMachine.State.Allocated || st == ObjectInDataStoreStateMachine.State.Creating || st == ObjectInDataStoreStateMachine.State.Copying) {
/*
* Threads must release lock within waiting for cache copy and
* must be waken up at completion.
*/
s_logger.debug("waiting cache copy completion type: " + typeName + ", id: " + obj.getObjectId() + ", lock: " + lock.hashCode());
try {
lock.wait(miliSeconds);
} catch (InterruptedException e) {
s_logger.debug("[ignored] interupted while waiting for cache copy completion.");
}
s_logger.debug("waken up");
now = new Date();
if (now.after(expiredDate)) {
String msg = "Waiting time exceeds timeout limit(" + timeoutSeconds + " s)";
throw new CloudRuntimeException(msg);
}
obj = objectInStoreMgr.findObject(data, store);
st = obj.getState();
}
if (st == ObjectInDataStoreStateMachine.State.Ready) {
s_logger.debug("there is already one in the cache store");
DataObject dataObj = objectInStoreMgr.get(data, store, null);
dataObj.incRefCount();
existingDataObj = dataObj;
}
}
if (existingDataObj == null) {
s_logger.debug("create " + typeName + " cache entry(id: " + dataId + ") on store(id: " + storeId + ")");
objOnCacheStore = store.create(data);
}
lock.notifyAll();
}
if (existingDataObj != null) {
return existingDataObj;
}
if (objOnCacheStore == null) {
s_logger.error("create " + typeName + " cache entry(id: " + dataId + ") on store(id: " + storeId + ") failed");
return null;
}
AsyncCallFuture<CopyCommandResult> future = new AsyncCallFuture<CopyCommandResult>();
CopyCommandResult result = null;
try {
objOnCacheStore.processEvent(Event.CreateOnlyRequested);
dataMotionSvr.copyAsync(data, objOnCacheStore, future);
result = future.get();
if (result.isFailed()) {
objOnCacheStore.processEvent(Event.OperationFailed);
} else {
objOnCacheStore.processEvent(Event.OperationSuccessed, result.getAnswer());
objOnCacheStore.incRefCount();
return objOnCacheStore;
}
} catch (InterruptedException e) {
s_logger.debug("create cache storage failed: " + e.toString());
throw new CloudRuntimeException(e);
} catch (ExecutionException e) {
s_logger.debug("create cache storage failed: " + e.toString());
throw new CloudRuntimeException(e);
} finally {
if (result == null) {
objOnCacheStore.processEvent(Event.OperationFailed);
}
synchronized (lock) {
/*
* Wake up all threads waiting for cache copy.
*/
s_logger.debug("wake up all waiting threads(lock: " + lock.hashCode() + ")");
lock.notifyAll();
}
}
return null;
}
Aggregations