107
108
import com.eucalyptus.ws.MappingHttpResponse;
108
109
import com.eucalyptus.ws.binding.Binding;
109
110
import com.eucalyptus.ws.binding.BindingManager;
111
import com.eucalyptus.ws.util.WalrusBucketLogger;
110
112
import com.eucalyptus.ws.util.XMLParser;
111
113
import com.google.common.collect.Lists;
113
115
import edu.ucsb.eucalyptus.annotation.HttpEmbedded;
114
116
import edu.ucsb.eucalyptus.annotation.HttpParameterMapping;
117
import edu.ucsb.eucalyptus.cloud.BucketLogData;
115
118
import edu.ucsb.eucalyptus.msgs.AccessControlListType;
116
119
import edu.ucsb.eucalyptus.msgs.AccessControlPolicyType;
117
120
import edu.ucsb.eucalyptus.msgs.CanonicalUserType;
120
123
import edu.ucsb.eucalyptus.msgs.Grant;
121
124
import edu.ucsb.eucalyptus.msgs.Grantee;
122
125
import edu.ucsb.eucalyptus.msgs.Group;
126
import edu.ucsb.eucalyptus.msgs.LoggingEnabled;
123
127
import edu.ucsb.eucalyptus.msgs.MetaDataEntry;
128
import edu.ucsb.eucalyptus.msgs.TargetGrants;
124
129
import edu.ucsb.eucalyptus.msgs.WalrusDataGetRequestType;
125
130
import edu.ucsb.eucalyptus.msgs.WalrusDataRequestType;
131
import edu.ucsb.eucalyptus.msgs.WalrusRequestType;
126
132
import edu.ucsb.eucalyptus.util.WalrusDataMessage;
127
133
import edu.ucsb.eucalyptus.util.WalrusDataMessenger;
128
134
import groovy.lang.GroovyObject;
135
141
private static final String OBJECT = "object";
136
142
private static final Map<String, String> operationMap = populateOperationMap();
137
143
private static WalrusDataMessenger putMessenger;
138
private static WalrusDataMessenger getMessenger;
139
144
public static final int DATA_MESSAGE_SIZE = 102400;
141
private String randomKey;
146
private String randomKey;
142
147
private LinkedBlockingQueue<WalrusDataMessage> putQueue;
145
public void handleUpstream( final ChannelHandlerContext channelHandlerContext, final ChannelEvent channelEvent ) throws Exception {
146
LOG.trace( LogUtil.dumpObject( channelEvent ) );
147
if ( channelEvent instanceof MessageEvent ) {
148
final MessageEvent msgEvent = ( MessageEvent ) channelEvent;
150
this.incomingMessage( channelHandlerContext, msgEvent );
151
} catch ( Throwable e ) {
153
Channels.fireExceptionCaught( channelHandlerContext, e );
156
} else if (channelEvent.toString().contains("DISCONNECTED") ||
157
channelEvent.toString().contains("CLOSED")) {
158
if(key != null && randomKey != null) {
159
putMessenger.removeQueue(key, randomKey);
163
channelHandlerContext.sendUpstream( channelEvent );
150
public void handleUpstream( final ChannelHandlerContext channelHandlerContext, final ChannelEvent channelEvent ) throws Exception {
151
LOG.trace( LogUtil.dumpObject( channelEvent ) );
152
if ( channelEvent instanceof MessageEvent ) {
153
final MessageEvent msgEvent = ( MessageEvent ) channelEvent;
155
this.incomingMessage( channelHandlerContext, msgEvent );
156
} catch ( Throwable e ) {
158
Channels.fireExceptionCaught( channelHandlerContext, e );
161
} else if (channelEvent.toString().contains("DISCONNECTED") ||
162
channelEvent.toString().contains("CLOSED")) {
163
if(key != null && randomKey != null) {
164
putMessenger.removeQueue(key, randomKey);
168
channelHandlerContext.sendUpstream( channelEvent );
167
172
public void incomingMessage( ChannelHandlerContext ctx, MessageEvent event ) throws Exception {
270
275
String servicePath = httpRequest.getServicePath();
271
276
Map bindingArguments = new HashMap();
272
277
final String operationName = getOperation(httpRequest, bindingArguments);
274
278
if(operationName == null)
275
279
throw new InvalidOperationException("Could not determine operation name for " + servicePath);
288
292
//:: get the map of parameters to fields :://
289
293
fieldMap = this.buildFieldMap( targetType );
290
294
//:: get an instance of the message :://
291
eucaMsg = ( EucalyptusMessage ) targetType.newInstance();
295
eucaMsg = (EucalyptusMessage) targetType.newInstance();
293
297
catch ( Exception e )
295
299
throw new BindingException( "Failed to construct message of type " + operationName );
302
addLogData(eucaMsg, bindingArguments);
299
304
//TODO: Refactor this to be more general
300
305
List<String> failedMappings = populateObject( eucaMsg, fieldMap, params);
336
private void addLogData(EucalyptusMessage eucaMsg,
337
Map bindingArguments) {
338
if(eucaMsg instanceof WalrusRequestType) {
339
String operation = (String) bindingArguments.remove("Operation");
340
if(operation != null) {
341
WalrusRequestType request = (WalrusRequestType) eucaMsg;
342
BucketLogData logData = WalrusBucketLogger.getInstance().makeLogEntry(UUID.randomUUID().toString());
343
logData.setOperation("REST." + operation);
344
request.setLogData(logData);
331
349
private void setRequiredParams(final GroovyObject msg, User user) {
332
350
if(user != null) {
333
351
msg.setProperty("accessKeyID", user.getQueryId());
399
417
if(!target[0].equals("")) {
400
418
operationKey = BUCKET + verb;
401
419
operationParams.put("Bucket", target[0]);
420
operationParams.put("Operation", verb.toUpperCase() + "." + "BUCKET");
403
421
if(verb.equals(WalrusProperties.HTTPVerb.POST.toString())) {
404
422
//TODO: handle POST.
405
423
Map formFields = httpRequest.getFormFields();
443
461
operationParams.put(WalrusProperties.Headers.RandomKey.toString(), randomKey);
444
462
putQueue = getWriteMessenger().interruptAllAndGetQueue(key, randomKey);
445
463
handleFirstChunk(httpRequest, (ChannelBuffer)formFields.get(WalrusProperties.IGNORE_PREFIX + "FirstDataChunk"), contentLength);
464
} else if(WalrusProperties.HTTPVerb.PUT.toString().equals(verb) &&
465
params.containsKey(WalrusProperties.OperationParameter.logging.toString())) {
466
//read logging params
467
getTargetBucketParams(operationParams, httpRequest);
449
470
operationKey = SERVICE + verb;
460
481
operationParams.put("Bucket", target[0]);
461
482
operationParams.put("Key", objectKey);
483
operationParams.put("Operation", verb.toUpperCase() + "." + "OBJECT");
464
485
if(!params.containsKey(WalrusProperties.OperationParameter.acl.toString())) {
465
486
if (verb.equals(WalrusProperties.HTTPVerb.PUT.toString())) {
623
644
return operationName;
647
private void getTargetBucketParams(Map operationParams,
648
MappingHttpRequest httpRequest) throws BindingException {
649
String message = getMessageString(httpRequest);
650
if(message.length() > 0) {
652
XMLParser xmlParser = new XMLParser(message);
653
String targetBucket = xmlParser.getValue("//TargetBucket");
654
String targetPrefix = xmlParser.getValue("//TargetPrefix");
655
ArrayList<Grant> grants = new ArrayList<Grant>();
657
List<String> permissions = xmlParser.getValues("//TargetGrants/Grant/Permission");
658
if(permissions == null)
659
throw new BindingException("malformed access control list");
661
DTMNodeList grantees = xmlParser.getNodes("//TargetGrants/Grant/Grantee");
663
throw new BindingException("malformed access control list");
665
for(int i = 0 ; i < grantees.getLength() ; ++i) {
666
String id = xmlParser.getValue(grantees.item(i), "ID");
667
if(id.length() > 0) {
668
String canonicalUserName = xmlParser.getValue(grantees.item(i), "DisplayName");
669
Grant grant = new Grant();
670
Grantee grantee = new Grantee();
671
grantee.setCanonicalUser(new CanonicalUserType(id, canonicalUserName));
672
grant.setGrantee(grantee);
673
grant.setPermission(permissions.get(i));
676
String groupUri = xmlParser.getValue(grantees.item(i), "URI");
677
if(groupUri.length() == 0)
678
throw new BindingException("malformed access control list");
679
Grant grant = new Grant();
680
Grantee grantee = new Grantee();
681
grantee.setGroup(new Group(groupUri));
682
grant.setGrantee(grantee);
683
grant.setPermission(permissions.get(i));
687
TargetGrants targetGrants = new TargetGrants(grants);
688
LoggingEnabled loggingEnabled = new LoggingEnabled(targetBucket, targetPrefix, new TargetGrants(grants));
689
operationParams.put("LoggingEnabled", loggingEnabled);
690
} catch(Exception ex) {
692
throw new BindingException("Unable to parse access control policy " + ex.getMessage());
626
697
private void parseExtendedHeaders(Map operationParams, String headerString, String value) throws BindingException {
627
698
if(headerString.equals(WalrusProperties.ExtendedGetHeaders.Range.toString())) {
628
699
String prefix = "bytes=";
1049
public static synchronized WalrusDataMessenger getReadMessenger() {
1050
if (getMessenger == null) {
1051
getMessenger = new WalrusDataMessenger();
1053
return getMessenger;
1057
1120
public static synchronized WalrusDataMessenger getWriteMessenger() {
1058
1121
if (putMessenger == null) {
1059
1122
putMessenger = new WalrusDataMessenger();