Revision 6475
Added by Matt Jones about 13 years ago
src/edu/ucsb/nceas/metacat/dataone/MNodeService.java | ||
---|---|---|
118 | 118 |
* MNReplication.replicate() |
119 | 119 |
* |
120 | 120 |
*/ |
121 |
public class MNodeService extends D1NodeService implements MNAuthorization, |
|
122 |
MNCore, MNRead, MNReplication, MNStorage { |
|
121 |
public class MNodeService extends D1NodeService implements MNAuthorization, MNCore, MNRead, MNReplication, MNStorage { |
|
123 | 122 |
|
124 |
/* the instance of the MNodeService object */ |
|
125 |
private static MNodeService instance = null; |
|
126 |
|
|
127 |
/* the logger instance */ |
|
128 |
private Logger logMetacat = null; |
|
123 |
/* the instance of the MNodeService object */ |
|
124 |
private static MNodeService instance = null; |
|
129 | 125 |
|
130 |
/** |
|
131 |
* Singleton accessor to get an instance of MNodeService. |
|
132 |
* |
|
133 |
* @return instance - the instance of MNodeService |
|
134 |
*/ |
|
135 |
public static MNodeService getInstance() { |
|
136 |
if (instance == null) { |
|
126 |
/* the logger instance */ |
|
127 |
private Logger logMetacat = null; |
|
137 | 128 |
|
138 |
instance = new MNodeService(); |
|
139 |
|
|
129 |
/** |
|
130 |
* Singleton accessor to get an instance of MNodeService. |
|
131 |
* |
|
132 |
* @return instance - the instance of MNodeService |
|
133 |
*/ |
|
134 |
public static MNodeService getInstance() { |
|
135 |
if (instance == null) { |
|
136 |
instance = new MNodeService(); |
|
137 |
} |
|
138 |
return instance; |
|
140 | 139 |
} |
141 |
|
|
142 |
return instance; |
|
143 |
} |
|
144 |
|
|
145 |
/** |
|
146 |
* Constructor, private for singleton access |
|
147 |
*/ |
|
148 |
private MNodeService() { |
|
149 |
super(); |
|
150 |
logMetacat = Logger.getLogger(MNodeService.class); |
|
151 |
|
|
152 |
} |
|
153 |
|
|
154 |
/** |
|
155 |
* Deletes an object from the Member Node, where the object is either a |
|
156 |
* data object or a science metadata object. |
|
157 |
* |
|
158 |
* @param session - the Session object containing the credentials for the Subject |
|
159 |
* @param pid - The object identifier to be deleted |
|
160 |
* |
|
161 |
* @return pid - the identifier of the object used for the deletion |
|
162 |
* |
|
163 |
* @throws InvalidToken |
|
164 |
* @throws ServiceFailure |
|
165 |
* @throws NotAuthorized |
|
166 |
* @throws NotFound |
|
167 |
* @throws NotImplemented |
|
168 |
* @throws InvalidRequest |
|
169 |
*/ |
|
170 |
@Override |
|
171 |
public Identifier delete(Session session, Identifier pid) |
|
172 |
throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, |
|
173 |
NotImplemented, InvalidRequest { |
|
174 | 140 |
|
175 |
String localId = null; |
|
176 |
boolean allowed = false; |
|
177 |
String username = Constants.PUBLIC_SUBJECT; |
|
178 |
String[] groupnames = null; |
|
179 |
if (session != null ) { |
|
180 |
username = session.getSubject().getValue(); |
|
181 |
if (session.getSubjectList() != null) { |
|
182 |
List<Group> groupList = session.getSubjectList().getGroupList(); |
|
183 |
if (groupList != null) { |
|
184 |
groupnames = new String[groupList.size()]; |
|
185 |
for (int i = 0; i > groupList.size(); i++ ) { |
|
186 |
groupnames[i] = groupList.get(i).getGroupName(); |
|
187 |
} |
|
188 |
} |
|
189 |
} |
|
141 |
/** |
|
142 |
* Constructor, private for singleton access |
|
143 |
*/ |
|
144 |
private MNodeService() { |
|
145 |
super(); |
|
146 |
logMetacat = Logger.getLogger(MNodeService.class); |
|
190 | 147 |
} |
191 |
|
|
192 |
// do we have a valid pid? |
|
193 |
if ( pid == null || pid.getValue().trim().equals("") ) { |
|
194 |
throw new InvalidRequest("1322", "The provided identifier was invalid."); |
|
148 |
|
|
149 |
/** |
|
150 |
* Deletes an object from the Member Node, where the object is either a |
|
151 |
* data object or a science metadata object. |
|
152 |
* |
|
153 |
* @param session - the Session object containing the credentials for the Subject |
|
154 |
* @param pid - The object identifier to be deleted |
|
155 |
* |
|
156 |
* @return pid - the identifier of the object used for the deletion |
|
157 |
* |
|
158 |
* @throws InvalidToken |
|
159 |
* @throws ServiceFailure |
|
160 |
* @throws NotAuthorized |
|
161 |
* @throws NotFound |
|
162 |
* @throws NotImplemented |
|
163 |
* @throws InvalidRequest |
|
164 |
*/ |
|
165 |
@Override |
|
166 |
public Identifier delete(Session session, Identifier pid) |
|
167 |
throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented, InvalidRequest { |
|
168 |
|
|
169 |
String localId = null; |
|
170 |
boolean allowed = false; |
|
171 |
String username = Constants.PUBLIC_SUBJECT; |
|
172 |
String[] groupnames = null; |
|
173 |
if (session != null) { |
|
174 |
username = session.getSubject().getValue(); |
|
175 |
if (session.getSubjectList() != null) { |
|
176 |
List<Group> groupList = session.getSubjectList().getGroupList(); |
|
177 |
if (groupList != null) { |
|
178 |
groupnames = new String[groupList.size()]; |
|
179 |
for (int i = 0; i > groupList.size(); i++) { |
|
180 |
groupnames[i] = groupList.get(i).getGroupName(); |
|
181 |
} |
|
182 |
} |
|
183 |
} |
|
184 |
} |
|
185 |
|
|
186 |
// do we have a valid pid? |
|
187 |
if (pid == null || pid.getValue().trim().equals("")) { |
|
188 |
throw new InvalidRequest("1322", "The provided identifier was invalid."); |
|
189 |
} |
|
190 |
|
|
191 |
// check for the existing identifier |
|
192 |
try { |
|
193 |
localId = IdentifierManager.getInstance().getLocalId(pid.getValue()); |
|
194 |
} catch (McdbDocNotFoundException e) { |
|
195 |
throw new InvalidRequest("1322", "The object with the provided " + "identifier was not found."); |
|
196 |
} |
|
197 |
|
|
198 |
// does the subject have DELETE (a D1 CHANGE_PERMISSION level) priveleges on the pid? |
|
199 |
allowed = isAuthorized(session, pid, Permission.CHANGE_PERMISSION); |
|
200 |
|
|
201 |
if (allowed) { |
|
202 |
try { |
|
203 |
// delete the document |
|
204 |
DocumentImpl.delete(localId, username, groupnames, null); |
|
205 |
EventLog.getInstance().log(metacatUrl, username, localId, Event.DELETE.xmlValue()); |
|
206 |
|
|
207 |
} catch (McdbDocNotFoundException e) { |
|
208 |
throw new InvalidRequest("1322", "The provided identifier was invalid."); |
|
209 |
|
|
210 |
} catch (SQLException e) { |
|
211 |
throw new ServiceFailure("1350", "There was a problem deleting the object." + "The error message was: " + e.getMessage()); |
|
212 |
|
|
213 |
} catch (InsufficientKarmaException e) { |
|
214 |
throw new NotAuthorized("1320", "The provided identity does not have " + "permission to DELETE objects on the Member Node."); |
|
215 |
|
|
216 |
} catch (Exception e) { // for some reason DocumentImpl throws a general Exception |
|
217 |
throw new ServiceFailure("1350", "There was a problem deleting the object." + "The error message was: " + e.getMessage()); |
|
218 |
} |
|
219 |
|
|
220 |
} else { |
|
221 |
throw new NotAuthorized("1320", "The provided identity does not have " + "permission to DELETE objects on the Member Node."); |
|
222 |
} |
|
223 |
|
|
224 |
return pid; |
|
195 | 225 |
} |
196 | 226 |
|
197 |
// check for the existing identifier |
|
198 |
try { |
|
199 |
localId = IdentifierManager.getInstance().getLocalId(pid.getValue()); |
|
200 |
|
|
201 |
} catch (McdbDocNotFoundException e) { |
|
202 |
throw new InvalidRequest("1322", "The object with the provided " + |
|
203 |
"identifier was not found."); |
|
227 |
/** |
|
228 |
* Updates an existing object by creating a new object identified by |
|
229 |
* newPid on the Member Node which explicitly obsoletes the object |
|
230 |
* identified by pid through appropriate changes to the SystemMetadata |
|
231 |
* of pid and newPid |
|
232 |
* |
|
233 |
* @param session - the Session object containing the credentials for the Subject |
|
234 |
* @param pid - The identifier of the object to be updated |
|
235 |
* @param object - the new object bytes |
|
236 |
* @param sysmeta - the new system metadata describing the object |
|
237 |
* |
|
238 |
* @return newPid - the identifier of the new object |
|
239 |
* |
|
240 |
* @throws InvalidToken |
|
241 |
* @throws ServiceFailure |
|
242 |
* @throws NotAuthorized |
|
243 |
* @throws NotFound |
|
244 |
* @throws NotImplemented |
|
245 |
* @throws IdentifierNotUnique |
|
246 |
* @throws UnsupportedType |
|
247 |
* @throws InsufficientResources |
|
248 |
* @throws InvalidSystemMetadata |
|
249 |
* @throws InvalidRequest |
|
250 |
*/ |
|
251 |
@Override |
|
252 |
public Identifier update(Session session, Identifier pid, InputStream object, Identifier newPid, SystemMetadata sysmeta) throws InvalidToken, |
|
253 |
ServiceFailure, NotAuthorized, IdentifierNotUnique, UnsupportedType, InsufficientResources, NotFound, InvalidSystemMetadata, NotImplemented, |
|
254 |
InvalidRequest { |
|
204 | 255 |
|
256 |
// check if the pid has been reserved |
|
257 |
try { |
|
258 |
boolean hasReservation = D1Client.getCN().hasReservation(session, pid); |
|
259 |
if (!hasReservation) { |
|
260 |
throw new NotAuthorized("", "No reservation for pid: " + pid.getValue()); |
|
261 |
} |
|
262 |
} catch (NotFound e) { |
|
263 |
// okay to continue |
|
264 |
} |
|
265 |
|
|
266 |
String localId = null; |
|
267 |
boolean allowed = false; |
|
268 |
boolean isScienceMetadata = false; |
|
269 |
Subject subject = session.getSubject(); |
|
270 |
|
|
271 |
// do we have a valid pid? |
|
272 |
if (pid == null || pid.getValue().trim().equals("")) { |
|
273 |
throw new InvalidRequest("1202", "The provided identifier was invalid."); |
|
274 |
} |
|
275 |
|
|
276 |
// check for the existing identifier |
|
277 |
try { |
|
278 |
localId = IdentifierManager.getInstance().getLocalId(pid.getValue()); |
|
279 |
} catch (McdbDocNotFoundException e) { |
|
280 |
throw new InvalidRequest("1202", "The object with the provided " + "identifier was not found."); |
|
281 |
} |
|
282 |
|
|
283 |
// does the subject have WRITE ( == update) priveleges on the pid? |
|
284 |
allowed = isAuthorized(session, pid, Permission.WRITE); |
|
285 |
|
|
286 |
if (allowed) { |
|
287 |
|
|
288 |
// get the existing system metadata for the object |
|
289 |
SystemMetadata existingSysMeta = getSystemMetadata(session, pid); |
|
290 |
|
|
291 |
// add the newPid to the obsoletedBy list for the existing sysmeta |
|
292 |
existingSysMeta.setObsoletedBy(newPid); |
|
293 |
|
|
294 |
// then update the existing system metadata |
|
295 |
updateSystemMetadata(existingSysMeta); |
|
296 |
|
|
297 |
// prep the new system metadata, add pid to the affected lists |
|
298 |
sysmeta.setObsoletes(pid); |
|
299 |
//sysmeta.addDerivedFrom(pid); |
|
300 |
|
|
301 |
isScienceMetadata = isScienceMetadata(sysmeta); |
|
302 |
|
|
303 |
// do we have XML metadata or a data object? |
|
304 |
if (isScienceMetadata) { |
|
305 |
|
|
306 |
// update the science metadata XML document |
|
307 |
// TODO: handle non-XML metadata/data documents (like netCDF) |
|
308 |
// TODO: don't put objects into memory using stream to string |
|
309 |
String objectAsXML = ""; |
|
310 |
try { |
|
311 |
objectAsXML = IOUtils.toString(object, "UTF-8"); |
|
312 |
localId = insertOrUpdateDocument(objectAsXML, newPid, session, "update"); |
|
313 |
// register the newPid and the generated localId |
|
314 |
if (newPid != null) { |
|
315 |
IdentifierManager.getInstance().createMapping(newPid.getValue(), localId); |
|
316 |
|
|
317 |
} |
|
318 |
|
|
319 |
} catch (IOException e) { |
|
320 |
String msg = "The Node is unable to create the object. " + "There was a problem converting the object to XML"; |
|
321 |
logMetacat.info(msg); |
|
322 |
throw new ServiceFailure("1310", msg + ": " + e.getMessage()); |
|
323 |
|
|
324 |
} |
|
325 |
|
|
326 |
} else { |
|
327 |
|
|
328 |
// update the data object |
|
329 |
localId = insertDataObject(object, newPid, session); |
|
330 |
|
|
331 |
} |
|
332 |
|
|
333 |
// and insert the new system metadata |
|
334 |
insertSystemMetadata(sysmeta); |
|
335 |
|
|
336 |
// log the update event |
|
337 |
EventLog.getInstance().log(metacatUrl, subject.getValue(), localId, "update"); |
|
338 |
|
|
339 |
} else { |
|
340 |
throw new NotAuthorized("1200", "The provided identity does not have " + "permission to UPDATE the object identified by " + pid.getValue() |
|
341 |
+ " on the Member Node."); |
|
342 |
} |
|
343 |
|
|
344 |
return newPid; |
|
205 | 345 |
} |
206 |
|
|
207 |
// does the subject have DELETE (a D1 CHANGE_PERMISSION level) priveleges on the pid? |
|
208 |
allowed = isAuthorized(session, pid, Permission.CHANGE_PERMISSION); |
|
209 |
|
|
210 |
if ( allowed ) { |
|
211 |
try { |
|
212 |
// delete the document |
|
213 |
DocumentImpl.delete(localId, username, groupnames, null); |
|
214 |
EventLog.getInstance().log(metacatUrl, username, localId, Event.DELETE.xmlValue()); |
|
215 | 346 |
|
216 |
} catch (McdbDocNotFoundException e) {
|
|
217 |
throw new InvalidRequest("1322", "The provided identifier was invalid.");
|
|
347 |
public Identifier create(Session session, Identifier pid, InputStream object, SystemMetadata sysmeta) throws InvalidToken, ServiceFailure, NotAuthorized,
|
|
348 |
IdentifierNotUnique, UnsupportedType, InsufficientResources, InvalidSystemMetadata, NotImplemented, InvalidRequest {
|
|
218 | 349 |
|
219 |
} catch (SQLException e) { |
|
220 |
throw new ServiceFailure("1350", "There was a problem deleting the object." + |
|
221 |
"The error message was: " + e.getMessage()); |
|
350 |
// check if the pid has been reserved |
|
351 |
try { |
|
352 |
boolean hasReservation = D1Client.getCN().hasReservation(session, pid); |
|
353 |
if (!hasReservation) { |
|
354 |
throw new NotAuthorized("", "No reservation for pid: " + pid.getValue()); |
|
355 |
} |
|
356 |
} catch (NotFound e) { |
|
357 |
// okay to continue |
|
358 |
} |
|
222 | 359 |
|
223 |
} catch (InsufficientKarmaException e) { |
|
224 |
throw new NotAuthorized("1320", "The provided identity does not have " + |
|
225 |
"permission to DELETE objects on the Member Node."); |
|
226 |
|
|
227 |
} catch (Exception e) { // for some reason DocumentImpl throws a general Exception |
|
228 |
throw new ServiceFailure("1350", "There was a problem deleting the object." + |
|
229 |
"The error message was: " + e.getMessage()); |
|
360 |
return super.create(session, pid, object, sysmeta); |
|
361 |
} |
|
230 | 362 |
|
231 |
} |
|
363 |
/** |
|
364 |
* Called by a Coordinating Node to request that the Member Node create a |
|
365 |
* copy of the specified object by retrieving it from another Member |
|
366 |
* Node and storing it locally so that it can be made accessible to |
|
367 |
* the DataONE system. |
|
368 |
* |
|
369 |
* @param session - the Session object containing the credentials for the Subject |
|
370 |
* @param sysmeta - Copy of the CN held system metadata for the object |
|
371 |
* @param sourceNode - A reference to node from which the content should be |
|
372 |
* retrieved. The reference should be resolved by |
|
373 |
* checking the CN node registry. |
|
374 |
* |
|
375 |
* @return true if the replication succeeds |
|
376 |
* |
|
377 |
* @throws ServiceFailure |
|
378 |
* @throws NotAuthorized |
|
379 |
* @throws NotImplemented |
|
380 |
* @throws UnsupportedType |
|
381 |
* @throws InsufficientResources |
|
382 |
* @throws InvalidRequest |
|
383 |
*/ |
|
384 |
@Override |
|
385 |
public boolean replicate(Session session, SystemMetadata sysmeta, NodeReference sourceNode) throws NotImplemented, ServiceFailure, NotAuthorized, |
|
386 |
InvalidRequest, InsufficientResources, UnsupportedType { |
|
232 | 387 |
|
233 |
} else { |
|
234 |
throw new NotAuthorized("1320", "The provided identity does not have " + |
|
235 |
"permission to DELETE objects on the Member Node."); |
|
236 |
|
|
388 |
boolean result = false; |
|
389 |
|
|
390 |
// TODO: check credentials |
|
391 |
|
|
392 |
// get the referenced object |
|
393 |
Identifier pid = sysmeta.getIdentifier(); |
|
394 |
|
|
395 |
// get from the membernode |
|
396 |
// TODO: switch credentials for the server retrieval? |
|
397 |
MNode mn = D1Client.getMN(sourceNode); |
|
398 |
InputStream object = null; |
|
399 |
|
|
400 |
try { |
|
401 |
object = mn.get(session, pid); |
|
402 |
} catch (InvalidToken e) { |
|
403 |
e.printStackTrace(); |
|
404 |
throw new ServiceFailure("2151", "Could not retrieve object to replicate (InvalidToken): " + e.getMessage()); |
|
405 |
} catch (NotFound e) { |
|
406 |
e.printStackTrace(); |
|
407 |
throw new ServiceFailure("2151", "Could not retrieve object to replicate (NotFound): " + e.getMessage()); |
|
408 |
} |
|
409 |
|
|
410 |
// add it to local store |
|
411 |
Identifier retPid; |
|
412 |
try { |
|
413 |
retPid = create(session, pid, object, sysmeta); |
|
414 |
result = (retPid.getValue().equals(pid.getValue())); |
|
415 |
} catch (InvalidToken e) { |
|
416 |
e.printStackTrace(); |
|
417 |
throw new ServiceFailure("2151", "Could not save object to local store (InvalidToken): " + e.getMessage()); |
|
418 |
} catch (IdentifierNotUnique e) { |
|
419 |
e.printStackTrace(); |
|
420 |
throw new ServiceFailure("2151", "Could not save object to local store (IdentifierNotUnique): " + e.getMessage()); |
|
421 |
} catch (InvalidSystemMetadata e) { |
|
422 |
e.printStackTrace(); |
|
423 |
throw new ServiceFailure("2151", "Could not save object to local store (InvalidSystemMetadata): " + e.getMessage()); |
|
424 |
} |
|
425 |
|
|
426 |
return result; |
|
427 |
|
|
237 | 428 |
} |
238 |
|
|
239 |
return pid; |
|
240 |
} |
|
241 | 429 |
|
430 |
/** |
|
431 |
* This method provides a lighter weight mechanism than |
|
432 |
* MN_read.getSystemMetadata() for a client to determine basic |
|
433 |
* properties of the referenced object. |
|
434 |
* |
|
435 |
* @param session - the Session object containing the credentials for the Subject |
|
436 |
* @param pid - the identifier of the object to be described |
|
437 |
* |
|
438 |
* @return describeResponse - A set of values providing a basic description |
|
439 |
* of the object. |
|
440 |
* |
|
441 |
* @throws InvalidToken |
|
442 |
* @throws ServiceFailure |
|
443 |
* @throws NotAuthorized |
|
444 |
* @throws NotFound |
|
445 |
* @throws NotImplemented |
|
446 |
* @throws InvalidRequest |
|
447 |
*/ |
|
448 |
@Override |
|
449 |
public DescribeResponse describe(Session session, Identifier pid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented, |
|
450 |
InvalidRequest { |
|
242 | 451 |
|
243 |
/** |
|
244 |
* Updates an existing object by creating a new object identified by |
|
245 |
* newPid on the Member Node which explicitly obsoletes the object |
|
246 |
* identified by pid through appropriate changes to the SystemMetadata |
|
247 |
* of pid and newPid |
|
248 |
* |
|
249 |
* @param session - the Session object containing the credentials for the Subject |
|
250 |
* @param pid - The identifier of the object to be updated |
|
251 |
* @param object - the new object bytes |
|
252 |
* @param sysmeta - the new system metadata describing the object |
|
253 |
* |
|
254 |
* @return newPid - the identifier of the new object |
|
255 |
* |
|
256 |
* @throws InvalidToken |
|
257 |
* @throws ServiceFailure |
|
258 |
* @throws NotAuthorized |
|
259 |
* @throws NotFound |
|
260 |
* @throws NotImplemented |
|
261 |
* @throws IdentifierNotUnique |
|
262 |
* @throws UnsupportedType |
|
263 |
* @throws InsufficientResources |
|
264 |
* @throws InvalidSystemMetadata |
|
265 |
* @throws InvalidRequest |
|
266 |
*/ |
|
267 |
@Override |
|
268 |
public Identifier update(Session session, Identifier pid, InputStream object, |
|
269 |
Identifier newPid, SystemMetadata sysmeta) |
|
270 |
throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, |
|
271 |
UnsupportedType, InsufficientResources, NotFound, InvalidSystemMetadata, |
|
272 |
NotImplemented, InvalidRequest { |
|
273 |
|
|
274 |
// check if the pid has been reserved |
|
275 |
try { |
|
276 |
boolean hasReservation = D1Client.getCN().hasReservation(session, pid); |
|
277 |
if (!hasReservation) { |
|
278 |
throw new NotAuthorized("", "No reservation for pid: " + pid.getValue()); |
|
279 |
} |
|
280 |
} catch (NotFound e) { |
|
281 |
// okay to continue |
|
282 |
} |
|
452 |
if (session == null) { |
|
453 |
throw new InvalidToken("1370", "The session object is null"); |
|
454 |
} |
|
283 | 455 |
|
284 |
String localId = null; |
|
285 |
boolean allowed = false; |
|
286 |
boolean isScienceMetadata = false; |
|
287 |
Subject subject = session.getSubject(); |
|
288 |
|
|
289 |
// do we have a valid pid? |
|
290 |
if ( pid == null || pid.getValue().trim().equals("") ) { |
|
291 |
throw new InvalidRequest("1202", "The provided identifier was invalid."); |
|
456 |
if (pid == null || pid.getValue().trim().equals("")) { |
|
457 |
throw new InvalidRequest("1362", "The object identifier is null. " + "A valid identifier is required."); |
|
458 |
} |
|
292 | 459 |
|
460 |
SystemMetadata sysmeta = getSystemMetadata(session, pid); |
|
461 |
DescribeResponse describeResponse = new DescribeResponse(sysmeta.getFmtid(), sysmeta.getSize(), sysmeta.getDateSysMetadataModified(), |
|
462 |
sysmeta.getChecksum()); |
|
463 |
|
|
464 |
return describeResponse; |
|
465 |
|
|
293 | 466 |
} |
294 | 467 |
|
295 |
// check for the existing identifier |
|
296 |
try { |
|
297 |
localId = IdentifierManager.getInstance().getLocalId(pid.getValue()); |
|
468 |
/** |
|
469 |
* Return the object identified by the given object identifier |
|
470 |
* |
|
471 |
* @param session - the Session object containing the credentials for the Subject |
|
472 |
* @param pid - the object identifier for the given object |
|
473 |
* |
|
474 |
* @return inputStream - the input stream of the given object |
|
475 |
* |
|
476 |
* @throws InvalidToken |
|
477 |
* @throws ServiceFailure |
|
478 |
* @throws NotAuthorized |
|
479 |
* @throws InvalidRequest |
|
480 |
* @throws NotImplemented |
|
481 |
*/ |
|
482 |
@Override |
|
483 |
public InputStream get(Session session, Identifier pid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented, InvalidRequest { |
|
298 | 484 |
|
299 |
} catch (McdbDocNotFoundException e) { |
|
300 |
throw new InvalidRequest("1202", "The object with the provided " + |
|
301 |
"identifier was not found."); |
|
485 |
return super.get(session, pid); |
|
302 | 486 |
|
303 | 487 |
} |
304 | 488 |
|
305 |
// does the subject have WRITE ( == update) priveleges on the pid? |
|
306 |
allowed = isAuthorized(session, pid, Permission.WRITE); |
|
489 |
/** |
|
490 |
* Returns a Checksum for the specified object using an accepted hashing algorithm |
|
491 |
* |
|
492 |
* @param session - the Session object containing the credentials for the Subject |
|
493 |
* @param pid - the object identifier for the given object |
|
494 |
* @param algorithm - the name of an algorithm that will be used to compute |
|
495 |
* a checksum of the bytes of the object |
|
496 |
* |
|
497 |
* @return checksum - the checksum of the given object |
|
498 |
* |
|
499 |
* @throws InvalidToken |
|
500 |
* @throws ServiceFailure |
|
501 |
* @throws NotAuthorized |
|
502 |
* @throws NotFound |
|
503 |
* @throws InvalidRequest |
|
504 |
* @throws NotImplemented |
|
505 |
*/ |
|
506 |
@Override |
|
507 |
public Checksum getChecksum(Session session, Identifier pid, String algorithm) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, |
|
508 |
InvalidRequest, NotImplemented { |
|
307 | 509 |
|
308 |
if ( allowed ) { |
|
309 |
|
|
310 |
// get the existing system metadata for the object |
|
311 |
SystemMetadata existingSysMeta = getSystemMetadata(session, pid); |
|
312 |
|
|
313 |
// add the newPid to the obsoletedBy list for the existing sysmeta |
|
314 |
existingSysMeta.setObsoletedBy(newPid); |
|
315 |
|
|
316 |
// then update the existing system metadata |
|
317 |
updateSystemMetadata(existingSysMeta); |
|
318 |
|
|
319 |
// prep the new system metadata, add pid to the affected lists |
|
320 |
sysmeta.setObsoletes(pid); |
|
321 |
//sysmeta.addDerivedFrom(pid); |
|
322 |
|
|
323 |
isScienceMetadata = isScienceMetadata(sysmeta); |
|
324 |
|
|
325 |
// do we have XML metadata or a data object? |
|
326 |
if ( isScienceMetadata ) { |
|
327 |
|
|
328 |
// update the science metadata XML document |
|
329 |
// TODO: handle non-XML metadata/data documents (like netCDF) |
|
330 |
// TODO: don't put objects into memory using stream to string |
|
331 |
String objectAsXML = ""; |
|
510 |
Checksum checksum = null; |
|
511 |
|
|
512 |
InputStream inputStream = get(session, pid); |
|
513 |
|
|
332 | 514 |
try { |
333 |
objectAsXML = IOUtils.toString(object, "UTF-8"); |
|
334 |
localId = insertOrUpdateDocument(objectAsXML, newPid, session, "update"); |
|
335 |
// register the newPid and the generated localId |
|
336 |
if ( newPid != null ) { |
|
337 |
IdentifierManager.getInstance().createMapping(newPid.getValue(), localId); |
|
338 |
|
|
339 |
} |
|
340 |
|
|
515 |
checksum = ChecksumUtil.checksum(inputStream, algorithm); |
|
516 |
|
|
517 |
} catch (NoSuchAlgorithmException e) { |
|
518 |
throw new ServiceFailure("1410", "The checksum for the object specified by " + pid.getValue() + "could not be returned due to an internal error: " |
|
519 |
+ e.getMessage()); |
|
341 | 520 |
} catch (IOException e) { |
342 |
String msg = "The Node is unable to create the object. " + |
|
343 |
"There was a problem converting the object to XML"; |
|
344 |
logMetacat.info(msg); |
|
345 |
throw new ServiceFailure("1310", msg + ": " + e.getMessage()); |
|
346 |
|
|
521 |
throw new ServiceFailure("1410", "The checksum for the object specified by " + pid.getValue() + "could not be returned due to an internal error: " |
|
522 |
+ e.getMessage()); |
|
347 | 523 |
} |
348 |
|
|
349 |
} else { |
|
350 |
|
|
351 |
// update the data object |
|
352 |
localId = insertDataObject(object, newPid, session); |
|
353 |
|
|
354 |
} |
|
355 |
|
|
356 |
// and insert the new system metadata |
|
357 |
insertSystemMetadata(sysmeta); |
|
358 | 524 |
|
359 |
// log the update event |
|
360 |
EventLog.getInstance().log(metacatUrl, subject.getValue(), localId, "update"); |
|
525 |
if (checksum == null) { |
|
526 |
throw new ServiceFailure("1410", "The checksum for the object specified by " + pid.getValue() + "could not be returned."); |
|
527 |
} |
|
361 | 528 |
|
362 |
} else { |
|
363 |
throw new NotAuthorized("1200", "The provided identity does not have " + |
|
364 |
"permission to UPDATE the object identified by " + |
|
365 |
pid.getValue() + " on the Member Node."); |
|
366 |
|
|
529 |
return checksum; |
|
367 | 530 |
} |
368 |
|
|
369 |
return newPid; |
|
370 |
} |
|
371 |
|
|
372 |
public Identifier create(Session session, Identifier pid, |
|
373 |
InputStream object, SystemMetadata sysmeta) throws InvalidToken, |
|
374 |
ServiceFailure, NotAuthorized, IdentifierNotUnique, |
|
375 |
UnsupportedType, InsufficientResources, InvalidSystemMetadata, |
|
376 |
NotImplemented, InvalidRequest { |
|
377 | 531 |
|
378 |
// check if the pid has been reserved |
|
379 |
try { |
|
380 |
boolean hasReservation = D1Client.getCN().hasReservation(session, pid); |
|
381 |
if (!hasReservation) { |
|
382 |
throw new NotAuthorized("", "No reservation for pid: " + pid.getValue()); |
|
383 |
} |
|
384 |
} catch (NotFound e) { |
|
385 |
// okay to continue |
|
386 |
} |
|
532 |
/** |
|
533 |
* Return the system metadata for a given object |
|
534 |
* |
|
535 |
* @param session - the Session object containing the credentials for the Subject |
|
536 |
* @param pid - the object identifier for the given object |
|
537 |
* |
|
538 |
* @return inputStream - the input stream of the given system metadata object |
|
539 |
* |
|
540 |
* @throws InvalidToken |
|
541 |
* @throws ServiceFailure |
|
542 |
* @throws NotAuthorized |
|
543 |
* @throws NotFound |
|
544 |
* @throws InvalidRequest |
|
545 |
* @throws NotImplemented |
|
546 |
*/ |
|
547 |
@Override |
|
548 |
public SystemMetadata getSystemMetadata(Session session, Identifier pid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, InvalidRequest, |
|
549 |
NotImplemented { |
|
387 | 550 |
|
388 |
return super.create(session, pid, object, sysmeta);
|
|
389 |
}
|
|
551 |
return super.getSystemMetadata(session, pid);
|
|
552 |
}
|
|
390 | 553 |
|
391 |
/** |
|
392 |
* Called by a Coordinating Node to request that the Member Node create a |
|
393 |
* copy of the specified object by retrieving it from another Member |
|
394 |
* Node and storing it locally so that it can be made accessible to |
|
395 |
* the DataONE system. |
|
396 |
* |
|
397 |
* @param session - the Session object containing the credentials for the Subject |
|
398 |
* @param sysmeta - Copy of the CN held system metadata for the object |
|
399 |
* @param sourceNode - A reference to node from which the content should be |
|
400 |
* retrieved. The reference should be resolved by |
|
401 |
* checking the CN node registry. |
|
402 |
* |
|
403 |
* @return true if the replication succeeds |
|
404 |
* |
|
405 |
* @throws ServiceFailure |
|
406 |
* @throws NotAuthorized |
|
407 |
* @throws NotImplemented |
|
408 |
* @throws UnsupportedType |
|
409 |
* @throws InsufficientResources |
|
410 |
* @throws InvalidRequest |
|
411 |
*/ |
|
412 |
@Override |
|
413 |
public boolean replicate(Session session, SystemMetadata sysmeta, |
|
414 |
NodeReference sourceNode) |
|
415 |
throws NotImplemented, ServiceFailure, NotAuthorized, InvalidRequest, |
|
416 |
InsufficientResources, UnsupportedType { |
|
554 |
/** |
|
555 |
* Retrieve the list of objects present on the MN that match the calling parameters |
|
556 |
* |
|
557 |
* @param session - the Session object containing the credentials for the Subject |
|
558 |
* @param startTime - Specifies the beginning of the time range from which |
|
559 |
* to return object (>=) |
|
560 |
* @param endTime - Specifies the beginning of the time range from which |
|
561 |
* to return object (>=) |
|
562 |
* @param objectFormat - Restrict results to the specified object format |
|
563 |
* @param replicaStatus - Indicates if replicated objects should be returned in the list |
|
564 |
* @param start - The zero-based index of the first value, relative to the |
|
565 |
* first record of the resultset that matches the parameters. |
|
566 |
* @param count - The maximum number of entries that should be returned in |
|
567 |
* the response. The Member Node may return less entries |
|
568 |
* than specified in this value. |
|
569 |
* |
|
570 |
* @return objectList - the list of objects matching the criteria |
|
571 |
* |
|
572 |
* @throws InvalidToken |
|
573 |
* @throws ServiceFailure |
|
574 |
* @throws NotAuthorized |
|
575 |
* @throws InvalidRequest |
|
576 |
* @throws NotImplemented |
|
577 |
*/ |
|
578 |
@Override |
|
579 |
public ObjectList listObjects(Session session, Date startTime, Date endTime, ObjectFormatIdentifier objectFormatId, Boolean replicaStatus, Integer start, |
|
580 |
Integer count) throws NotAuthorized, InvalidRequest, NotImplemented, ServiceFailure, InvalidToken { |
|
417 | 581 |
|
418 |
boolean result = false;
|
|
582 |
ObjectList objectList = null;
|
|
419 | 583 |
|
420 |
// TODO: check credentials |
|
421 |
|
|
422 |
// get the referenced object |
|
423 |
Identifier pid = sysmeta.getIdentifier(); |
|
424 |
|
|
425 |
// get from the membernode |
|
426 |
// TODO: switch credentials for the server retrieval? |
|
427 |
MNode mn = D1Client.getMN(sourceNode); |
|
428 |
InputStream object = null; |
|
584 |
try { |
|
585 |
objectList = IdentifierManager.getInstance().querySystemMetadata(startTime, endTime, objectFormatId, replicaStatus, start, count); |
|
586 |
} catch (Exception e) { |
|
587 |
throw new ServiceFailure("1580", "Error querying system metadata: " + e.getMessage()); |
|
588 |
} |
|
429 | 589 |
|
430 |
try { |
|
431 |
object = mn.get(session, pid); |
|
432 |
} catch (InvalidToken e) { |
|
433 |
e.printStackTrace(); |
|
434 |
throw new ServiceFailure("2151", "Could not retrieve object to replicate (InvalidToken): " + e.getMessage()); |
|
435 |
} catch (NotFound e) { |
|
436 |
e.printStackTrace(); |
|
437 |
throw new ServiceFailure("2151", "Could not retrieve object to replicate (NotFound): " + e.getMessage()); |
|
438 |
} |
|
439 |
|
|
440 |
// add it to local store |
|
441 |
Identifier retPid; |
|
442 |
try { |
|
443 |
retPid = create(session, pid, object, sysmeta); |
|
444 |
result = (retPid.getValue().equals(pid.getValue())); |
|
445 |
} catch (InvalidToken e) { |
|
446 |
e.printStackTrace(); |
|
447 |
throw new ServiceFailure("2151", "Could not save object to local store (InvalidToken): " + e.getMessage()); |
|
448 |
} catch (IdentifierNotUnique e) { |
|
449 |
e.printStackTrace(); |
|
450 |
throw new ServiceFailure("2151", "Could not save object to local store (IdentifierNotUnique): " + e.getMessage()); |
|
451 |
} catch (InvalidSystemMetadata e) { |
|
452 |
e.printStackTrace(); |
|
453 |
throw new ServiceFailure("2151", "Could not save object to local store (InvalidSystemMetadata): " + e.getMessage()); |
|
454 |
} |
|
455 |
|
|
456 |
return result; |
|
457 |
|
|
458 |
} |
|
459 |
|
|
460 |
/** |
|
461 |
* This method provides a lighter weight mechanism than |
|
462 |
* MN_read.getSystemMetadata() for a client to determine basic |
|
463 |
* properties of the referenced object. |
|
464 |
* |
|
465 |
* @param session - the Session object containing the credentials for the Subject |
|
466 |
* @param pid - the identifier of the object to be described |
|
467 |
* |
|
468 |
* @return describeResponse - A set of values providing a basic description |
|
469 |
* of the object. |
|
470 |
* |
|
471 |
* @throws InvalidToken |
|
472 |
* @throws ServiceFailure |
|
473 |
* @throws NotAuthorized |
|
474 |
* @throws NotFound |
|
475 |
* @throws NotImplemented |
|
476 |
* @throws InvalidRequest |
|
477 |
*/ |
|
478 |
@Override |
|
479 |
public DescribeResponse describe(Session session, Identifier pid) |
|
480 |
throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, |
|
481 |
NotImplemented, InvalidRequest { |
|
482 |
|
|
483 |
if(session == null) { |
|
484 |
throw new InvalidToken("1370", "The session object is null"); |
|
485 |
|
|
590 |
return objectList; |
|
486 | 591 |
} |
487 |
|
|
488 |
if(pid == null || pid.getValue().trim().equals("")) |
|
489 |
{ |
|
490 |
throw new InvalidRequest("1362", "The object identifier is null. " + |
|
491 |
"A valid identifier is required."); |
|
492 |
|
|
493 |
} |
|
494 |
|
|
495 |
SystemMetadata sysmeta = getSystemMetadata(session, pid); |
|
496 |
DescribeResponse describeResponse = |
|
497 |
new DescribeResponse(sysmeta.getFmtid(), |
|
498 |
sysmeta.getSize(), sysmeta.getDateSysMetadataModified(), sysmeta.getChecksum()); |
|
499 |
|
|
500 |
return describeResponse; |
|
501 | 592 |
|
502 |
} |
|
593 |
/** |
|
594 |
* Retrieve the list of objects present on the MN that match the calling parameters |
|
595 |
* |
|
596 |
* @return node - the technical capabilities of the Member Node |
|
597 |
* |
|
598 |
* @throws ServiceFailure |
|
599 |
* @throws NotAuthorized |
|
600 |
* @throws InvalidRequest |
|
601 |
* @throws NotImplemented |
|
602 |
*/ |
|
603 |
@Override |
|
604 |
public Node getCapabilities() throws NotImplemented, NotAuthorized, ServiceFailure, InvalidRequest { |
|
503 | 605 |
|
504 |
/** |
|
505 |
* Return the object identified by the given object identifier |
|
506 |
* |
|
507 |
* @param session - the Session object containing the credentials for the Subject |
|
508 |
* @param pid - the object identifier for the given object |
|
509 |
* |
|
510 |
* @return inputStream - the input stream of the given object |
|
511 |
* |
|
512 |
* @throws InvalidToken |
|
513 |
* @throws ServiceFailure |
|
514 |
* @throws NotAuthorized |
|
515 |
* @throws InvalidRequest |
|
516 |
* @throws NotImplemented |
|
517 |
*/ |
|
518 |
@Override |
|
519 |
public InputStream get(Session session, Identifier pid) |
|
520 |
throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, |
|
521 |
NotImplemented, InvalidRequest { |
|
522 |
|
|
523 |
return super.get(session, pid); |
|
524 |
|
|
525 |
} |
|
606 |
String nodeName = null; |
|
607 |
String nodeId = null; |
|
608 |
String nodeUrl = null; |
|
609 |
String nodeDesc = null; |
|
610 |
String nodeType = null; |
|
611 |
String mnCoreServiceVersion = null; |
|
612 |
String mnReadServiceVersion = null; |
|
613 |
String mnAuthorizationServiceVersion = null; |
|
614 |
String mnStorageServiceVersion = null; |
|
615 |
String mnReplicationServiceVersion = null; |
|
526 | 616 |
|
527 |
/** |
|
528 |
* Returns a Checksum for the specified object using an accepted hashing algorithm |
|
529 |
* |
|
530 |
* @param session - the Session object containing the credentials for the Subject |
|
531 |
* @param pid - the object identifier for the given object |
|
532 |
* @param algorithm - the name of an algorithm that will be used to compute |
|
533 |
* a checksum of the bytes of the object |
|
534 |
* |
|
535 |
* @return checksum - the checksum of the given object |
|
536 |
* |
|
537 |
* @throws InvalidToken |
|
538 |
* @throws ServiceFailure |
|
539 |
* @throws NotAuthorized |
|
540 |
* @throws NotFound |
|
541 |
* @throws InvalidRequest |
|
542 |
* @throws NotImplemented |
|
543 |
*/ |
|
544 |
@Override |
|
545 |
public Checksum getChecksum(Session session, Identifier pid, String algorithm) |
|
546 |
throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, |
|
547 |
InvalidRequest, NotImplemented { |
|
617 |
boolean nodeSynchronize = false; |
|
618 |
boolean nodeReplicate = false; |
|
619 |
boolean mnCoreServiceAvailable = false; |
|
620 |
boolean mnReadServiceAvailable = false; |
|
621 |
boolean mnAuthorizationServiceAvailable = false; |
|
622 |
boolean mnStorageServiceAvailable = false; |
|
623 |
boolean mnReplicationServiceAvailable = false; |
|
548 | 624 |
|
549 |
Checksum checksum = null; |
|
550 |
|
|
551 |
InputStream inputStream = get(session, pid); |
|
552 |
|
|
553 |
try { |
|
554 |
checksum = |
|
555 |
ChecksumUtil.checksum(inputStream, algorithm); |
|
556 |
|
|
557 |
} catch (NoSuchAlgorithmException e) { |
|
558 |
throw new ServiceFailure("1410", "The checksum for the object specified by " + |
|
559 |
pid.getValue() + |
|
560 |
"could not be returned due to an internal error: " + |
|
561 |
e.getMessage()); |
|
562 |
|
|
563 |
} catch (IOException e) { |
|
564 |
throw new ServiceFailure("1410", "The checksum for the object specified by " + |
|
565 |
pid.getValue() + |
|
566 |
"could not be returned due to an internal error: " + |
|
567 |
e.getMessage()); |
|
568 |
|
|
625 |
try { |
|
626 |
// get the properties of the node based on configuration information |
|
627 |
nodeId = PropertyService.getProperty("dataone.memberNodeId"); |
|
628 |
nodeName = PropertyService.getProperty("dataone.nodeName"); |
|
629 |
nodeUrl = SystemUtil.getContextURL() + "/d1/"; |
|
630 |
nodeDesc = PropertyService.getProperty("dataone.nodeDescription"); |
|
631 |
nodeType = PropertyService.getProperty("dataone.nodeType"); |
|
632 |
nodeSynchronize = new Boolean(PropertyService.getProperty("dataone.nodeSynchronize")).booleanValue(); |
|
633 |
nodeReplicate = new Boolean(PropertyService.getProperty("dataone.nodeReplicate")).booleanValue(); |
|
634 |
|
|
635 |
mnCoreServiceVersion = PropertyService.getProperty("dataone.mnCore.serviceVersion"); |
|
636 |
mnReadServiceVersion = PropertyService.getProperty("dataone.mnRead.serviceVersion"); |
|
637 |
mnAuthorizationServiceVersion = PropertyService.getProperty("dataone.mnAuthorization.serviceVersion"); |
|
638 |
mnStorageServiceVersion = PropertyService.getProperty("dataone.mnStorage.serviceVersion"); |
|
639 |
mnReplicationServiceVersion = PropertyService.getProperty("dataone.mnReplication.serviceVersion"); |
|
640 |
|
|
641 |
mnCoreServiceAvailable = new Boolean(PropertyService.getProperty("dataone.mnCore.serviceAvailable")).booleanValue(); |
|
642 |
mnReadServiceAvailable = new Boolean(PropertyService.getProperty("dataone.mnRead.serviceAvailable")).booleanValue(); |
|
643 |
mnAuthorizationServiceAvailable = new Boolean(PropertyService.getProperty("dataone.mnAuthorization.serviceAvailable")).booleanValue(); |
|
644 |
mnStorageServiceAvailable = new Boolean(PropertyService.getProperty("dataone.mnStorage.serviceAvailable")).booleanValue(); |
|
645 |
mnReplicationServiceAvailable = new Boolean(PropertyService.getProperty("dataone.mnReplication.serviceAvailable")).booleanValue(); |
|
646 |
|
|
647 |
} catch (PropertyNotFoundException pnfe) { |
|
648 |
logMetacat.error("MNodeService.getCapabilities(): " + "property not found: " + pnfe.getMessage()); |
|
649 |
|
|
650 |
} |
|
651 |
|
|
652 |
// Set the properties of the node based on configuration information and |
|
653 |
// calls to current status methods |
|
654 |
Node node = new Node(); |
|
655 |
node.setBaseURL(metacatUrl + "/" + nodeType); |
|
656 |
node.setDescription(nodeDesc); |
|
657 |
|
|
658 |
// set the node's health information |
|
659 |
NodeState state = NodeState.UP; |
|
660 |
node.setState(state); |
|
661 |
// set the ping response to the current value |
|
662 |
Ping canPing = new Ping(); |
|
663 |
canPing.setSuccess(false); |
|
664 |
try { |
|
665 |
canPing.setSuccess(ping()); |
|
666 |
} catch (InsufficientResources e) { |
|
667 |
e.printStackTrace(); |
|
668 |
|
|
669 |
} catch (UnsupportedType e) { |
|
670 |
e.printStackTrace(); |
|
671 |
|
|
672 |
} |
|
673 |
node.setPing(canPing); |
|
674 |
|
|
675 |
NodeReference identifier = new NodeReference(); |
|
676 |
identifier.setValue(nodeId); |
|
677 |
node.setIdentifier(identifier); |
|
678 |
node.setName(nodeName + " -- WAR version WARVERSION"); |
|
679 |
node.setReplicate(new Boolean(nodeReplicate).booleanValue()); |
|
680 |
node.setSynchronize(new Boolean(nodeSynchronize).booleanValue()); |
|
681 |
|
|
682 |
// services: MNAuthorization, MNCore, MNRead, MNReplication, MNStorage |
|
683 |
Services services = new Services(); |
|
684 |
|
|
685 |
Service sMNCore = new Service(); |
|
686 |
sMNCore.setName("MNCore"); |
|
687 |
sMNCore.setVersion(mnCoreServiceVersion); |
|
688 |
sMNCore.setAvailable(mnCoreServiceAvailable); |
|
689 |
|
|
690 |
Service sMNRead = new Service(); |
|
691 |
sMNRead.setName("MNRead"); |
|
692 |
sMNRead.setVersion(mnReadServiceVersion); |
|
693 |
sMNRead.setAvailable(mnReadServiceAvailable); |
|
694 |
|
|
695 |
Service sMNAuthorization = new Service(); |
|
696 |
sMNAuthorization.setName("MNAuthorization"); |
|
697 |
sMNAuthorization.setVersion(mnAuthorizationServiceVersion); |
|
698 |
sMNAuthorization.setAvailable(mnAuthorizationServiceAvailable); |
|
699 |
|
|
700 |
Service sMNStorage = new Service(); |
|
701 |
sMNStorage.setName("MNStorage"); |
|
702 |
sMNStorage.setVersion(mnStorageServiceVersion); |
|
703 |
sMNStorage.setAvailable(mnStorageServiceAvailable); |
|
704 |
|
|
705 |
Service sMNReplication = new Service(); |
|
706 |
sMNReplication.setName("MNReplication"); |
|
707 |
sMNReplication.setVersion(mnReplicationServiceVersion); |
|
708 |
sMNReplication.setAvailable(mnReplicationServiceAvailable); |
|
709 |
|
|
710 |
services.addService(sMNRead); |
|
711 |
services.addService(sMNCore); |
|
712 |
services.addService(sMNAuthorization); |
|
713 |
services.addService(sMNStorage); |
|
714 |
services.addService(sMNReplication); |
|
715 |
node.setServices(services); |
|
716 |
|
|
717 |
// TODO: Determine the synchronization info without mock values |
|
718 |
Synchronization synchronization = new Synchronization(); |
|
719 |
Schedule schedule = new Schedule(); |
|
720 |
Date now = new Date(); |
|
721 |
schedule.setYear(new SimpleDateFormat("yyyy").format(now)); |
|
722 |
schedule.setMon(new SimpleDateFormat("MM").format(now)); |
|
723 |
schedule.setMday(new SimpleDateFormat("dd").format(now)); |
|
724 |
schedule.setWday(new SimpleDateFormat("dd").format(now)); |
|
725 |
schedule.setHour(new SimpleDateFormat("HH").format(now)); |
|
726 |
schedule.setMin(new SimpleDateFormat("mm").format(now)); |
|
727 |
schedule.setSec(new SimpleDateFormat("ss").format(now)); |
|
728 |
synchronization.setSchedule(schedule); |
|
729 |
synchronization.setLastHarvested(now); |
|
730 |
synchronization.setLastCompleteHarvest(now); |
|
731 |
node.setSynchronization(synchronization); |
|
732 |
node.setSynchronize(false); |
|
733 |
node.setType(NodeType.MN); |
|
734 |
|
|
735 |
return node; |
|
569 | 736 |
} |
570 |
|
|
571 |
if ( checksum == null ) { |
|
572 |
throw new ServiceFailure("1410", "The checksum for the object specified by " + |
|
573 |
pid.getValue() + |
|
574 |
"could not be returned."); |
|
575 |
|
|
576 |
} |
|
577 |
|
|
578 |
return checksum; |
|
579 |
} |
|
580 | 737 |
|
581 |
/** |
|
582 |
* Return the system metadata for a given object |
|
583 |
* |
|
584 |
* @param session - the Session object containing the credentials for the Subject |
|
585 |
* @param pid - the object identifier for the given object |
|
586 |
* |
|
587 |
* @return inputStream - the input stream of the given system metadata object |
|
588 |
* |
|
589 |
* @throws InvalidToken |
|
590 |
* @throws ServiceFailure |
|
591 |
* @throws NotAuthorized |
|
592 |
* @throws NotFound |
|
593 |
* @throws InvalidRequest |
|
594 |
* @throws NotImplemented |
|
595 |
*/ |
|
596 |
@Override |
|
597 |
public SystemMetadata getSystemMetadata(Session session, Identifier pid) |
|
598 |
throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, |
|
599 |
InvalidRequest, NotImplemented { |
|
738 |
/** |
|
739 |
* Returns the number of operations that have been serviced by the node |
|
740 |
* over time periods of one and 24 hours. |
|
741 |
* |
|
742 |
* @param session - the Session object containing the credentials for the Subject |
|
743 |
* @param period - An ISO8601 compatible DateTime range specifying the time |
|
744 |
* range for which to return operation statistics. |
|
745 |
* @param requestor - Limit to operations performed by given requestor identity. |
|
746 |
* @param event - Enumerated value indicating the type of event being examined |
|
747 |
* @param format - Limit to events involving objects of the specified format |
|
748 |
* |
|
749 |
* @return the desired log records |
|
750 |
* |
|
751 |
* @throws InvalidToken |
|
752 |
* @throws ServiceFailure |
|
753 |
* @throws NotAuthorized |
|
754 |
* @throws InvalidRequest |
|
755 |
* @throws NotImplemented |
|
756 |
*/ |
|
757 |
@Override |
|
758 |
public MonitorList getOperationStatistics(Session session, Date startTime, Date endTime, Subject requestor, Event event, ObjectFormatIdentifier formatId) |
|
759 |
throws NotImplemented, ServiceFailure, NotAuthorized, InvalidRequest, InsufficientResources, UnsupportedType { |
|
600 | 760 |
|
601 |
return super.getSystemMetadata(session, pid); |
|
602 |
} |
|
761 |
MonitorList monitorList = new MonitorList(); |
|
603 | 762 |
|
604 |
/** |
|
605 |
* Retrieve the list of objects present on the MN that match the calling parameters |
|
606 |
* |
|
607 |
* @param session - the Session object containing the credentials for the Subject |
|
608 |
* @param startTime - Specifies the beginning of the time range from which |
|
609 |
* to return object (>=) |
|
610 |
* @param endTime - Specifies the beginning of the time range from which |
|
611 |
* to return object (>=) |
|
612 |
* @param objectFormat - Restrict results to the specified object format |
|
613 |
* @param replicaStatus - Indicates if replicated objects should be returned in the list |
|
614 |
* @param start - The zero-based index of the first value, relative to the |
|
615 |
* first record of the resultset that matches the parameters. |
|
616 |
* @param count - The maximum number of entries that should be returned in |
|
617 |
* the response. The Member Node may return less entries |
|
618 |
* than specified in this value. |
|
619 |
* |
|
620 |
* @return objectList - the list of objects matching the criteria |
|
621 |
* |
|
622 |
* @throws InvalidToken |
|
623 |
* @throws ServiceFailure |
|
624 |
* @throws NotAuthorized |
|
625 |
* @throws InvalidRequest |
|
626 |
* @throws NotImplemented |
|
627 |
*/ |
|
628 |
@Override |
|
629 |
public ObjectList listObjects(Session session, Date startTime, Date endTime, |
|
630 |
ObjectFormatIdentifier objectFormatId, Boolean replicaStatus, Integer start, Integer count) |
|
631 |
throws NotAuthorized, InvalidRequest, NotImplemented, ServiceFailure, |
|
632 |
InvalidToken { |
|
763 |
try { |
|
633 | 764 |
|
634 |
ObjectList objectList = null; |
|
635 |
|
|
636 |
try { |
|
637 |
objectList = IdentifierManager.getInstance().querySystemMetadata(startTime, endTime, |
|
638 |
objectFormatId, replicaStatus, start, count); |
|
639 |
} catch (Exception e) { |
|
640 |
throw new ServiceFailure("1580", "Error querying system metadata: " + e.getMessage()); |
|
641 |
} |
|
642 |
|
|
643 |
return objectList; |
|
644 |
} |
|
765 |
// get log records first |
|
766 |
Log logs = getLogRecords(session, startTime, endTime, event, 0, null); |
|
645 | 767 |
|
646 |
/** |
|
647 |
* Retrieve the list of objects present on the MN that match the calling parameters |
|
648 |
* |
|
649 |
* @return node - the technical capabilities of the Member Node |
|
650 |
* |
|
651 |
* @throws ServiceFailure |
|
652 |
* @throws NotAuthorized |
|
653 |
* @throws InvalidRequest |
|
654 |
* @throws NotImplemented |
|
655 |
*/ |
|
656 |
@Override |
|
657 |
public Node getCapabilities() throws NotImplemented, NotAuthorized, |
|
658 |
ServiceFailure, InvalidRequest { |
|
659 |
|
|
660 |
String nodeName = null; |
|
661 |
String nodeId = null; |
|
662 |
String nodeUrl = null; |
|
663 |
String nodeDesc = null; |
|
664 |
String nodeType = null; |
|
665 |
String mnCoreServiceVersion = null; |
|
666 |
String mnReadServiceVersion = null; |
|
667 |
String mnAuthorizationServiceVersion = null; |
|
668 |
String mnStorageServiceVersion = null; |
|
669 |
String mnReplicationServiceVersion = null; |
|
768 |
// TODO: aggregate by day or hour -- needs clarification |
|
769 |
int count = 1; |
|
770 |
for (LogEntry logEntry : logs.getLogEntryList()) { |
|
771 |
Identifier pid = logEntry.getIdentifier(); |
|
772 |
Date logDate = logEntry.getDateLogged(); |
|
773 |
// if we are filtering by format |
|
774 |
if (formatId != null) { |
|
775 |
SystemMetadata sysmeta = IdentifierManager.getInstance().getSystemMetadata(pid.getValue()); |
|
776 |
if (!sysmeta.getFmtid().getValue().equals(formatId.getValue())) { |
|
777 |
// does not match |
|
778 |
continue; |
|
779 |
} |
|
780 |
} |
|
781 |
MonitorInfo item = new MonitorInfo(); |
|
782 |
item.setCount(count); |
|
783 |
item.setDate(new java.sql.Date(logDate.getTime())); |
|
784 |
monitorList.addMonitorInfo(item); |
|
670 | 785 |
|
671 |
boolean nodeSynchronize = false; |
|
672 |
boolean nodeReplicate = false; |
|
673 |
boolean mnCoreServiceAvailable = false; |
|
674 |
boolean mnReadServiceAvailable = false; |
|
675 |
boolean mnAuthorizationServiceAvailable = false; |
|
676 |
boolean mnStorageServiceAvailable = false; |
|
677 |
boolean mnReplicationServiceAvailable = false; |
|
786 |
} |
|
787 |
} catch (Exception e) { |
|
788 |
e.printStackTrace(); |
|
789 |
throw new ServiceFailure("2081", "Could not retrieve statistics: " + e.getMessage()); |
|
790 |
} |
|
678 | 791 |
|
679 |
try |
|
680 |
{ |
|
681 |
// get the properties of the node based on configuration information |
|
682 |
nodeId = PropertyService.getProperty("dataone.memberNodeId"); |
|
683 |
nodeName = PropertyService.getProperty("dataone.nodeName"); |
|
684 |
nodeUrl = SystemUtil.getContextURL() + "/d1/"; |
|
685 |
nodeDesc = PropertyService.getProperty("dataone.nodeDescription"); |
|
686 |
nodeType = PropertyService.getProperty("dataone.nodeType"); |
|
687 |
nodeSynchronize = |
|
688 |
new Boolean(PropertyService.getProperty( |
|
689 |
"dataone.nodeSynchronize")).booleanValue(); |
|
690 |
nodeReplicate = |
|
691 |
new Boolean(PropertyService.getProperty( |
|
692 |
"dataone.nodeReplicate")).booleanValue(); |
|
693 |
|
|
694 |
mnCoreServiceVersion = |
|
695 |
PropertyService.getProperty("dataone.mnCore.serviceVersion"); |
|
696 |
mnReadServiceVersion = |
|
697 |
PropertyService.getProperty("dataone.mnRead.serviceVersion"); |
|
698 |
mnAuthorizationServiceVersion = |
|
699 |
PropertyService.getProperty("dataone.mnAuthorization.serviceVersion"); |
|
700 |
mnStorageServiceVersion = |
|
701 |
PropertyService.getProperty("dataone.mnStorage.serviceVersion"); |
|
702 |
mnReplicationServiceVersion = |
|
703 |
PropertyService.getProperty("dataone.mnReplication.serviceVersion"); |
|
704 |
|
|
705 |
mnCoreServiceAvailable = new Boolean( |
|
706 |
PropertyService.getProperty("dataone.mnCore.serviceAvailable")).booleanValue(); |
|
707 |
mnReadServiceAvailable = new Boolean( |
|
708 |
PropertyService.getProperty( |
|
709 |
"dataone.mnRead.serviceAvailable")).booleanValue(); |
|
710 |
mnAuthorizationServiceAvailable = new Boolean( |
|
711 |
PropertyService.getProperty( |
|
712 |
"dataone.mnAuthorization.serviceAvailable")).booleanValue(); |
|
713 |
mnStorageServiceAvailable = new Boolean( |
|
714 |
PropertyService.getProperty( |
|
715 |
"dataone.mnStorage.serviceAvailable")).booleanValue(); |
|
716 |
mnReplicationServiceAvailable = new Boolean( |
|
717 |
PropertyService.getProperty( |
|
718 |
"dataone.mnReplication.serviceAvailable")).booleanValue(); |
|
792 |
return monitorList; |
|
719 | 793 |
|
720 |
} catch(PropertyNotFoundException pnfe) { |
|
721 |
logMetacat.error("MNodeService.getCapabilities(): " + |
|
722 |
"property not found: " + pnfe.getMessage()); |
|
723 |
|
|
724 | 794 |
} |
725 | 795 |
|
726 |
// Set the properties of the node based on configuration information and |
|
727 |
// calls to current status methods |
|
728 |
Node node = new Node(); |
|
729 |
node.setBaseURL(metacatUrl + "/" + nodeType); |
|
730 |
node.setDescription(nodeDesc); |
|
731 |
|
|
732 |
// set the node's health information |
|
733 |
NodeState state = NodeState.UP; |
|
734 |
node.setState(state); |
|
735 |
// set the ping response to the current value |
|
736 |
Ping canPing = new Ping(); |
|
737 |
canPing.setSuccess(false); |
|
738 |
try { |
|
739 |
canPing.setSuccess(ping()); |
|
740 |
} catch (InsufficientResources e) { |
|
741 |
e.printStackTrace(); |
|
742 |
|
|
743 |
} catch (UnsupportedType e) { |
|
744 |
e.printStackTrace(); |
|
745 |
|
|
796 |
/** |
|
797 |
* Low level “are you alive” operation. A valid ping response is |
|
798 |
* indicated by a HTTP status of 200. |
|
799 |
* |
|
800 |
* @return true if the service is alive |
|
801 |
* |
|
802 |
* @throws InvalidToken |
|
803 |
* @throws ServiceFailure |
|
804 |
* @throws NotAuthorized |
|
805 |
* @throws InvalidRequest |
|
806 |
* @throws NotImplemented |
|
807 |
*/ |
|
808 |
@Override |
|
809 |
public boolean ping() throws NotImplemented, ServiceFailure, NotAuthorized, InvalidRequest, InsufficientResources, UnsupportedType { |
|
810 |
|
|
811 |
// test if we can get a database connection |
|
812 |
boolean alive = false; |
|
813 |
int serialNumber = -1; |
|
814 |
DBConnection dbConn = null; |
|
815 |
try { |
|
816 |
dbConn = DBConnectionPool.getDBConnection("MNodeService.ping"); |
|
817 |
serialNumber = dbConn.getCheckOutSerialNumber(); |
|
818 |
alive = true; |
|
819 |
} catch (SQLException e) { |
|
820 |
return alive; |
|
821 |
} finally { |
|
822 |
// Return the database connection |
|
823 |
DBConnectionPool.returnDBConnection(dbConn, serialNumber); |
|
824 |
} |
|
825 |
|
|
826 |
return alive; |
|
746 | 827 |
} |
747 |
node.setPing(canPing); |
|
748 |
|
|
749 |
NodeReference identifier = new NodeReference(); |
|
750 |
identifier.setValue(nodeId); |
|
751 |
node.setIdentifier(identifier); |
|
752 |
node.setName(nodeName + " -- WAR version WARVERSION"); |
|
753 |
node.setReplicate(new Boolean(nodeReplicate).booleanValue()); |
|
754 |
node.setSynchronize(new Boolean(nodeSynchronize).booleanValue()); |
|
755 |
|
|
756 |
// services: MNAuthorization, MNCore, MNRead, MNReplication, MNStorage |
|
757 |
Services services = new Services(); |
|
758 | 828 |
|
759 |
Service sMNCore = new Service(); |
|
760 |
sMNCore.setName("MNCore"); |
|
761 |
sMNCore.setVersion(mnCoreServiceVersion); |
|
762 |
sMNCore.setAvailable(mnCoreServiceAvailable); |
|
763 |
|
|
764 |
Service sMNRead = new Service(); |
|
765 |
sMNRead.setName("MNRead"); |
|
766 |
sMNRead.setVersion(mnReadServiceVersion); |
|
767 |
sMNRead.setAvailable(mnReadServiceAvailable); |
|
768 |
|
|
769 |
Service sMNAuthorization = new Service(); |
|
770 |
sMNAuthorization.setName("MNAuthorization"); |
|
771 |
sMNAuthorization.setVersion(mnAuthorizationServiceVersion); |
|
772 |
sMNAuthorization.setAvailable(mnAuthorizationServiceAvailable); |
|
773 |
|
|
774 |
Service sMNStorage = new Service(); |
|
775 |
sMNStorage.setName("MNStorage"); |
|
776 |
sMNStorage.setVersion(mnStorageServiceVersion); |
|
777 |
sMNStorage.setAvailable(mnStorageServiceAvailable); |
|
778 |
|
|
779 |
Service sMNReplication = new Service(); |
|
780 |
sMNReplication.setName("MNReplication"); |
|
781 |
sMNReplication.setVersion(mnReplicationServiceVersion); |
|
782 |
sMNReplication.setAvailable(mnReplicationServiceAvailable); |
|
783 |
|
|
784 |
services.addService(sMNRead); |
|
785 |
services.addService(sMNCore); |
|
786 |
services.addService(sMNAuthorization); |
|
787 |
services.addService(sMNStorage); |
|
788 |
services.addService(sMNReplication); |
|
789 |
node.setServices(services); |
|
790 |
|
|
791 |
// TODO: Determine the synchronization info without mock values |
|
792 |
Synchronization synchronization = new Synchronization(); |
|
793 |
Schedule schedule = new Schedule(); |
|
794 |
Date now = new Date(); |
|
795 |
schedule.setYear(new SimpleDateFormat("yyyy").format(now)); |
|
796 |
schedule.setMon(new SimpleDateFormat("MM").format(now)); |
|
797 |
schedule.setMday(new SimpleDateFormat("dd").format(now)); |
|
798 |
schedule.setWday(new SimpleDateFormat("dd").format(now)); |
|
799 |
schedule.setHour(new SimpleDateFormat("HH").format(now)); |
|
800 |
schedule.setMin(new SimpleDateFormat("mm").format(now)); |
|
801 |
schedule.setSec(new SimpleDateFormat("ss").format(now)); |
|
802 |
synchronization.setSchedule(schedule); |
|
803 |
synchronization.setLastHarvested(now); |
|
804 |
synchronization.setLastCompleteHarvest(now); |
|
805 |
node.setSynchronization(synchronization); |
|
806 |
node.setSynchronize(false); |
|
807 |
node.setType(NodeType.MN); |
|
808 |
|
|
809 |
return node; |
|
810 |
} |
|
829 |
/** |
|
830 |
* A callback method used by a CN to indicate to a MN that it cannot |
|
831 |
* complete synchronization of the science metadata identified by pid. Log |
|
832 |
* the event in the metacat event log. |
|
833 |
* |
|
834 |
* @param session |
|
835 |
* @param syncFailed |
|
836 |
* |
|
837 |
* @throws ServiceFailure |
|
838 |
* @throws NotAuthorized |
|
839 |
* @throws InvalidRequest |
|
840 |
* @throws NotImplemented |
|
841 |
*/ |
|
842 |
@Override |
|
843 |
public void synchronizationFailed(Session session, SynchronizationFailed syncFailed) throws NotImplemented, ServiceFailure, NotAuthorized, InvalidRequest { |
|
811 | 844 |
|
812 |
/** |
|
813 |
* Returns the number of operations that have been serviced by the node |
|
814 |
* over time periods of one and 24 hours. |
|
815 |
* |
|
816 |
* @param session - the Session object containing the credentials for the Subject |
|
817 |
* @param period - An ISO8601 compatible DateTime range specifying the time |
|
818 |
* range for which to return operation statistics. |
|
819 |
* @param requestor - Limit to operations performed by given requestor identity. |
|
820 |
* @param event - Enumerated value indicating the type of event being examined |
|
821 |
* @param format - Limit to events involving objects of the specified format |
|
822 |
* |
|
823 |
* @return the desired log records |
|
824 |
* |
|
825 |
* @throws InvalidToken |
|
826 |
* @throws ServiceFailure |
|
827 |
* @throws NotAuthorized |
|
828 |
* @throws InvalidRequest |
|
829 |
* @throws NotImplemented |
|
830 |
*/ |
|
831 |
@Override |
|
832 |
public MonitorList getOperationStatistics(Session session, Date startTime, |
|
833 |
Date endTime, Subject requestor, Event event, ObjectFormatIdentifier formatId) |
|
834 |
throws NotImplemented, ServiceFailure, NotAuthorized, InvalidRequest, |
|
835 |
InsufficientResources, UnsupportedType { |
|
836 |
|
|
837 |
MonitorList monitorList = new MonitorList(); |
|
838 |
|
|
839 |
try { |
|
845 |
String localId; |
|
840 | 846 |
|
841 |
// get log records first |
|
842 |
Log logs = getLogRecords(session, startTime, endTime, event, 0, null); |
|
843 |
|
|
844 |
// TODO: aggregate by day or hour -- needs clarification |
|
845 |
int count = 1; |
|
846 |
for (LogEntry logEntry: logs.getLogEntryList()) { |
|
847 |
Identifier pid = logEntry.getIdentifier(); |
|
848 |
Date logDate = logEntry.getDateLogged(); |
|
849 |
// if we are filtering by format |
|
850 |
if (formatId != null) { |
|
851 |
SystemMetadata sysmeta = IdentifierManager.getInstance().getSystemMetadata(pid.getValue()); |
|
852 |
if (!sysmeta.getFmtid().getValue().equals(formatId.getValue())) { |
|
853 |
// does not match |
|
854 |
continue; |
|
855 |
} |
|
856 |
} |
|
857 |
MonitorInfo item = new MonitorInfo(); |
|
858 |
item.setCount(count); |
|
859 |
item.setDate(new java.sql.Date(logDate.getTime())); |
|
860 |
monitorList.addMonitorInfo(item); |
|
861 |
|
|
862 |
} |
|
863 |
} catch (Exception e) { |
|
864 |
e.printStackTrace(); |
|
865 |
throw new ServiceFailure("2081", "Could not retrieve statistics: " + e.getMessage()); |
|
866 |
} |
|
867 |
|
|
868 |
return monitorList; |
|
869 |
|
|
870 |
} |
|
847 |
try { |
|
848 |
localId = IdentifierManager.getInstance().getLocalId(syncFailed.getPid()); |
|
849 |
} catch (McdbDocNotFoundException e) { |
|
850 |
throw new InvalidRequest("2163", "The identifier specified by " + syncFailed.getPid() + " was not found on this node."); |
|
871 | 851 |
|
872 |
/** |
|
873 |
* Low level “are you alive” operation. A valid ping response is |
|
874 |
* indicated by a HTTP status of 200. |
|
875 |
* |
|
876 |
* @return true if the service is alive |
|
877 |
* |
|
878 |
* @throws InvalidToken |
|
879 |
* @throws ServiceFailure |
|
880 |
* @throws NotAuthorized |
|
881 |
* @throws InvalidRequest |
|
882 |
* @throws NotImplemented |
|
883 |
*/ |
|
884 |
@Override |
|
885 |
public boolean ping() |
|
886 |
throws NotImplemented, ServiceFailure, NotAuthorized, InvalidRequest, |
|
887 |
InsufficientResources, UnsupportedType { |
|
852 |
} |
|
853 |
// TODO: update the CN URL below when the CNRead.SynchronizationFailed |
|
854 |
// method is changed to include the URL as a parameter |
|
855 |
logMetacat.debug("Synchronization for the object identified by " + syncFailed.getPid() + " failed from " + syncFailed.getNodeId() |
|
856 |
+ " Logging the event to the Metacat EventLog as a 'syncFailed' event."); |
|
857 |
// TODO: use the event type enum when the SYNCHRONIZATION_FAILED event is added |
|
858 |
EventLog.getInstance().log(syncFailed.getNodeId(), session.getSubject().getValue(), localId, "synchronization_failed"); |
|
859 |
//EventLog.getInstance().log("CN URL WILL GO HERE", |
|
860 |
// session.getSubject().getValue(), localId, Event.SYNCHRONIZATION_FAILED); |
|
888 | 861 |
|
889 |
// test if we can get a database connection |
|
890 |
boolean alive = false; |
|
891 |
int serialNumber = -1; |
|
892 |
DBConnection dbConn = null; |
|
893 |
try { |
|
894 |
dbConn = DBConnectionPool |
|
895 |
.getDBConnection("MNodeService.ping"); |
|
896 |
serialNumber = dbConn.getCheckOutSerialNumber(); |
|
897 |
alive = true; |
|
898 |
|
|
899 |
} catch (SQLException e) { |
|
900 |
return alive; |
|
901 |
|
|
902 |
} finally { |
|
903 |
// Return the database connection |
|
904 |
DBConnectionPool.returnDBConnection(dbConn, serialNumber); |
|
905 |
|
|
906 | 862 |
} |
907 | 863 |
|
908 |
return alive; |
|
909 |
} |
|
864 |
/** |
|
865 |
* Essentially a get() but with different logging behavior |
|
866 |
*/ |
|
867 |
@Override |
|
868 |
public InputStream getReplica(Session session, Identifier pid) throws InvalidRequest, InvalidToken, NotAuthorized, NotImplemented, ServiceFailure, NotFound { |
|
910 | 869 |
|
911 |
/** |
|
912 |
* A callback method used by a CN to indicate to a MN that it cannot |
|
913 |
* complete synchronization of the science metadata identified by pid. Log |
|
914 |
* the event in the metacat event log. |
|
915 |
* |
|
916 |
* @param session |
|
917 |
* @param syncFailed |
|
918 |
* |
|
919 |
* @throws ServiceFailure |
|
920 |
* @throws NotAuthorized |
|
921 |
* @throws InvalidRequest |
|
922 |
* @throws NotImplemented |
|
923 |
*/ |
|
924 |
@Override |
|
925 |
public void synchronizationFailed(Session session, SynchronizationFailed syncFailed) |
|
926 |
throws NotImplemented, ServiceFailure, NotAuthorized, InvalidRequest { |
|
870 |
InputStream inputStream = null; // bytes to be returned |
|
871 |
handler = new MetacatHandler(new Timer()); |
Also available in: Unified diff
Reformatted to correct indentation to make class readable.