/*************************************************************************
* Copyright 2009-2015 Eucalyptus Systems, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
* Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta
* CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need
* additional information or have any questions.
************************************************************************/
package com.eucalyptus.resources.client;
import java.util.NoSuchElementException;
import javax.annotation.Nullable;
import org.apache.log4j.Logger;
import com.eucalyptus.component.ComponentId;
import com.eucalyptus.util.Callback;
import com.eucalyptus.util.Exceptions;
import com.eucalyptus.util.async.AsyncExceptions;
import com.eucalyptus.util.async.CheckedListenableFuture;
import com.eucalyptus.util.async.Futures;
import com.google.common.base.Optional;
import edu.ucsb.eucalyptus.msgs.BaseMessage;
/**
* @author Sang-Min Park
*
*/
public abstract class EucalyptusClientTask<TM extends BaseMessage, TC extends ComponentId> {
private static final Logger LOG = Logger.getLogger(EucalyptusClientTask.class);
private String errorCode;
private String errorMessage;
protected EucalyptusClientTask( ) {
}
final CheckedListenableFuture<Boolean> dispatch(
final ClientContext<TM, TC> context) {
try {
final CheckedListenableFuture<Boolean> future = Futures
.newGenericeFuture();
dispatchInternal(context, new Callback.Checked<TM>() {
@Override
public void fireException(final Throwable throwable) {
boolean result = false;
try {
result = dispatchFailure(context, throwable);
} finally {
future.set( result );
}
}
@Override
public void fire(final TM response) {
try {
dispatchSuccess(context, response);
} finally {
future.set(true);
}
}
});
return future;
} catch (Exception e) {
LOG.error("Got error", e);
}
return Futures.predestinedFuture(false);
}
abstract void dispatchInternal(ClientContext<TM, TC> context,
Callback.Checked<TM> callback);
/**
* @return True if the failure was handled and should be treated as success.
*/
boolean dispatchFailure(ClientContext<TM, TC> context, Throwable throwable) {
final Optional<AsyncExceptions.AsyncWebServiceError> serviceErrorOption =
AsyncExceptions.asWebServiceError( throwable );
if ( serviceErrorOption.isPresent( ) ) {
errorCode = serviceErrorOption.get( ).getCode();
errorMessage = serviceErrorOption.get( ).getMessage();
return false;
}
final NoSuchElementException ex2 = Exceptions.findCause( throwable, NoSuchElementException.class );
if ( ex2 != null ) {
errorMessage = ex2.getMessage();
return false;
}
LOG.error("Eucalyptus client error", throwable);
return false;
}
@Nullable
String getErrorCode() {
return errorCode;
}
@Nullable
String getErrorMessage() {
return errorMessage;
}
abstract void dispatchSuccess(ClientContext<TM, TC> context, TM response);
}