Project

General

Profile

1 6253 leinfelder
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2011 Regents of the University of California and the
4
 *              National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author$'
7
 *     '$Date$'
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 2 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
 */
23
package edu.ucsb.nceas.metacat.restservice;
24
25
import java.io.ByteArrayInputStream;
26
import java.io.File;
27
import java.io.FileInputStream;
28
import java.io.IOException;
29
import java.io.InputStream;
30
import java.io.OutputStream;
31
import java.util.Date;
32 6622 leinfelder
import java.util.Enumeration;
33 6253 leinfelder
import java.util.Map;
34
35
import javax.servlet.ServletContext;
36
import javax.servlet.http.HttpServletRequest;
37
import javax.servlet.http.HttpServletResponse;
38 6514 leinfelder
import javax.xml.parsers.ParserConfigurationException;
39 6253 leinfelder
40 6269 leinfelder
import org.apache.commons.fileupload.FileUploadException;
41 6253 leinfelder
import org.apache.commons.io.IOUtils;
42
import org.apache.log4j.Logger;
43
import org.dataone.client.ObjectFormatCache;
44 6634 cjones
import org.dataone.mimemultipart.MultipartRequest;
45
import org.dataone.mimemultipart.MultipartRequestResolver;
46 6253 leinfelder
import org.dataone.service.exceptions.BaseException;
47
import org.dataone.service.exceptions.IdentifierNotUnique;
48
import org.dataone.service.exceptions.InsufficientResources;
49
import org.dataone.service.exceptions.InvalidRequest;
50
import org.dataone.service.exceptions.InvalidSystemMetadata;
51
import org.dataone.service.exceptions.InvalidToken;
52
import org.dataone.service.exceptions.NotAuthorized;
53
import org.dataone.service.exceptions.NotFound;
54
import org.dataone.service.exceptions.NotImplemented;
55
import org.dataone.service.exceptions.ServiceFailure;
56
import org.dataone.service.exceptions.UnsupportedType;
57 6366 leinfelder
import org.dataone.service.types.v1.AccessPolicy;
58
import org.dataone.service.types.v1.Checksum;
59
import org.dataone.service.types.v1.Event;
60
import org.dataone.service.types.v1.Identifier;
61
import org.dataone.service.types.v1.Log;
62 6592 cjones
import org.dataone.service.types.v1.NodeReference;
63 6366 leinfelder
import org.dataone.service.types.v1.ObjectFormat;
64
import org.dataone.service.types.v1.ObjectFormatIdentifier;
65
import org.dataone.service.types.v1.ObjectFormatList;
66 6622 leinfelder
import org.dataone.service.types.v1.ObjectList;
67 6366 leinfelder
import org.dataone.service.types.v1.ObjectLocationList;
68
import org.dataone.service.types.v1.Permission;
69 6592 cjones
import org.dataone.service.types.v1.Replica;
70
import org.dataone.service.types.v1.ReplicationPolicy;
71
import org.dataone.service.types.v1.ReplicationStatus;
72 6366 leinfelder
import org.dataone.service.types.v1.Subject;
73
import org.dataone.service.types.v1.SystemMetadata;
74 6469 leinfelder
import org.dataone.service.util.DateTimeMarshaller;
75 6367 leinfelder
import org.dataone.service.util.TypeMarshaller;
76 6253 leinfelder
import org.jibx.runtime.JiBXException;
77 6514 leinfelder
import org.xml.sax.SAXException;
78 6253 leinfelder
79
import edu.ucsb.nceas.metacat.dataone.CNodeService;
80 6639 leinfelder
import edu.ucsb.nceas.metacat.properties.PropertyService;
81
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
82 6253 leinfelder
83
/**
84
 * CN REST service implementation handler
85
 *
86
 * ******************
87
 	CNCore -- DONE
88
		create() - POST /d1/cn/object/PID
89
		listFormats() - GET /d1/cn/formats
90
		getFormat() - GET /d1/cn/formats/FMTID
91
		getLogRecords - GET /d1/cn/log
92
		reserveIdentifier() - POST /d1/cn/reserve
93
		listNodes() - Not implemented
94
		registerSystemMetadata() - POST /d1/meta/PID
95
96
	CNRead -- DONE
97
		get() - GET /d1/cn/object/PID
98
		getSystemMetadata() - GET /d1/cn/meta/PID
99
		resolve() - GET /d1/cn/resolve/PID
100
		assertRelation() - GET /d1/cn/assertRelation/PID
101
		getChecksum() - GET /d1/cn/checksum
102
		search() - Not implemented in Metacat
103
104
	CNAuthorization
105
		setOwner() - PUT /d1/cn/owner/PID
106
		isAuthorized() - GET /d1/cn/isAuthorized/PID
107
		setAccessPolicy() - POST /d1/cn/accessRules
108
109
	CNIdentity - not implemented at all on Metacat
110
111
	CNReplication
112 6623 cjones
		setReplicationStatus() - PUT /replicaNotifications/PID
113
		updateReplicationMetadata() - PUT /replicaMetadata/PID
114
		setReplicationPolicy() - PUT /replicaPolicies/PID
115
		isNodeAuthorized() - GET /replicaAuthorizations/PID
116 6253 leinfelder
117
	CNRegister -- not implemented at all in Metacat
118
 * ******************
119
 * @author leinfelder
120
 *
121
 */
