/************************************************************************* * Copyright 2009-2016 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.imaging.service; import com.eucalyptus.auth.AuthContextSupplier; import java.net.InetSocketAddress; import java.util.NoSuchElementException; import com.eucalyptus.component.annotation.ComponentNamed; import com.eucalyptus.context.Context; import com.eucalyptus.component.Topology; import com.eucalyptus.context.Contexts; import com.eucalyptus.imaging.common.GetInstanceImportTaskType; import com.eucalyptus.imaging.common.ImagingMessage; import com.eucalyptus.imaging.common.PutInstanceImportTaskStatusType; import com.eucalyptus.imaging.common.backend.msgs.ImagingBackendMessage; import com.eucalyptus.imaging.common.ImagingBackend; import com.eucalyptus.util.EucalyptusCloudException; import com.eucalyptus.util.Exceptions; import com.eucalyptus.util.async.AsyncExceptions; import com.eucalyptus.util.async.AsyncRequests; import com.eucalyptus.util.async.FailedRequestException; import com.eucalyptus.ws.EucalyptusWebServiceException; import com.eucalyptus.ws.Role; import com.google.common.base.Optional; import edu.ucsb.eucalyptus.msgs.BaseMessage; import edu.ucsb.eucalyptus.msgs.BaseMessages; /** * */ @SuppressWarnings( "UnusedDeclaration" ) @ComponentNamed public class ImagingService { public ImagingMessage dispatchAction( final ImagingMessage request ) throws EucalyptusCloudException { // Authorization final Context ctx = Contexts.lookup( ); final AuthContextSupplier user = ctx.getAuthContext( ); // Dispatch try { final ImagingBackendMessage backendRequest = (ImagingBackendMessage) BaseMessages.deepCopy( request, getBackendMessageClass( request ) ); final InetSocketAddress remoteAddr = ( ( InetSocketAddress ) ctx.getChannel( ).getRemoteAddress( ) ); if (remoteAddr != null) { final String remoteHost = remoteAddr.getAddress( ).getHostAddress( ); if (request instanceof GetInstanceImportTaskType) { ((com.eucalyptus.imaging.common.backend.msgs.GetInstanceImportTaskType) backendRequest).setSourceIp(remoteHost); }else if (request instanceof PutInstanceImportTaskStatusType) { ((com.eucalyptus.imaging.common.backend.msgs.PutInstanceImportTaskStatusType) backendRequest).setSourceIp(remoteHost); } } final BaseMessage backendResponse = send( backendRequest ); final ImagingMessage response = (ImagingMessage) BaseMessages.deepCopy( backendResponse, request.getReply( ).getClass( ) ); response.setCorrelationId( request.getCorrelationId( ) ); return response; } catch ( Exception e ) { handleRemoteException( e ); Exceptions.findAndRethrow( e, EucalyptusWebServiceException.class, EucalyptusCloudException.class ); throw new EucalyptusCloudException( e ); } } private static Class getBackendMessageClass( final BaseMessage request ) throws ClassNotFoundException { return Class.forName( request.getClass( ).getName( ).replace( ".common.", ".common.backend.msgs." ) ); } private static BaseMessage send( final ImagingBackendMessage request ) throws Exception { try { return AsyncRequests.sendSyncWithCurrentIdentity( Topology.lookup( ImagingBackend.class ), (BaseMessage)request ); } catch ( NoSuchElementException e ) { throw new ImagingUnavailableException( "Service Unavailable" ); } catch ( final FailedRequestException e ) { if ( ((BaseMessage)request).getReply( ).getClass( ).isInstance( e.getRequest( ) ) ) { return e.getRequest( ); } throw e.getRequest( ) == null ? e : new ImagingException( "InternalError", Role.Receiver, "Internal error " + e.getRequest().getClass().getSimpleName() + ":false" ); } } @SuppressWarnings( "ThrowableResultOfMethodCallIgnored" ) private void handleRemoteException( final Exception e ) throws EucalyptusCloudException { final Optional<AsyncExceptions.AsyncWebServiceError> serviceErrorOption = AsyncExceptions.asWebServiceError( e ); if ( serviceErrorOption.isPresent( ) ) { final AsyncExceptions.AsyncWebServiceError serviceError = serviceErrorOption.get( ); final String code = serviceError.getCode( ); final String message = serviceError.getMessage( ); switch( serviceError.getHttpErrorCode( ) ) { case 400: throw new ImagingClientException( code, message ); case 403: throw new ImagingAuthorizationException( code, message ); case 409: throw new ImagingInvalidConfigurationException( code, message ); case 503: throw new ImagingUnavailableException( message ); default: throw new ImagingException( code, Role.Receiver, message ); } } } }