/******************************************************************************* * Copyright (c) 2011 GigaSpaces Technologies Ltd. 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 org.cloudifysource.esc.driver.provisioning.storage; import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; import org.cloudifysource.domain.cloud.storage.StorageTemplate; import org.cloudifysource.domain.context.blockstorage.RemoteStorageOperationException; import org.cloudifysource.dsl.internal.context.RemoteStorageProvisioningDriver; /** * * @author elip * */ public class RemoteStorageProvisioningDriverAdapter implements RemoteStorageProvisioningDriver { private Logger logger = java.util.logging.Logger .getLogger(RemoteStorageProvisioningDriverAdapter.class.getName()); private static final long DEFAULT_STORAGE_OPERATION_TIMEOUT = 60 * 1000; private StorageProvisioningDriver storageProvisioningDriver; private StorageTemplate storageTemplate; public RemoteStorageProvisioningDriverAdapter(final StorageProvisioningDriver driver, final StorageTemplate storageTemplate) { this.storageProvisioningDriver = driver; this.storageTemplate = storageTemplate; } @Override public void attachVolume(final String volumeId, final String device, final String ip) throws RemoteStorageOperationException { try { storageProvisioningDriver .attachVolume(volumeId, device, ip, DEFAULT_STORAGE_OPERATION_TIMEOUT, TimeUnit.MILLISECONDS); } catch (final Exception e) { logSevereAndThrow("Failed attaching volume with id " + volumeId + " to instance with ip " + ip + " : " + e.getMessage(), e); } } @Override public String createVolume(final String templateName, final String locationId) throws RemoteStorageOperationException, TimeoutException { return createVolume(templateName, locationId, DEFAULT_STORAGE_OPERATION_TIMEOUT); } @Override public String createVolume(final String templateName, final String locationId, final long timeoutInMillis) throws RemoteStorageOperationException, TimeoutException { String volumeId = "-1"; try { VolumeDetails volumeDetails = storageProvisioningDriver .createVolume(templateName, locationId, timeoutInMillis, TimeUnit.MILLISECONDS); volumeId = volumeDetails.getId(); } catch (final Exception e) { logSevereAndThrow("Failed creating volume in location " + locationId + " : " + e.getMessage(), e); } return volumeId; } @Override public void detachVolume(final String volumeId, final String ip) throws RemoteStorageOperationException { try { storageProvisioningDriver .detachVolume(volumeId, ip, DEFAULT_STORAGE_OPERATION_TIMEOUT * 2, TimeUnit.MILLISECONDS); } catch (final Exception e) { logSevereAndThrow("Failed detaching volume with id " + volumeId + " to instance with ip " + ip + ", reported error: " + e.getMessage(), e); } } @Override public void deleteVolume(final String location, final String volumeId) throws RemoteStorageOperationException { try { storageProvisioningDriver .deleteVolume(location, volumeId, DEFAULT_STORAGE_OPERATION_TIMEOUT, TimeUnit.MILLISECONDS); } catch (final Exception e) { logSevereAndThrow("Failed deleting volume with id " + volumeId + ", reported error: " + e.getMessage(), e); } } @Override public StorageTemplate getTemplate(final String templateName) { return storageTemplate; } /** * Logs the exception as severe and throws a {@link RemoteStorageOperationException}. If the exception is * serializable it is included in the newly thrown exception. * @param message The error message to log * @param e The exception to log and re-throw if possible * @throws RemoteStorageOperationException */ private void logSevereAndThrow(final String message, final Exception e) throws RemoteStorageOperationException { logger.log(Level.SEVERE, message, e); if (isSerializable(e)) { throw new RemoteStorageOperationException(message, e); } else { throw new RemoteStorageOperationException(message); } } /** * Checks if the given object can be serialized. * @param obj The object to serialize * @return True is serialization was successful, False otherwise */ private boolean isSerializable(final Object obj) { boolean serializable = false; try { new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(obj); serializable = true; } catch (Exception e) { // failed to serialize } return serializable; } }