122 6267 leinfelder
public class CNResourceHandler extends D1ResourceHandler {
123 6253 leinfelder
124
	/** CN-specific operations **/
125
    protected static final String RESOURCE_RESERVE = "reserve";
126 6271 leinfelder
    protected static final String RESOURCE_FORMATS = "formats";
127 6253 leinfelder
    protected static final String RESOURCE_RESOLVE = "resolve";
128
    protected static final String RESOURCE_ASSERT_RELATION = "assertRelation";
129
    protected static final String RESOURCE_OWNER = "owner";
130 6592 cjones
    protected static final String RESOURCE_REPLICATION_POLICY = "replicaPolicies";
131
    protected static final String RESOURCE_REPLICATION_META = "replicaMetadata";
132
    protected static final String RESOURCE_REPLICATION_AUTHORIZED = "replicaAuthorizations";
133
    protected static final String RESOURCE_REPLICATION_NOTIFY = "replicaNotifications";
134 6253 leinfelder
135
    public CNResourceHandler(ServletContext servletContext,
136
			HttpServletRequest request, HttpServletResponse response) {
137
		super(servletContext, request, response);
138
        logMetacat = Logger.getLogger(CNResourceHandler.class);
139
	}
140
141
	/**
142 6271 leinfelder
     * This function is called from REST API servlet and handles each request to the servlet
143 6253 leinfelder
     *
144
     * @param httpVerb (GET, POST, PUT or DELETE)
145
     */
146 6271 leinfelder
    @Override
147 6253 leinfelder
    public void handle(byte httpVerb) {
148 6271 leinfelder
    	// prepare the handler
149
    	super.handle(httpVerb);
150
151 6253 leinfelder
        try {
152 6282 leinfelder
153
        	// get the resource
154
            String resource = request.getPathInfo();
155
            resource = resource.substring(resource.indexOf("/") + 1);
156 6253 leinfelder
157 6396 leinfelder
            // for the rest of the resouce
158 6282 leinfelder
            String extra = null;
159
160 6253 leinfelder
            logMetacat.debug("handling verb " + httpVerb + " request with resource '" + resource + "'");
161
            boolean status = false;
162 6271 leinfelder
163 6253 leinfelder
            if (resource != null) {
164
165 6282 leinfelder
                if (resource.startsWith(RESOURCE_ACCESS_RULES) && httpVerb == PUT) {
166 6253 leinfelder
                    logMetacat.debug("Setting access policy");
167 6514 leinfelder
                    // after the command
168
                    extra = parseTrailing(resource, RESOURCE_ACCESS_RULES);
169
                    setAccess(extra);
170 6253 leinfelder
                    status = true;
171
                    logMetacat.debug("done setting access");
172
173 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_META)) {
174 6253 leinfelder
                    logMetacat.debug("Using resource: " + RESOURCE_META);
175 6282 leinfelder
176 6396 leinfelder
                    // after the command
177
                    extra = parseTrailing(resource, RESOURCE_META);
178
179 6253 leinfelder
                    // get
180
                    if (httpVerb == GET) {
181 6282 leinfelder
                        getSystemMetadataObject(extra);
182 6253 leinfelder
                        status = true;
183
                    }
184
                    // post to register system metadata
185
                    if (httpVerb == POST) {
186 6282 leinfelder
                    	registerSystemMetadata(extra);
187 6253 leinfelder
                    	status = true;
188
                    }
189
190 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_RESERVE)) {
191 6253 leinfelder
                    // reserve the ID (in params)
192
                    if (httpVerb == POST) {
193
                    	reserve();
194
                    	status = true;
195
                    }
196 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_ASSERT_RELATION)) {
197
198 6396 leinfelder
                	// after the command
199
                    extra = parseTrailing(resource, RESOURCE_ASSERT_RELATION);
200
201 6253 leinfelder
                    // reserve the ID (in params)
202
                    if (httpVerb == GET) {
203 6282 leinfelder
                    	assertRelation(extra);
204 6253 leinfelder
                    	status = true;
205
                    }
206 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_RESOLVE)) {
207
208 6396 leinfelder
                	// after the command
209
                    extra = parseTrailing(resource, RESOURCE_RESOLVE);
210
211 6253 leinfelder
                    // resolve the object location
212
                    if (httpVerb == GET) {
213 6282 leinfelder
                    	resolve(extra);
214 6253 leinfelder
                    	status = true;
215
                    }
216 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_OWNER)) {
217
218 6396 leinfelder
                	// after the command
219
                    extra = parseTrailing(resource, RESOURCE_OWNER);
220
221 6253 leinfelder
                    // set the owner
222
                    if (httpVerb == PUT) {
223 6282 leinfelder
                    	owner(extra);
224 6253 leinfelder
                    	status = true;
225
                    }
226 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_IS_AUTHORIZED)) {
227
228 6396 leinfelder
                	// after the command
229
                    extra = parseTrailing(resource, RESOURCE_IS_AUTHORIZED);
230
231 6253 leinfelder
                    // authorized?
232
                    if (httpVerb == GET) {
233 6282 leinfelder
                    	isAuthorized(extra);
234 6253 leinfelder
                    	status = true;
235
                    }
236 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_OBJECTS)) {
237 6253 leinfelder
                    logMetacat.debug("Using resource 'object'");
238
                    logMetacat.debug("D1 Rest: Starting resource processing...");
239
240 6396 leinfelder
                    // after the command
241
                    extra = parseTrailing(resource, RESOURCE_OBJECTS);
242
243 6282 leinfelder
                    logMetacat.debug("objectId: " + extra);
244 6253 leinfelder
                    logMetacat.debug("verb:" + httpVerb);
245
246
                    if (httpVerb == GET) {
247 6282 leinfelder
                    	if (extra != null) {
248
                    		getObject(extra);
249
                    	} else {
250 6622 leinfelder
                    		listObjects();
251 6282 leinfelder
                    	}
252 6253 leinfelder
                        status = true;
253
                    } else if (httpVerb == POST) {
254 6282 leinfelder
                        putObject(extra, FUNCTION_NAME_INSERT);
255 6253 leinfelder
                        status = true;
256
                    }
257
258 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_FORMATS)) {
259 6253 leinfelder
                  logMetacat.debug("Using resource: " + RESOURCE_FORMATS);
260
261 6396 leinfelder
                  // after the command
262
                  extra = parseTrailing(resource, RESOURCE_FORMATS);
263 6253 leinfelder
264
                  // handle each verb
265
                  if (httpVerb == GET) {
266 6282 leinfelder
                  	if (extra == null) {
267 6253 leinfelder
                  		// list the formats collection
268
                  		listFormats();
269
                  	} else {
270
                  		// get the specified format
271 6282 leinfelder
                  		getFormat(extra);
272 6253 leinfelder
                  	}
273
                  	status = true;
274
                  }
275
276 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_LOG)) {
277 6253 leinfelder
                    logMetacat.debug("Using resource: " + RESOURCE_LOG);
278
                    //handle log events
279
                    if (httpVerb == GET) {
280
                        getLog();
281
                        status = true;
282
                    }
283
284 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_CHECKSUM)) {
285 6253 leinfelder
                    logMetacat.debug("Using resource: " + RESOURCE_CHECKSUM);
286 6396 leinfelder
287
                    // after the command
288
                    extra = parseTrailing(resource, RESOURCE_CHECKSUM);
289
290 6253 leinfelder
                    //handle checksum requests
291
                    if (httpVerb == GET) {
292
293 6282 leinfelder
                        checksum(extra);
294 6253 leinfelder
                        status = true;
295 6592 cjones
296 6253 leinfelder
                    }
297 6592 cjones
298
                } else if ( resource.startsWith(RESOURCE_REPLICATION_POLICY) &&
299
                        httpVerb == PUT) {
300
301
                    logMetacat.debug("Using resource: " + RESOURCE_REPLICATION_POLICY);
302
                    // get the trailing pid
303
                    extra = parseTrailing(resource, RESOURCE_REPLICATION_POLICY);
304
                    setReplicationPolicy(extra);
305
                    status = true;
306
307
                } else if ( resource.startsWith(RESOURCE_REPLICATION_META) &&
308
                        httpVerb == PUT) {
309
310
                    logMetacat.debug("Using resource: " + RESOURCE_REPLICATION_META);
311
                    // get the trailing pid
312
                    extra = parseTrailing(resource, RESOURCE_REPLICATION_META);
313
                    updateReplicationMetadata(extra);
314
                    status = true;
315
316
                } else if ( resource.startsWith(RESOURCE_REPLICATION_NOTIFY) &&
317
                        httpVerb == PUT ) {
318
319
                    logMetacat.debug("Using resource: " + RESOURCE_REPLICATION_NOTIFY);
320
                    // get the trailing pid
321
                    extra = parseTrailing(resource, RESOURCE_REPLICATION_NOTIFY);
322
                    setReplicationStatus(extra);
323
                    status = true;
324
325
                } else if ( resource.startsWith(RESOURCE_REPLICATION_AUTHORIZED)
326
                        && httpVerb == GET) {
327
328
                    logMetacat.debug("Using resource: " + RESOURCE_REPLICATION_AUTHORIZED);
329
                    // get the trailing pid
330
                    extra = parseTrailing(resource, RESOURCE_REPLICATION_AUTHORIZED);
331
                    isNodeAuthorized(extra);
332
                    status = true;
333
334 6253 leinfelder
                }
