~ubuntu-branches/ubuntu/natty/eucalyptus/natty-updates

« back to all changes in this revision

Viewing changes to clc/modules/wsstack/src/main/java/com/eucalyptus/ws/handlers/WalrusRESTBinding.java

  • Committer: Bazaar Package Importer
  • Author(s): Dustin Kirkland
  • Date: 2009-12-17 18:22:02 UTC
  • mto: This revision was merged to the branch mainline in revision 83.
  • Revision ID: james.westby@ubuntu.com-20091217182202-0v2v09ry3cxrvh84
Tags: upstream-1.6.2~bzr1103
ImportĀ upstreamĀ versionĀ 1.6.2~bzr1103

Show diffs side-by-side

added added

removed removed

Lines of Context:
72
72
import java.util.List;
73
73
import java.util.Map;
74
74
import java.util.Set;
 
75
import java.util.UUID;
75
76
import java.util.concurrent.LinkedBlockingQueue;
76
77
 
77
78
import net.sf.json.JSONArray;
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;
112
114
 
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;
140
 
        private String key;
141
 
        private String randomKey;
 
145
        private String key;
 
146
        private String randomKey;
142
147
        private LinkedBlockingQueue<WalrusDataMessage> putQueue;
143
148
 
144
 
        @Override
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;
149
 
                        try {
150
 
                                this.incomingMessage( channelHandlerContext, msgEvent );
151
 
                        } catch ( Throwable e ) {
152
 
                                LOG.error( e, e );
153
 
                                Channels.fireExceptionCaught( channelHandlerContext, e );
154
 
                                return;
155
 
                        }
156
 
                } else if (channelEvent.toString().contains("DISCONNECTED") ||
157
 
                                channelEvent.toString().contains("CLOSED")) {
158
 
                        if(key != null && randomKey != null) {
159
 
                                putMessenger.removeQueue(key, randomKey);
160
 
                                putQueue = null;
161
 
                        }
162
 
                }
163
 
                channelHandlerContext.sendUpstream( channelEvent );
164
 
        }
 
149
        @Override
 
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;
 
154
                        try {
 
155
                                this.incomingMessage( channelHandlerContext, msgEvent );
 
156
                        } catch ( Throwable e ) {
 
157
                                LOG.error( e, e );
 
158
                                Channels.fireExceptionCaught( channelHandlerContext, e );
 
159
                                return;
 
160
                        } 
 
161
                } else if (channelEvent.toString().contains("DISCONNECTED") || 
 
162
                                channelEvent.toString().contains("CLOSED")) {
 
163
                        if(key != null && randomKey != null) {
 
164
                                putMessenger.removeQueue(key, randomKey);
 
165
                                putQueue = null;
 
166
                        }
 
167
                }
 
168
                channelHandlerContext.sendUpstream( channelEvent );
 
169
        }
165
170
 
166
171
        @Override
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);
273
 
 
274
278
                if(operationName == null)
275
279
                        throw new InvalidOperationException("Could not determine operation name for " + servicePath);
276
280
 
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();
292
296
                }
293
297
                catch ( Exception e )
294
298
                {
295
299
                        throw new BindingException( "Failed to construct message of type " + operationName );
296
300
                }
297
301
 
 
302
                addLogData(eucaMsg, bindingArguments);
298
303
 
299
304
                //TODO: Refactor this to be more general
300
305
                List<String> failedMappings = populateObject( eucaMsg, fieldMap, params);
328
333
 
329
334
        }
330
335
 
 
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);
 
345
                        }
 
346
                }
 
347
        }
 
348
 
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]);
402
 
 
 
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);
446
468
                                }
447
 
 
448
469
                        } else {
449
470
                                operationKey = SERVICE + verb;
450
471
                        }
459
480
                        }
460
481
                        operationParams.put("Bucket", target[0]);
461
482
                        operationParams.put("Key", objectKey);
462
 
 
 
483
                        operationParams.put("Operation", verb.toUpperCase() + "." + "OBJECT");
463
484
 
464
485
                        if(!params.containsKey(WalrusProperties.OperationParameter.acl.toString())) {
465
486
                                if (verb.equals(WalrusProperties.HTTPVerb.PUT.toString())) {
623
644
                return operationName;   
624
645
        }
625
646
 
 
647
        private void getTargetBucketParams(Map operationParams,
 
648
                        MappingHttpRequest httpRequest) throws BindingException {
 
649
                String message = getMessageString(httpRequest);
 
650
                if(message.length() > 0) {
 
651
                        try {
 
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>();
 
656
 
 
657
                                List<String> permissions = xmlParser.getValues("//TargetGrants/Grant/Permission");
 
658
                                if(permissions == null)
 
659
                                        throw new BindingException("malformed access control list");
 
660
 
 
661
                                DTMNodeList grantees = xmlParser.getNodes("//TargetGrants/Grant/Grantee");
 
662
                                if(grantees == null)
 
663
                                        throw new BindingException("malformed access control list");
 
664
 
 
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));
 
674
                                                grants.add(grant);
 
675
                                        } else {
 
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));
 
684
                                                grants.add(grant);
 
685
                                        }
 
686
                                }
 
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) {
 
691
                                LOG.warn(ex);
 
692
                                throw new BindingException("Unable to parse access control policy " + ex.getMessage());
 
693
                        }
 
694
                }
 
695
        }
 
696
 
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=";
1046
1117
        }
1047
1118
 
1048
1119
 
1049
 
        public static synchronized WalrusDataMessenger getReadMessenger() {
1050
 
                if (getMessenger == null) {
1051
 
                        getMessenger = new WalrusDataMessenger();
1052
 
                }
1053
 
                return getMessenger;
1054
 
        }
1055
 
 
1056
 
 
1057
1120
        public static synchronized WalrusDataMessenger getWriteMessenger() {
1058
1121
                if (putMessenger == null) {
1059
1122
                        putMessenger = new WalrusDataMessenger();