53
53
* SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
54
54
* IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA
55
55
* BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN
56
* THE REGENTS’ DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT
56
* THE REGENTS' DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT
57
57
* OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR
58
58
* WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH
59
59
* ANY SUCH LICENSES OR RIGHTS.
64
64
package com.eucalyptus.cluster.callback;
66
66
import org.apache.log4j.Logger;
67
import com.eucalyptus.cluster.VmInstance;
68
import com.eucalyptus.cluster.VmInstances;
67
import com.eucalyptus.entities.Entities;
68
import com.eucalyptus.util.Exceptions;
69
69
import com.eucalyptus.util.LogUtil;
70
import edu.ucsb.eucalyptus.msgs.AttachVolumeResponseType;
70
import com.eucalyptus.util.async.ConnectionException;
71
import com.eucalyptus.util.async.FailedRequestException;
72
import com.eucalyptus.util.async.MessageCallback;
73
import com.eucalyptus.vm.VmInstance;
74
import com.eucalyptus.vm.VmInstances;
75
import com.eucalyptus.vm.VmVolumeAttachment;
76
import com.eucalyptus.vm.VmVolumeAttachment.AttachmentState;
77
import com.google.common.base.Function;
71
78
import edu.ucsb.eucalyptus.msgs.AttachedVolume;
72
import edu.ucsb.eucalyptus.msgs.BaseMessage;
73
79
import edu.ucsb.eucalyptus.msgs.DetachVolumeResponseType;
74
80
import edu.ucsb.eucalyptus.msgs.DetachVolumeType;
76
public class VolumeDetachCallback extends QueuedEventCallback<DetachVolumeType,DetachVolumeResponseType> {
82
public class VolumeDetachCallback extends MessageCallback<DetachVolumeType,DetachVolumeResponseType> {
78
84
private static Logger LOG = Logger.getLogger( VolumeDetachCallback.class );
80
86
public VolumeDetachCallback( DetachVolumeType request ) {
81
this.setRequest( request );
85
public void prepare( DetachVolumeType msg ) throws Exception {
89
public void verify( DetachVolumeResponseType reply ) throws Exception {
90
if ( reply.get_return( ) ) {
91
VmInstance vm = VmInstances.getInstance( ).lookup( this.getRequest( ).getInstanceId( ) );
92
vm.getVolumes( ).remove( new AttachedVolume( this.getRequest( ).getVolumeId( ) ) );
88
final Function<String, VmInstance> removeVolAttachment = new Function<String, VmInstance>( ) {
89
public VmInstance apply( final String input ) {
90
String volumeId = VolumeDetachCallback.this.getRequest( ).getVolumeId( );
91
VmInstance vm = VmInstances.lookup( input );
92
VmVolumeAttachment volumeAttachment = vm.lookupVolumeAttachment( volumeId );
93
if ( !VmVolumeAttachment.AttachmentState.attached.equals( volumeAttachment.getAttachmentState( ) ) ) {
94
if ( VmVolumeAttachment.AttachmentState.detaching.equals( volumeAttachment.getAttachmentState( ) ) ) {
95
throw Exceptions.toUndeclared( "Failed to detach volume which is already detaching: " + volumeId );
96
} else if ( VmVolumeAttachment.AttachmentState.attaching.equals( volumeAttachment.getAttachmentState( ) ) ) {
97
throw Exceptions.toUndeclared( "Failed to detach volume which is currently attaching: " + volumeId );
99
throw Exceptions.toUndeclared( "Failed to detach volume which is not currently attached: " + volumeId );
102
vm.updateVolumeAttachment( volumeId, AttachmentState.detaching );
106
Entities.asTransaction( VmInstance.class, removeVolAttachment ).apply( this.getRequest( ).getInstanceId( ) );
110
public void fire( DetachVolumeResponseType reply ) {}
114
* @see com.eucalyptus.util.async.MessageCallback#fireException(java.lang.Throwable)
118
public void fireException( Throwable e ) {
119
if( e instanceof FailedRequestException ) {
120
LOG.debug( "Request failed: " + this.getRequest( ).toSimpleString( ) + " because of: " + e.getMessage( ) );
121
} else if( e instanceof ConnectionException ) {
97
public void fail( Throwable e ) {
98
LOG.debug( LogUtil.subheader( this.getRequest( ).toString( "eucalyptus_ucsb_edu" ) ) );
124
LOG.trace( this.getRequest( ).toString( "eucalyptus_ucsb_edu" ) );
125
final Function<String, VmInstance> failedVolDetach = new Function<String, VmInstance>( ) {
126
public VmInstance apply( final String input ) {
127
VmInstance vm = VmInstances.lookup( input );
128
vm.updateVolumeAttachment( VolumeDetachCallback.this.getRequest( ).getVolumeId( ), AttachmentState.attached );
132
Entities.asTransaction( VmInstance.class, failedVolDetach ).apply( this.getRequest( ).getInstanceId( ) );