335
336
                if (!status) {
337 6271 leinfelder
                	throw new ServiceFailure("0000", "Unknown error, status = " + status);
338 6253 leinfelder
                }
339
            } else {
340 6270 leinfelder
            	throw new InvalidRequest("0000", "No resource matched for " + resource);
341 6253 leinfelder
            }
342
        } catch (BaseException be) {
343 6270 leinfelder
        	// report Exceptions as clearly and generically as possible
344 6253 leinfelder
        	OutputStream out = null;
345
			try {
346
				out = response.getOutputStream();
347 6270 leinfelder
			} catch (IOException ioe) {
348
				logMetacat.error("Could not get output stream from response", ioe);
349 6253 leinfelder
			}
350
            serializeException(be, out);
351
        } catch (Exception e) {
352 6270 leinfelder
            // report Exceptions as clearly and generically as possible
353 6253 leinfelder
            logMetacat.error(e.getClass() + ": " + e.getMessage(), e);
354 6270 leinfelder
        	OutputStream out = null;
355
			try {
356
				out = response.getOutputStream();
357
			} catch (IOException ioe) {
358
				logMetacat.error("Could not get output stream from response", ioe);
359
			}
360
			ServiceFailure se = new ServiceFailure("0000", e.getMessage());
361
            serializeException(se, out);
362 6253 leinfelder
        }
363
    }
364
365 6396 leinfelder
366 6270 leinfelder
    /**
367
     * Get the checksum for the given guid
368
     *
369
     * @param guid
370
     * @throws NotImplemented
371
     * @throws InvalidRequest
372
     * @throws NotFound
373
     * @throws NotAuthorized
374
     * @throws ServiceFailure
375
     * @throws InvalidToken
376
     * @throws IOException
377
     * @throws JiBXException
378
     */
379
    private void checksum(String guid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, InvalidRequest, NotImplemented, JiBXException, IOException {
380
    	Identifier guidid = new Identifier();
381
        guidid.setValue(guid);
382
        logMetacat.debug("getting checksum for object " + guid);
383 6542 leinfelder
        Checksum c = CNodeService.getInstance(request).getChecksum(session, guidid);
384 6270 leinfelder
        logMetacat.debug("got checksum " + c.getValue());
385
        response.setStatus(200);
386
        logMetacat.debug("serializing response");
387 6367 leinfelder
        TypeMarshaller.marshalTypeToOutputStream(c, response.getOutputStream());
388 6270 leinfelder
        logMetacat.debug("done serializing response.");
389
390
    }
391
392 6253 leinfelder
	/**
393 6362 leinfelder
     * get the logs based on passed params.  Available
394 6253 leinfelder
     * params are token, fromDate, toDate, event.  See
395
     * http://mule1.dataone.org/ArchitectureDocs/mn_api_crud.html#MN_crud.getLogRecords
396
     * for more info
397 6270 leinfelder
	 * @throws NotImplemented
398
	 * @throws InvalidRequest
399
	 * @throws NotAuthorized
400
	 * @throws ServiceFailure
401
	 * @throws InvalidToken
402
	 * @throws IOException
403
	 * @throws JiBXException
404 6253 leinfelder
     */
405 6270 leinfelder
    private void getLog() throws InvalidToken, ServiceFailure, NotAuthorized, InvalidRequest, NotImplemented, IOException, JiBXException
406 6253 leinfelder
    {
407 6270 leinfelder
408
        Date fromDate = null;
409
        Date toDate = null;
410
        Event event = null;
411
        Integer start = null;
412
        Integer count = null;
413
414
        try {
415
        	String fromDateS = params.get("fromDate")[0];
416 6272 leinfelder
            logMetacat.debug("param fromDateS: " + fromDateS);
417 6469 leinfelder
            fromDate = DateTimeMarshaller.deserializeDateToUTC(fromDateS);
418 6270 leinfelder
        } catch (Exception e) {
419
        	logMetacat.warn("Could not parse fromDate: " + e.getMessage());
420 6253 leinfelder
        }
421 6270 leinfelder
        try {
422
        	String toDateS = params.get("toDate")[0];
423 6272 leinfelder
            logMetacat.debug("param toDateS: " + toDateS);
424 6469 leinfelder
            toDate = DateTimeMarshaller.deserializeDateToUTC(toDateS);
425 6270 leinfelder
        } catch (Exception e) {
426
        	logMetacat.warn("Could not parse toDate: " + e.getMessage());
427
		}
428
        try {
429
        	String eventS = params.get("event")[0];
430
            event = Event.convert(eventS);
431
        } catch (Exception e) {
432
        	logMetacat.warn("Could not parse event: " + e.getMessage());
433
		}
434 6272 leinfelder
        logMetacat.debug("fromDate: " + fromDate + " toDate: " + toDate);
435 6270 leinfelder
436
        try {
437
        	start =  Integer.parseInt(params.get("start")[0]);
438
        } catch (Exception e) {
439
			logMetacat.warn("Could not parse start: " + e.getMessage());
440
		}
441
        try {
442
        	count =  Integer.parseInt(params.get("count")[0]);
443
        } catch (Exception e) {
444
			logMetacat.warn("Could not parse count: " + e.getMessage());
445
		}
446
447 6272 leinfelder
        logMetacat.debug("calling getLogRecords");
448 6542 leinfelder
        Log log = CNodeService.getInstance(request).getLogRecords(session, fromDate, toDate, event, start, count);
449 6270 leinfelder
450
        OutputStream out = response.getOutputStream();
451
        response.setStatus(200);
452
        response.setContentType("text/xml");
453
454 6367 leinfelder
        TypeMarshaller.marshalTypeToOutputStream(log, out);
455 6270 leinfelder
456 6253 leinfelder
    }
457
458
    /**
459
     * Implements REST version of DataONE CRUD API --> get
460
     * @param guid ID of data object to be read
461 6270 leinfelder
     * @throws NotImplemented
462
     * @throws InvalidRequest
463
     * @throws NotFound
464
     * @throws NotAuthorized
465
     * @throws ServiceFailure
466
     * @throws InvalidToken
467
     * @throws IOException
468 6253 leinfelder
     */
469 6270 leinfelder
    protected void getObject(String guid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, InvalidRequest, NotImplemented, IOException {
470
471 6280 leinfelder
        Identifier id = new Identifier();
472
        id.setValue(guid);
473
474 6542 leinfelder
        SystemMetadata sm = CNodeService.getInstance(request).getSystemMetadata(session, id);
475 6270 leinfelder
476 6280 leinfelder
        //set the content type
477 6561 leinfelder
        if(sm.getFormatId().getValue().trim().equals(
478
        		ObjectFormatCache.getInstance().getFormat("text/csv").getFormatId().getValue()))
479 6280 leinfelder
        {
480
            response.setContentType("text/csv");
481
            response.setHeader("Content-Disposition", "inline; filename=" + id.getValue() + ".csv");
482 6253 leinfelder
        }
483 6561 leinfelder
        else if(sm.getFormatId().getValue().trim().equals(
484
        		ObjectFormatCache.getInstance().getFormat("text/plain").getFormatId().getValue()))
485 6280 leinfelder
        {
486
            response.setContentType("text/plain");
487
            response.setHeader("Content-Disposition", "inline; filename=" + id.getValue() + ".txt");
488
        }
489 6561 leinfelder
        else if(sm.getFormatId().getValue().trim().equals(
490
        		ObjectFormatCache.getInstance().getFormat("application/octet-stream").getFormatId().getValue()))
491 6280 leinfelder
        {
492
            response.setContentType("application/octet-stream");
493
        }
494
        else
495
        {
496
            response.setContentType("text/xml");
497
            response.setHeader("Content-Disposition", "inline; filename=" + id.getValue() + ".xml");
498
        }
499
500 6542 leinfelder
        InputStream data = CNodeService.getInstance(request).get(session, id);
501 6280 leinfelder
502
        OutputStream out = response.getOutputStream();
503
        response.setStatus(200);
504
        IOUtils.copyLarge(data, out);
505 6270 leinfelder
506 6253 leinfelder
    }
507
508
509
    /**
510
     * Implements REST version of DataONE CRUD API --> getSystemMetadata
511
     * @param guid ID of data object to be read
512 6270 leinfelder
     * @throws NotImplemented
513
     * @throws InvalidRequest
514
     * @throws NotFound
515
     * @throws NotAuthorized
516
     * @throws ServiceFailure
517
     * @throws InvalidToken
518
     * @throws IOException
519
     * @throws JiBXException
520 6253 leinfelder
     */
521 6270 leinfelder
    protected void getSystemMetadataObject(String guid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, InvalidRequest, NotImplemented, IOException, JiBXException {
522
523
        Identifier id = new Identifier();
524
        id.setValue(guid);
525 6542 leinfelder
        SystemMetadata sysmeta = CNodeService.getInstance(request).getSystemMetadata(session, id);
526 6270 leinfelder
527
        response.setContentType("text/xml");
528
        response.setStatus(200);
529
        OutputStream out = response.getOutputStream();
530
531
        // Serialize and write it to the output stream
532 6367 leinfelder
        TypeMarshaller.marshalTypeToOutputStream(sysmeta, out);
533 6270 leinfelder
   }
534 6253 leinfelder
535
    /**
536
     * Earthgrid API > Put Service >Put Function : calls MetacatHandler > handleInsertOrUpdateAction
537
     *
538
     * @param guid - ID of data object to be inserted or updated.  If action is update, the pid
539
     *               is the existing pid.  If insert, the pid is the new one
540 6269 leinfelder
     * @throws InvalidRequest
541
     * @throws ServiceFailure
542
     * @throws IdentifierNotUnique
543
     * @throws JiBXException
544
     * @throws NotImplemented
545
     * @throws InvalidSystemMetadata
546
     * @throws InsufficientResources
547
     * @throws UnsupportedType
548
     * @throws NotAuthorized
549
     * @throws InvalidToken
550
     * @throws IOException
551 6367 leinfelder
     * @throws IllegalAccessException
552
     * @throws InstantiationException
553 6253 leinfelder
     */
554 6367 leinfelder
    protected void putObject(String pid, String action) throws ServiceFailure, InvalidRequest, IdentifierNotUnique, JiBXException, InvalidToken, NotAuthorized, UnsupportedType, InsufficientResources, InvalidSystemMetadata, NotImplemented, IOException, InstantiationException, IllegalAccessException {
555 6253 leinfelder
        logMetacat.debug("Entering putObject: " + pid + "/" + action);
556 6269 leinfelder
557
        // Read the incoming data from its Mime Multipart encoding
558
    	Map<String, File> files = collectMultipartFiles();
559
        InputStream object = null;
560
        InputStream sysmeta = null;
561 6253 leinfelder
562 6269 leinfelder
        File smFile = files.get("sysmeta");
563
        sysmeta = new FileInputStream(smFile);
564
        File objFile = files.get("object");
565
        object = new FileInputStream(objFile);
566
567 6270 leinfelder
        if (action.equals(FUNCTION_NAME_INSERT)) { //handle inserts
568 6253 leinfelder
569 6269 leinfelder
            logMetacat.debug("Commence creation...");
570 6367 leinfelder
            SystemMetadata smd = TypeMarshaller.unmarshalTypeFromStream(SystemMetadata.class, sysmeta);
571 6253 leinfelder
572 6269 leinfelder
            Identifier id = new Identifier();
573
            id.setValue(pid);
574
            logMetacat.debug("creating object with pid " + id.getValue());
575 6542 leinfelder
            Identifier rId = CNodeService.getInstance(request).create(session, id, object, smd);
576 6253 leinfelder
577 6269 leinfelder
            OutputStream out = response.getOutputStream();
578
            response.setStatus(200);
579
            response.setContentType("text/xml");
580 6253 leinfelder
581 6367 leinfelder
            TypeMarshaller.marshalTypeToOutputStream(rId, out);
582 6269 leinfelder
583
        } else {
584
            throw new InvalidRequest("1000", "Operation must be create.");
585 6253 leinfelder
        }
586
    }
587
588
    /**
589
     * List the object formats registered with the system
590 6270 leinfelder
     * @throws NotImplemented
591
     * @throws InsufficientResources
592
     * @throws NotFound
593
     * @throws ServiceFailure
594
     * @throws InvalidRequest
595
     * @throws IOException
596
     * @throws JiBXException
597 6253 leinfelder
     */
598 6270 leinfelder
	private void listFormats() throws InvalidRequest, ServiceFailure, NotFound, InsufficientResources, NotImplemented, IOException, JiBXException {
599 6253 leinfelder
      logMetacat.debug("Entering listFormats()");
600 6270 leinfelder
601 6542 leinfelder
      ObjectFormatList objectFormatList = CNodeService.getInstance(request).listFormats();
602 6253 leinfelder
      // get the response output stream
603 6270 leinfelder
      OutputStream out = response.getOutputStream();
604
      response.setStatus(200);
605
      response.setContentType("text/xml");
606 6253 leinfelder
607 6639 leinfelder
      // style the object with a processing directive
608
      String stylesheet = null;
609
      try {
610
    	  stylesheet = PropertyService.getProperty("dataone.types.xsl");
611
      } catch (PropertyNotFoundException e) {
612
    	  logMetacat.warn("Could not locate DataONE types XSLT: " + e.getMessage());
613
      }
614
615
      TypeMarshaller.marshalTypeToOutputStream(objectFormatList, out, stylesheet);
616 6270 leinfelder
617 6253 leinfelder
    }
618
619
		/**
620
     * Return the requested object format
621
     *
622
     * @param fmtidStr the requested format identifier as a string
623 6270 leinfelder
		 * @throws NotImplemented
624
		 * @throws InsufficientResources
625
		 * @throws NotFound
626
		 * @throws ServiceFailure
627
		 * @throws InvalidRequest
628
		 * @throws IOException
629
		 * @throws JiBXException
630 6253 leinfelder
     */
631 6270 leinfelder
    private void getFormat(String fmtidStr) throws InvalidRequest, ServiceFailure, NotFound, InsufficientResources, NotImplemented, IOException, JiBXException {
632 6253 leinfelder
      logMetacat.debug("Entering listFormats()");
633
634
      ObjectFormatIdentifier fmtid = new ObjectFormatIdentifier();
635
      fmtid.setValue(fmtidStr);
636
637 6270 leinfelder
	  // get the specified object format
638 6542 leinfelder
      ObjectFormat objectFormat = CNodeService.getInstance(request).getFormat(fmtid);
639 6253 leinfelder
640 6270 leinfelder
      OutputStream out = response.getOutputStream();
641
      response.setStatus(200);
642
      response.setContentType("text/xml");
643 6253 leinfelder
644 6367 leinfelder
      TypeMarshaller.marshalTypeToOutputStream(objectFormat, out);
645 6253 leinfelder
646
    }
647
648
    /**
649
     * Reserve the given Identifier
650
     * @throws InvalidToken
651
     * @throws ServiceFailure
652
     * @throws NotAuthorized
653
     * @throws IdentifierNotUnique
654
     * @throws NotImplemented
655
     * @throws InvalidRequest
656
     * @throws IOException
657 6270 leinfelder
     * @throws JiBXException
658 6253 leinfelder
     */
659 6270 leinfelder
    private void reserve() throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, NotImplemented, InvalidRequest, IOException, JiBXException {
660 6279 leinfelder
		Identifier pid = null;
661
		String scope = null;
662
    	String format = null;
663
    	// gather the params
664
		try {
665
	    	String id = params.get("pid")[0];
666
			pid = new Identifier();
667
			pid.setValue(id);
668
		} catch (Exception e) {
669
			logMetacat.warn("pid not specified");
670
		}
671
		try {
672
			scope = params.get("scope")[0];
673
		} catch (Exception e) {
674
			logMetacat.warn("pid not specified");
675
		}
676
		try {
677
			format = params.get("format")[0];
678
		} catch (Exception e) {
679
			logMetacat.warn("pid not specified");
680
		}
681
		// call the implementation
682 6622 leinfelder
		Identifier resultPid = CNodeService.getInstance(request).reserveIdentifier(session, pid);
683 6253 leinfelder
		OutputStream out = response.getOutputStream();
684
		response.setStatus(200);
685
		response.setContentType("text/xml");
686 6622 leinfelder
		// send back the reserved pid
687
		TypeMarshaller.marshalTypeToOutputStream(resultPid, out);
688 6253 leinfelder
    }
689
690 6270 leinfelder
    /**
691
     *
692
     * @param id
693
     * @throws InvalidRequest
694
     * @throws InvalidToken
695
     * @throws ServiceFailure
696
     * @throws NotAuthorized
697
     * @throws NotFound
698
     * @throws NotImplemented
699
     * @throws IOException
700
     * @throws JiBXException
701
     */
702
    private void resolve(String id) throws InvalidRequest, InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented, IOException, JiBXException {
703 6253 leinfelder
		Identifier pid = new Identifier();
704
		pid.setValue(id);
705 6542 leinfelder
		ObjectLocationList locationList = CNodeService.getInstance(request).resolve(session, pid);
706 6253 leinfelder
	    OutputStream out = response.getOutputStream();
707
		response.setStatus(200);
708
		response.setContentType("text/xml");
709 6367 leinfelder
		TypeMarshaller.marshalTypeToOutputStream(locationList, out);
710 6270 leinfelder
711 6253 leinfelder
    }
712
713 6270 leinfelder
    /**
714
     * Assert that a relationship exists between two resources
715
     * @param id
716
     * @return
717
     * @throws InvalidToken
718
     * @throws ServiceFailure
719
     * @throws NotAuthorized
720
     * @throws NotFound
721
     * @throws InvalidRequest
722
     * @throws NotImplemented
723
     */
724 6268 leinfelder
    private boolean assertRelation(String id) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, InvalidRequest, NotImplemented {
725 6253 leinfelder
		Identifier pidOfSubject = new Identifier();
726
		pidOfSubject.setValue(id);
727 6270 leinfelder
		String relationship = null;
728
		try {
729
			relationship = params.get("relationship")[0];
730
		} catch (Exception e) {
731
			logMetacat.warn("relationship not specified");
732
		}
733 6253 leinfelder
		Identifier pidOfObject = new Identifier();
734 6270 leinfelder
		try {
735
			String objPid = params.get("pidOfObject")[0];
736
			pidOfObject.setValue(objPid);
737
		} catch (Exception e) {
738
			logMetacat.warn("pidOfObject not specified");
739
		}
740 6542 leinfelder
		boolean result = CNodeService.getInstance(request).assertRelation(session, pidOfSubject, relationship, pidOfObject);
741 6253 leinfelder
		response.setStatus(200);
742
		response.setContentType("text/xml");
743
		return result;
744
    }
745
746 6270 leinfelder
    /**
747
     * Set the owner of a resource
748
     * @param id
749
     * @throws JiBXException
750
     * @throws InvalidToken
751
     * @throws ServiceFailure
752
     * @throws NotFound
753
     * @throws NotAuthorized
754
     * @throws NotImplemented
755
     * @throws InvalidRequest
756
     * @throws IOException
757 6367 leinfelder
     * @throws IllegalAccessException
758
     * @throws InstantiationException
759 6270 leinfelder
     */
760 6592 cjones
    private void owner(String id)
761
        throws JiBXException, InvalidToken, ServiceFailure,
762
        NotFound, NotAuthorized, NotImplemented, InvalidRequest, IOException,
763
        InstantiationException, IllegalAccessException {
764
765
        Identifier pid = new Identifier();
766
		    pid.setValue(id);
767
768
        long serialVersion = 0L;
769
        String serialVersionStr = null;
770
771
        // get the serialVersion
772
        try {
773
            serialVersionStr = params.get("serialVersion")[0];
774
            serialVersion = new Long(serialVersionStr).longValue();
775
776
        } catch (NullPointerException e) {
777
            String msg = "The 'serialVersion' must be provided as a parameter and was not.";
778
            logMetacat.error(msg);
779
            throw new InvalidRequest("4442", msg);
780
781
        }
782
783
		    // get the subject
784
		    String subjectStr = params.get("subject")[0];
785
		    Subject subject = TypeMarshaller.unmarshalTypeFromStream(Subject.class, new ByteArrayInputStream(subjectStr.getBytes("UTF-8")));
786
787
		    Identifier retPid = CNodeService.getInstance(request).setOwner(session, pid, subject, serialVersion);
788
		    OutputStream out = response.getOutputStream();
789
		    response.setStatus(200);
790
		    response.setContentType("text/xml");
791
		    TypeMarshaller.marshalTypeToOutputStream(retPid, out);
792 6253 leinfelder
    }
793
794 6270 leinfelder
    /**
795
     * Processes the authorization check for given id
796
     * @param id
797
     * @return
798
     * @throws ServiceFailure
799
     * @throws InvalidToken
800
     * @throws NotFound
801
     * @throws NotAuthorized
802
     * @throws NotImplemented
803
     * @throws InvalidRequest
804
     */
805 6253 leinfelder
    private boolean isAuthorized(String id) throws ServiceFailure, InvalidToken, NotFound, NotAuthorized, NotImplemented, InvalidRequest {
806
		Identifier pid = new Identifier();
807
		pid.setValue(id);
808 6510 leinfelder
		String permission = params.get("action")[0];
809 6542 leinfelder
		boolean result = CNodeService.getInstance(request).isAuthorized(session, pid, Permission.convert(permission));
810 6253 leinfelder
		response.setStatus(200);
811
		response.setContentType("text/xml");
812
		return result;
813
    }
814
815
    /**
816
     * Register System Metadata without data or metadata object
817
     * @param pid identifier for System Metadata entry
818 6269 leinfelder
     * @throws JiBXException
819
     * @throws FileUploadException
820
     * @throws IOException
821
     * @throws InvalidRequest
822
     * @throws ServiceFailure
823
     * @throws InvalidSystemMetadata
824
     * @throws NotAuthorized
825
     * @throws NotImplemented
826 6367 leinfelder
     * @throws IllegalAccessException
827
     * @throws InstantiationException
828 6253 leinfelder
     */
829 6397 leinfelder
    protected Identifier registerSystemMetadata(String pid) throws ServiceFailure, InvalidRequest, IOException, FileUploadException, JiBXException, NotImplemented, NotAuthorized, InvalidSystemMetadata, InstantiationException, IllegalAccessException {
830 6253 leinfelder
		logMetacat.debug("Entering registerSystemMetadata: " + pid);
831
832 6269 leinfelder
		// get the system metadata from the request
833
		SystemMetadata systemMetadata = collectSystemMetadata();
834 6253 leinfelder
835 6269 leinfelder
		Identifier guid = new Identifier();
836
		guid.setValue(pid);
837
		logMetacat.debug("registering system metadata with pid " + guid.getValue());
838 6542 leinfelder
		Identifier retGuid = CNodeService.getInstance(request).registerSystemMetadata(session, guid, systemMetadata);
839 6269 leinfelder
840
		response.setStatus(200);
841
		response.setContentType("text/xml");
842 6397 leinfelder
		return retGuid;
843 6269 leinfelder
844 6253 leinfelder
	}
845 6268 leinfelder
846
    /**
847
     * set the access perms on a document
848 6270 leinfelder
     * @throws JiBXException
849
     * @throws InvalidRequest
850
     * @throws NotImplemented
851
     * @throws NotAuthorized
852
     * @throws NotFound
853
     * @throws ServiceFailure
854
     * @throws InvalidToken
855 6367 leinfelder
     * @throws IllegalAccessException
856
     * @throws InstantiationException
857
     * @throws IOException
858 6514 leinfelder
     * @throws SAXException
859
     * @throws ParserConfigurationException
860 6268 leinfelder
     */
861 6592 cjones
    protected void setAccess(String pid)
862
        throws JiBXException, InvalidToken, ServiceFailure, NotFound,
863
        NotAuthorized, NotImplemented, InvalidRequest, IOException,
864
        InstantiationException, IllegalAccessException, ParserConfigurationException,
865
        SAXException {
866 6270 leinfelder
867 6592 cjones
        long serialVersion = 0L;
868
        String serialVersionStr = null;
869
870
        // get the serialVersion
871
        try {
872
            serialVersionStr = params.get("serialVersion")[0];
873
            serialVersion = new Long(serialVersionStr).longValue();
874
875
        } catch (NullPointerException e) {
876
            String msg = "The 'serialVersion' must be provided as a parameter and was not.";
877
            logMetacat.error(msg);
878
            throw new InvalidRequest("4402", msg);
879
880
        }
881
882 6270 leinfelder
        Identifier id = new Identifier();
883 6514 leinfelder
        id.setValue(pid);
884
885
        AccessPolicy accessPolicy = collectAccessPolicy();
886 6592 cjones
        CNodeService.getInstance(request).setAccessPolicy(session, id, accessPolicy, serialVersion);
887 6270 leinfelder
888 6268 leinfelder
    }
889
890
    /**
891 6622 leinfelder
     *	List the objects
892 6282 leinfelder
     *
893
     * @throws NotImplemented
894
     * @throws InvalidRequest
895
     * @throws NotAuthorized
896
     * @throws ServiceFailure
897
     * @throws InvalidToken
898 6622 leinfelder
     * @throws NotFound
899
     * @throws IOException
900
     * @throws JiBXException
901 6268 leinfelder
     * @throws Exception
902
     */
903 6622 leinfelder
    private void listObjects() throws InvalidToken, ServiceFailure, NotAuthorized,
904
			InvalidRequest, NotImplemented, NotFound, IOException,
905
			JiBXException {
906
907
		Date startTime = null;
908
		Date endTime = null;
909
		ObjectFormat objectFormat = null;
910
		boolean replicaStatus = false;
911
		int start = 0;
912
		int count = -1;
913
		Enumeration<String> paramlist = request.getParameterNames();
914
		while (paramlist.hasMoreElements()) {
915
			// parse the params and make the call
916
			String name = paramlist.nextElement();
917
			String[] value = request.getParameterValues(name);
918
919
			if (name.equals("startTime") && value != null) {
920
				try {
921
					startTime = DateTimeMarshaller.deserializeDateToUTC(value[0]);
922
				} catch (Exception e) {
923
					// if we can't parse it, just don't use the startTime param
924
					logMetacat.warn("Could not parse startTime: " + value[0]);
925
					startTime = null;
926
				}
927
			} else if (name.equals("endTime") && value != null) {
928
				try {
929
					endTime = DateTimeMarshaller.deserializeDateToUTC(value[0]);
930
				} catch (Exception e) {
931
					// if we can't parse it, just don't use the endTime param
932
					logMetacat.warn("Could not parse endTime: " + value[0]);
933
					endTime = null;
934
				}
935
			} else if (name.equals("objectFormat") && value != null) {
936
				objectFormat = ObjectFormatCache.getInstance().getFormat(value[0]);
937
			} else if (name.equals("replicaStatus") && value != null) {
938
				replicaStatus = Boolean.parseBoolean(value[0]);
939
			} else if (name.equals("start") && value != null) {
940
				start = Integer.valueOf(value[0]);
941
			} else if (name.equals("count") && value != null) {
942
				count = Integer.valueOf(value[0]);
943
			}
944
		}
945
		// make the call
946
		logMetacat.debug("session: " + session + " startTime: " + startTime
947
				+ " endtime: " + endTime + " objectFormat: " + objectFormat
948
				+ " replicaStatus: " + replicaStatus + " start: " + start
949
				+ " count: " + count);
950
951
		ObjectFormatIdentifier fmtid = null;
952
		if (objectFormat != null) {
953
			fmtid = objectFormat.getFormatId();
954
		}
955
956
		// get the list
957
		ObjectList ol =
958
			CNodeService.getInstance(request).listObjects(session,
959
				startTime, endTime, fmtid, replicaStatus, start, count);
960
961
		// send it
962
		OutputStream out = response.getOutputStream();
963
		response.setStatus(200);
964
		response.setContentType("text/xml");
965 6639 leinfelder
966
		// style the object with a processing directive
967
		String stylesheet = null;
968
		try {
969
			stylesheet = PropertyService.getProperty("dataone.types.xsl");
970
		} catch (PropertyNotFoundException e) {
971
			logMetacat.warn("Could not locate DataONE types XSLT: " + e.getMessage());
972
		}
973
974 6622 leinfelder
		// Serialize and write it to the output stream
975 6639 leinfelder
		TypeMarshaller.marshalTypeToOutputStream(ol, out, stylesheet);
976 6622 leinfelder
	}
977 6592 cjones
978
    /**
979
     * Pass the request to get node replication authorization to CNodeService
980
     *
981
     * @param pid  the identifier of the object to get authorization to replicate
982
     *
983
     * @throws NotImplemented
984
     * @throws NotAuthorized
985
     * @throws InvalidToken
986
     * @throws ServiceFailure
987
     * @throws NotFound
988
     * @throws InvalidRequest
989
     */
990
    public boolean isNodeAuthorized(String pid)
991
        throws NotImplemented, NotAuthorized, InvalidToken, ServiceFailure,
992
        NotFound, InvalidRequest {
993
994
        boolean result = false;
995
        Subject targetNodeSubject = new Subject();
996
        String nodeSubject = null;
997
        Permission permission = null;
998
        String replPermission = null;
999
1000
        // get the pid
1001
        Identifier identifier = new Identifier();
1002
        identifier.setValue(pid);
1003
1004
        // get the target node subject
1005
        try {
1006
            nodeSubject = params.get("targetNodeSubject")[0];
1007
            targetNodeSubject.setValue(nodeSubject);
1008
1009
        } catch (NullPointerException e) {
1010
            String msg = "The 'targetNodeSubject' must be provided as a parameter and was not.";
1011
            logMetacat.error(msg);
1012
            throw new InvalidRequest("4873", msg);
1013
1014
        }
1015
1016
        // get the permission
1017
        try {
1018
            replPermission = params.get("replicatePermission")[0];
1019
            permission = Permission.convert(replPermission);
1020 6268 leinfelder
1021 6592 cjones
        } catch (NullPointerException e) {
1022
            String msg = "The 'replicatePermission' must be provided as a parameter and was not.";
1023
            logMetacat.error(msg);
1024
            throw new InvalidRequest("4873", msg);
1025
1026
        }
1027
1028
        result =
1029
            CNodeService.getInstance(request).isNodeAuthorized(session, targetNodeSubject, identifier, permission);
1030
1031
        response.setStatus(200);
1032
        response.setContentType("text/xml");
1033
        return result;
1034
1035
    }
1036
1037
    /**
1038
     * Pass the request to set the replication policy to CNodeService
1039
     *
1040
     * @param pid  the identifier of the object to set the replication policy on
1041
     *
1042
     * @throws NotImplemented
1043
     * @throws NotFound
1044
     * @throws NotAuthorized
1045
     * @throws ServiceFailure
1046
     * @throws InvalidRequest
1047
     * @throws InvalidToken
1048
     * @throws IOException
1049
     * @throws InstantiationException
1050
     * @throws IllegalAccessException
1051
     * @throws JiBXException
1052
     */
1053
    public boolean setReplicationPolicy(String pid)
1054
        throws NotImplemented, NotFound, NotAuthorized, ServiceFailure,
1055
        InvalidRequest, InvalidToken, IOException, InstantiationException,
1056
        IllegalAccessException, JiBXException {
1057
1058
        boolean result = false;
1059
        ReplicationPolicy policy = null;
1060
        long serialVersion = 0L;
1061
        String serialVersionStr = null;
1062
1063
        Identifier identifier = new Identifier();
1064
        identifier.setValue(pid);
1065
1066 6634 cjones
        policy = collectReplicationPolicy();
1067
1068 6592 cjones
        // get the serialVersion
1069
        try {
1070 6603 cjones
            serialVersionStr = multipartparams.get("serialVersion").get(0);
1071 6592 cjones
            serialVersion = new Long(serialVersionStr).longValue();
1072
1073
        } catch (NullPointerException e) {
1074
            String msg = "The 'serialVersion' must be provided as a parameter and was not.";
1075
            logMetacat.error(msg);
1076
            throw new InvalidRequest("4883", msg);
1077
1078
        }
1079
        result =
1080
            CNodeService.getInstance(request).setReplicationPolicy(session, identifier, policy, serialVersion);
1081
        response.setStatus(200);
1082
        response.setContentType("text/xml");
1083
        return result;
1084
1085
    }
1086
1087
    /**
1088
     * Pass the request to set the replication status to CNodeService
1089
     *
1090
     * @param pid  the identifier of the object to set the replication status on
1091
     *
1092
     * @throws ServiceFailure
1093
     * @throws NotImplemented
1094
     * @throws InvalidToken
1095
     * @throws NotAuthorized
1096
     * @throws InvalidRequest
1097
     * @throws NotFound
1098
     */
1099
    public boolean setReplicationStatus(String pid)
1100
        throws ServiceFailure, NotImplemented, InvalidToken, NotAuthorized,
1101
        InvalidRequest, NotFound {
1102
1103 6634 cjones
        File tmpDir = getTempDirectory();
1104
        MultipartRequest mr = null;
1105 6592 cjones
        boolean result = false;
1106
        Identifier identifier = new Identifier();
1107
        identifier.setValue(pid);
1108
        long serialVersion = 0L;
1109
        String serialVersionStr = null;
1110
        ReplicationStatus status = null;
1111
        String replicationStatus = null;
1112
        NodeReference targetNodeRef = null;
1113
        String targetNode = null;
1114
1115 6634 cjones
        // Parse the params out of the multipart form data
1116
        // Read the incoming data from its Mime Multipart encoding
1117
        logMetacat.debug("Parsing ReplicaStatus from the mime multipart entity");
1118
1119
        // handle MMP inputs
1120
        MultipartRequestResolver mrr =
1121
            new MultipartRequestResolver(tmpDir.getAbsolutePath(),1000000000, 0);
1122
1123
        try {
1124
            mr = mrr.resolveMultipart(request);
1125
            multipartparams = mr.getMultipartParameters();
1126
            logMetacat.debug("Resolved the ReplicaStatus multipart request.");
1127
1128
        } catch (IOException e) {
1129
            throw new ServiceFailure("4852", "Couldn't resolve the multipart request: " +
1130
                e.getMessage());
1131
1132
        } catch (FileUploadException e) {
1133
            throw new ServiceFailure("4852", "Couldn't resolve the multipart request: " +
1134
                    e.getMessage());
1135
1136
        } catch (Exception e) {
1137
            throw new ServiceFailure("4852", "Couldn't resolve the multipart request: " +
1138
                    e.getMessage());
1139
1140
        }
1141
1142 6592 cjones
        // get the serialVersion
1143
        try {
1144 6603 cjones
            serialVersionStr = multipartparams.get("serialVersion").get(0);
1145 6592 cjones
            serialVersion = new Long(serialVersionStr).longValue();
1146 6642 cjones
1147
        } catch (NumberFormatException nfe) {
1148
            String msg = "The 'serialVersion' must be a positive integer and was not.";
1149 6592 cjones
            logMetacat.error(msg);
1150
            throw new InvalidRequest("4730", msg);
1151
1152 6642 cjones
        } catch (NullPointerException e) {
1153
            logMetacat.debug("The 'serialVersion' parameter was not found in the " +
1154
                "multipartparams map.  Trying the params map.");
1155
            try {
1156
                serialVersionStr = params.get("serialVersion")[0];
1157
                serialVersion = new Long(serialVersionStr).longValue();
1158
1159
            } catch (NumberFormatException e1) {
1160
                String msg = "The 'serialVersion' must be a positive integer and was not.";
1161
                logMetacat.error(msg);
1162
                throw new InvalidRequest("4730", msg);
1163
1164
            } catch (NullPointerException npe) {
1165
                String msg = "The 'serialVersion' must be provided as a parameter and was not.";
1166
                logMetacat.error(msg);
1167
                throw new InvalidRequest("4730", msg);
1168
1169
            }
1170
1171 6592 cjones
        }
1172
1173
        // get the replication status param
1174
        try {
1175 6603 cjones
            replicationStatus = multipartparams.get("replicationStatus").get(0);
1176 6592 cjones
            status = ReplicationStatus.convert(replicationStatus);
1177 6642 cjones
1178
        } catch (NullPointerException npe) {
1179
1180
            logMetacat.debug("The 'replicationStatus' parameter was not found in the " +
1181
            "multipartparams map.  Trying the params map.");
1182
1183
            try {
1184
                replicationStatus = params.get("replicationStatus")[0];
1185
                status = ReplicationStatus.convert(replicationStatus);
1186
1187
            } catch (Exception e) {
1188
                String msg = "The 'replicationStatus' must be provided as a parameter and was not.";
1189
                logMetacat.error(msg);
1190
                throw new InvalidRequest("4730", msg);
1191
1192
            }
1193
1194 6592 cjones
        }
1195
1196
        // get the target node reference param
1197 6642 cjones
        try {
1198
            targetNode = multipartparams.get("nodeRef").get(0);
1199
            targetNodeRef = new NodeReference();
1200
            targetNodeRef.setValue(targetNode);
1201
1202
        } catch (NullPointerException e) {
1203
            logMetacat.debug("The 'nodeRef' parameter was not found in the " +
1204
            "multipartparams map.  Trying the params map.");
1205
1206
            try {
1207
                targetNode = params.get("nodeRef")[0];
1208
                targetNodeRef = new NodeReference();
1209
                targetNodeRef.setValue(targetNode);
1210
1211
            } catch (Exception e1) {
1212
                String msg = "The 'nodeRef' must be provided as a parameter and was not.";
1213
                logMetacat.error(msg);
1214
                throw new InvalidRequest("4730", msg);
1215
1216
            }
1217
1218
        }
1219 6592 cjones
1220
        result =
1221
            CNodeService.getInstance(request).setReplicationStatus(session, identifier, targetNodeRef, status, serialVersion);
1222
        response.setStatus(200);
1223
        response.setContentType("text/xml");
1224
        return result;
1225
1226
    }
1227
1228
    /**
1229
     * Pass the request to update the replication metadata to CNodeService
1230
     *
1231
     * @param pid  the identifier of the object to update the replication metadata on
1232
     *
1233
     * @throws ServiceFailure
1234
     * @throws NotImplemented
1235
     * @throws InvalidToken
1236
     * @throws NotAuthorized
1237
     * @throws InvalidRequest
1238
     * @throws NotFound
1239
     */
1240
    public boolean updateReplicationMetadata(String pid)
1241
        throws ServiceFailure, NotImplemented, InvalidToken, NotAuthorized,
1242
        InvalidRequest, NotFound {
1243
1244
        boolean result = false;
1245
        long serialVersion = 0L;
1246
        String serialVersionStr = null;
1247
        Replica replica = null;
1248
        Identifier identifier = new Identifier();
1249
        identifier.setValue(pid);
1250
1251 6634 cjones
        replica = collectReplicaMetadata();
1252
1253 6592 cjones
        // get the serialVersion
1254
        try {
1255 6603 cjones
            serialVersionStr = multipartparams.get("serialVersion").get(0);
1256 6592 cjones
            serialVersion = new Long(serialVersionStr).longValue();
1257
1258
        } catch (NullPointerException e) {
1259
            String msg = "The 'serialVersion' must be provided as a parameter and was not.";
1260
            logMetacat.error(msg);
1261
            throw new InvalidRequest("4853", msg);
1262
1263
        }
1264
1265
        result =
1266
            CNodeService.getInstance(request).updateReplicationMetadata(session, identifier, replica, serialVersion);
1267
        response.setStatus(200);
1268
        response.setContentType("text/xml");
1269
        return result;
1270
1271
    }
1272
1273 6253 leinfelder
}