Project

General

Profile

« Previous | Next » 

Revision 6195

CNCoreImpl is replaced by CNodeService

View differences:

src/edu/ucsb/nceas/metacat/dataone/CNCoreImpl.java
1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2000 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.dataone;
24

  
25
import java.io.ByteArrayInputStream;
26
import java.io.IOException;
27
import java.io.InputStream;
28
import java.sql.SQLException;
29
import java.util.Calendar;
30
import java.util.Date;
31
import java.util.HashMap;
32
import java.util.Vector;
33

  
34
import org.apache.log4j.Logger;
35
import org.dataone.cn.batch.utils.TypeMarshaller;
36
import org.dataone.service.cn.CNCore;
37
import org.dataone.service.exceptions.IdentifierNotUnique;
38
import org.dataone.service.exceptions.InsufficientResources;
39
import org.dataone.service.exceptions.InvalidRequest;
40
import org.dataone.service.exceptions.InvalidSystemMetadata;
41
import org.dataone.service.exceptions.InvalidToken;
42
import org.dataone.service.exceptions.NotAuthorized;
43
import org.dataone.service.exceptions.NotFound;
44
import org.dataone.service.exceptions.NotImplemented;
45
import org.dataone.service.exceptions.ServiceFailure;
46
import org.dataone.service.exceptions.UnsupportedType;
47
import org.dataone.service.types.Event;
48
import org.dataone.service.types.Identifier;
49
import org.dataone.service.types.Log;
50
import org.dataone.service.types.LogEntry;
51
import org.dataone.service.types.NodeList;
52
import org.dataone.service.types.NodeReference;
53
import org.dataone.service.types.ObjectFormat;
54
import org.dataone.service.types.ObjectFormatIdentifier;
55
import org.dataone.service.types.ObjectFormatList;
56
import org.dataone.service.types.Session;
57
import org.dataone.service.types.Subject;
58
import org.dataone.service.types.SystemMetadata;
59
import org.jibx.runtime.JiBXException;
60

  
61
import edu.ucsb.nceas.metacat.DBUtil;
62
import edu.ucsb.nceas.metacat.DocumentImpl;
63
import edu.ucsb.nceas.metacat.EventLog;
64
import edu.ucsb.nceas.metacat.IdentifierManager;
65
import edu.ucsb.nceas.metacat.McdbException;
66
import edu.ucsb.nceas.metacat.properties.PropertyService;
67
import edu.ucsb.nceas.metacat.replication.ForceReplicationSystemMetadataHandler;
68
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
69

  
70
/**
71
 * 
72
 * Implements DataONE CNCore services for Metacat. 
73
 * 
74
 * @author leinfelder
75
 */
76
public class CNCoreImpl implements CNCore
77
{
78
  private static CNCoreImpl instance = null;
79

  
80
  private Logger logMetacat = null;
81
  
82
  /* The scope of the object formats docid used as the metacat identifier */
83
  private final String OBJECT_FORMAT_DOCID = "OBJECT_FORMAT_LIST.1";
84
  
85
  /* The revision of the object formats document */
86
  private int rev;
87
  
88
  /* The separator of the object formats document */
89
  private String separator = ".";
90

  
91
  /* The accession number of the object formats document */
92
  private String accNumber = null;
93

  
94
  /* The list of object formats */
95
  private ObjectFormatList objectFormatList = null;
96
  
97
  /* the searchable map of object formats */
98
  private static HashMap<String, ObjectFormat> objectFormatMap;
99
  
100
  /**
101
   * singleton accessor
102
   */
103
  public static CNCoreImpl getInstance() 
104
  {
105
    if (instance == null) {
106
      instance = new CNCoreImpl();
107
    }
108
    
109
    return instance;
110
  }
111
  
112
  /**
113
   * Constructor, private for singleton access
114
   */
115
  private CNCoreImpl() {
116
    logMetacat = Logger.getLogger(CNCoreImpl.class);
117
        
118
  }
119
    
120
    /**
121
     * register System Metadata without data/metadata object
122
     */
123
	  @Override
124
    public boolean registerSystemMetadata(Session session, Identifier guid,
125
      SystemMetadata sysmeta) throws NotImplemented, NotAuthorized,
126
      ServiceFailure, InvalidRequest, InvalidSystemMetadata {
127
      
128
	  	// TODO: control who can call this?
129
      if (session == null) {
130
          //TODO: many of the thrown exceptions do not use the correct error codes
131
          //check these against the docs and correct them
132
          throw new NotAuthorized("4861", "No Session - could not authorize to registration." +
133
                  "  If you are not logged in, please do so and retry the request.");
134
      }
135
      
136
      // verify that guid == SystemMetadata.getIdentifier()
137
      logMetacat.debug("Comparing guid|sysmeta_guid: " + guid.getValue() + "|" + sysmeta.getIdentifier().getValue());
138
      if (!guid.getValue().equals(sysmeta.getIdentifier().getValue())) {
139
          throw new InvalidRequest("4863", 
140
              "GUID in method call (" + guid.getValue() + ") does not match GUID in system metadata (" +
141
              sysmeta.getIdentifier().getValue() + ").");
142
      }
143

  
144
      logMetacat.debug("Checking if identifier exists...");
145
      // Check that the identifier does not already exist
146
      IdentifierManager im = IdentifierManager.getInstance();
147
      if (im.identifierExists(guid.getValue())) {
148
          throw new InvalidRequest("4863", 
149
              "GUID is already in use by an existing object.");
150
      }
151

  
152
      // insert the system metadata into the object store
153
      logMetacat.debug("Starting to insert SystemMetadata...");
154
      sysmeta.setDateSysMetadataModified(new Date());
155
      try {
156
		    IdentifierManager.getInstance().createSystemMetadata(sysmeta);
157
		    IdentifierManager.getInstance().updateSystemMetadata(sysmeta);
158
		    // force replication of this record
159
		    ForceReplicationSystemMetadataHandler forceReplication = 
160
		    	new ForceReplicationSystemMetadataHandler(guid.getValue(), null);
161
	    } catch (Exception e) {
162
          throw new ServiceFailure("4862", "Error inserting system metadata: " + e.getClass() + ": " + e.getMessage());
163
	    }
164
      
165
      logMetacat.debug("Returning from registerSystemMetadata");
166
      EventLog.getInstance().log(null, session.getSubject().getValue(), guid.getValue(), "registerSystemMetadata");
167
      return true;
168

  
169
    }
170

  
171
	@Override
172
	public Log getLogRecords(Session session, Date fromDate, Date toDate,
173
			Event event) throws InvalidToken, InvalidRequest, ServiceFailure,
174
			NotAuthorized, NotImplemented {
175

  
176
		Log log = new Log();
177
		Vector<LogEntry> logs = new Vector<LogEntry>();
178
		IdentifierManager im = IdentifierManager.getInstance();
179
		EventLog el = EventLog.getInstance();
180
		if (fromDate == null) {
181
			logMetacat.debug("setting fromdate from null");
182
			fromDate = new Date(1);
183
		}
184
		if (toDate == null) {
185
			logMetacat.debug("setting todate from null");
186
			toDate = new Date();
187
		}
188

  
189
		logMetacat.debug("fromDate: " + fromDate);
190
		logMetacat.debug("toDate: " + toDate);
191

  
192
		String report = el.getReport(null, null, null, null,
193
				new java.sql.Timestamp(fromDate.getTime()),
194
				new java.sql.Timestamp(toDate.getTime()), false);
195

  
196
		logMetacat.debug("report: " + report);
197

  
198
		String logEntry = "<logEntry>";
199
		String endLogEntry = "</logEntry>";
200
		int startIndex = 0;
201
		int foundIndex = report.indexOf(logEntry, startIndex);
202
		while (foundIndex != -1) {
203
			// parse out each entry
204
			int endEntryIndex = report.indexOf(endLogEntry, foundIndex);
205
			String entry = report.substring(foundIndex, endEntryIndex);
206
			logMetacat.debug("entry: " + entry);
207
			startIndex = endEntryIndex + endLogEntry.length();
208
			foundIndex = report.indexOf(logEntry, startIndex);
209

  
210
			String entryId = getLogEntryField("entryid", entry);
211
			String ipAddress = getLogEntryField("ipAddress", entry);
212
			String principal = getLogEntryField("principal", entry);
213
			String docid = getLogEntryField("docid", entry);
214
			String eventS = getLogEntryField("event", entry);
215
			String dateLogged = getLogEntryField("dateLogged", entry);
216

  
217
			LogEntry le = new LogEntry();
218

  
219
			Event e = Event.convert(eventS);
220
			if (e == null) { // skip any events that are not Dataone Crud events
221
				continue;
222
			}
223
			le.setEvent(e);
224
			Identifier entryid = new Identifier();
225
			entryid.setValue(entryId);
226
			le.setEntryId(entryid);
227
			Identifier identifier = new Identifier();
228
			try {
229
				logMetacat.debug("converting docid '" + docid + "' to a guid.");
230
				if (docid == null || docid.trim().equals("") || docid.trim().equals("null")) {
231
					continue;
232
				}
233
				docid = docid.substring(0, docid.lastIndexOf("."));
234
				identifier.setValue(im.getGUID(docid, im.getLatestRevForLocalId(docid)));
235
			} catch (Exception ex) { 
236
				// try to get the guid, if that doesn't
237
				// work, just use the local id
238
				// throw new ServiceFailure("1030",
239
				// "Error getting guid for localId " +
240
				// docid + ": " + ex.getMessage());\
241

  
242
				// skip it if the guid can't be found
243
				continue;
244
			}
245

  
246
			le.setIdentifier(identifier);
247
			le.setIpAddress(ipAddress);
248
			Calendar c = Calendar.getInstance();
249
			String year = dateLogged.substring(0, 4);
250
			String month = dateLogged.substring(5, 7);
251
			String date = dateLogged.substring(8, 10);
252
			logMetacat.debug("year: " + year + " month: " + month + " day: " + date);
253
			c.set(new Integer(year).intValue(), new Integer(month).intValue(),
254
					new Integer(date).intValue());
255
			Date logDate = c.getTime();
256
			le.setDateLogged(logDate);
257
			NodeReference memberNode = new NodeReference();
258
			memberNode.setValue(ipAddress);
259
			le.setMemberNode(memberNode);
260
			Subject princ = new Subject();
261
			princ.setValue(principal);
262
			le.setSubject(princ);
263
			le.setUserAgent("metacat/RESTService");
264

  
265
			if (event == null) {
266
				logs.add(le);
267
			}
268

  
269
			if (event != null
270
					&& e.toString().toLowerCase().trim().equals(
271
							event.toString().toLowerCase().trim())) {
272
				logs.add(le);
273
			}
274
		}
275

  
276
		log.setLogEntryList(logs);
277
		logMetacat.info("getLogRecords");
278
		return log;
279
	}
280

  
281
	/**
282
	 * parse a logEntry and get the relevant field from it
283
	 * 
284
	 * @param fieldname
285
	 * @param entry
286
	 * @return
287
	 */
288
	private String getLogEntryField(String fieldname, String entry) {
289
		String begin = "<" + fieldname + ">";
290
		String end = "</" + fieldname + ">";
291
		// logMetacat.debug("looking for " + begin + " and " + end +
292
		// " in entry " + entry);
293
		String s = entry.substring(entry.indexOf(begin) + begin.length(), entry
294
				.indexOf(end));
295
		logMetacat.debug("entry " + fieldname + " : " + s);
296
		return s;
297
	}
298
  
299
  /**
300
   * Return the object format based on the given object format identifier
301
   * @param fmtid - the object format identifier to look up
302
   * @return objectFormat - the desired object format
303
   */
304
  @Override
305
	public ObjectFormat getFormat(ObjectFormatIdentifier fmtid) 
306
	  throws InvalidRequest, ServiceFailure, NotFound, InsufficientResources, 
307
	  NotImplemented {
308
    
309
  	logMetacat.debug("CNCoreImpl.getFormat() called.");
310
  	
311
    ObjectFormat objectFormat = null;
312
    
313
    // look up the format in the object format map
314
	    objectFormat = getObjectFormatMap().get(fmtid.getValue());
315
	    
316
	    // refresh the object format list if the format is null
317
	    if ( objectFormat == null ) {
318
	    	getCachedList();
319
	      objectFormat = getObjectFormatMap().get(fmtid.getValue());
320
        
321
	      // the object format isn't registered
322
	      if ( objectFormat == null ) {
323
		      throw new NotFound("4848", "The format specified by " + fmtid.getValue() + 
324
	        " does not exist at this node.");
325
	
326
	      }
327
	      
328
	    }
329
    	    
330
  	return objectFormat;
331
	}
332

  
333
	@Override
334
	public NodeList listNodes() throws NotImplemented, ServiceFailure {
335
		// TODO Auto-generated method stub
336
		return null;
337
	}
338

  
339
	/**
340
	 * Return the list of object formats registered from the Coordinating Node.
341
	 * @return objectFormatList -  the list of object formats
342
	 */
343
	@Override
344
  public ObjectFormatList listFormats() throws InvalidRequest, ServiceFailure,
345
    NotFound, InsufficientResources, NotImplemented {
346
    
347
		try {
348
	    objectFormatList = getInstance().getCachedList();
349
    
350
		} catch (ServiceFailure sfe) {
351
    	throw sfe;
352

  
353
		} catch (NotFound nfe) {
354
    	throw nfe;
355
		
356
		}
357
		
358
		return objectFormatList;
359
  }
360

  
361
	@Override
362
	public Identifier create(Session arg0, Identifier arg1, InputStream arg2,
363
			SystemMetadata arg3) throws InvalidToken, ServiceFailure,
364
			NotAuthorized, IdentifierNotUnique, UnsupportedType,
365
			InsufficientResources, InvalidSystemMetadata, NotImplemented,
366
			InvalidRequest {
367
		// TODO Auto-generated method stub
368
		return null;
369
	}
370

  
371
	@Override
372
	public Identifier reserveIdentifier(Session arg0, Identifier arg1,
373
			String arg2, String arg3) throws InvalidToken, ServiceFailure,
374
			NotAuthorized, IdentifierNotUnique, NotImplemented, InvalidRequest {
375
		// TODO Auto-generated method stub
376
		return null;
377
	}
378

  
379
  /*
380
   * Return the hash containing the fmtid and format mapping
381
   * 
382
   * @return objectFormatMap - the hash of fmtid/format pairs
383
   */
384
  private HashMap<String, ObjectFormat> getObjectFormatMap() {
385
  	
386
  	if ( objectFormatMap == null ) {
387
  		objectFormatMap = new HashMap<String, ObjectFormat>();
388
  		
389
  	}
390
  	return objectFormatMap;
391
  	
392
  }
393
  
394
  /**
395
   * Get the object format list cached in Metacat
396
   */
397
  private ObjectFormatList getCachedList()
398
    throws NotFound, ServiceFailure {
399
    
400
  	ObjectFormatList objectFormatList = null;
401
  	
402
    try {
403
      
404
      // reset the accession number separator in case it is 
405
      // different than the default
406
      try {
407
        
408
        separator = PropertyService.getProperty("document.accNumSeparator");
409
        
410
      } catch ( PropertyNotFoundException pnfe ) {
411
        
412
        // use the default separator, but log the issue
413
        logMetacat.debug("There was a problem finding the document " +
414
          "separator property. The error message was: " + pnfe.getMessage());
415
      }
416
      
417
      // get the latest accession number if it is in Metacat
418
      this.rev = 
419
        DBUtil.getLatestRevisionInDocumentTable(this.OBJECT_FORMAT_DOCID);
420
      
421
      if ( this.rev != -1 ) {
422
        this.accNumber = this.OBJECT_FORMAT_DOCID + 
423
                         this.separator + 
424
                         this.rev;
425
        DocumentImpl objectFormatsDocument = new DocumentImpl(accNumber, false);
426
        ByteArrayInputStream bais = 
427
          new ByteArrayInputStream(objectFormatsDocument.toString().getBytes());
428

  
429
        // deserialize the object format list
430
        try {
431
  	      
432
        	objectFormatList = 
433
        		TypeMarshaller.unmarshalTypeFromStream(ObjectFormatList.class, bais);
434
        
435
        } catch (IOException e) {
436
        	throw new ServiceFailure("4841", "Unexpected exception from the service - " + 
437
        		e.getClass() + ": " + e.getMessage());
438
        
439
        } catch (InstantiationException e) {
440
         	throw new ServiceFailure("4841", "Unexpected exception from the service - " + 
441
        		e.getClass() + ": " + e.getMessage());
442
        
443
        } catch (IllegalAccessException e) {
444
         	throw new ServiceFailure("4841", "Unexpected exception from the service - " + 
445
        		e.getClass() + ": " + e.getMessage());
446
             
447
        } catch (JiBXException e) {
448
         	throw new ServiceFailure("4841", "Unexpected exception from the service - " + 
449
        		e.getClass() + ": " + e.getMessage());
450
       
451
        }
452
  
453
      } else {
454
        throw new NotFound("4843", "The object formats collection could not " +
455
        	"be found at this node.");
456
      }
457
      
458
    } catch ( SQLException sqle ) {      
459
     	throw new ServiceFailure("4841", "Unexpected exception from the service - " + 
460
      		sqle.getClass() + ": " + sqle.getMessage());
461
      
462
    } catch (McdbException mcdbe) {      
463
     	throw new ServiceFailure("4841", "Unexpected exception from the service - " + 
464
     			mcdbe.getClass() + ": " + mcdbe.getMessage());
465
     	
466
    }
467
  
468
    // index the object format list based on the format identifier string
469
    int listSize = objectFormatList.sizeObjectFormats();
470
    
471
    for (int i = 0; i < listSize; i++ ) {
472
      
473
      ObjectFormat objectFormat = 
474
        objectFormatList.getObjectFormat(i);
475
      String identifier = objectFormat.getFmtid().getValue();
476
      getObjectFormatMap().put(identifier, objectFormat);
477
      
478
    }
479

  
480
    return objectFormatList;
481
    
482
  }
483

  
484
}
485

  
486 0

  
test/edu/ucsb/nceas/metacat/dataone/CNCoreTest.java
110 110
			Identifier guid = new Identifier();
111 111
			guid.setValue("testRegisterSystemMetadata." + System.currentTimeMillis());
112 112
			SystemMetadata sysmeta = createSystemMetadata(guid, subject);
113
			CNCoreImpl.getInstance().registerSystemMetadata(session, guid, sysmeta);
113
			CNodeService.getInstance().registerSystemMetadata(session, guid, sysmeta);
114 114
        }
115 115
        catch(Exception e)
116 116
        {
......
170 170
  	ObjectFormatList objectFormatList;
171 171
  	
172 172
  	try {
173
	    objectFormatList = CNCoreImpl.getInstance().listFormats();
173
	    objectFormatList = CNodeService.getInstance().listFormats();
174 174
	  	assertTrue(objectFormatList.getTotal() >= formatsCount);
175 175
  	
176 176
  	} catch (InvalidRequest e) {
......
206 206
    try {
207 207
	    
208 208
			String result = 
209
				CNCoreImpl.getInstance().getFormat(fmtid).getFmtid().getValue();
209
				CNodeService.getInstance().getFormat(fmtid).getFmtid().getValue();
210 210
	  	System.out.println("Expected result: " + knownFormat);
211 211
	  	System.out.println("Found    result: " + result);
212 212
	  	assertTrue(result.equals(knownFormat));
......
247 247
  	try {
248 248
  		
249 249
	    ObjectFormat objectFormat = 
250
	    	CNCoreImpl.getInstance().getFormat(fmtid);
250
	    	CNodeService.getInstance().getFormat(fmtid);
251 251
      
252 252
  	} catch (Exception e) {
253 253
	    
src/edu/ucsb/nceas/metacat/restservice/ResourceHandler.java
96 96
import edu.ucsb.nceas.metacat.McdbDocNotFoundException;
97 97
import edu.ucsb.nceas.metacat.MetaCatServlet;
98 98
import edu.ucsb.nceas.metacat.MetacatHandler;
99
import edu.ucsb.nceas.metacat.dataone.CNCoreImpl;
99
import edu.ucsb.nceas.metacat.dataone.CNodeService;
100 100
import edu.ucsb.nceas.metacat.dataone.CrudService;
101 101
import edu.ucsb.nceas.metacat.dataone.HealthService;
102 102
import edu.ucsb.nceas.metacat.properties.PropertyService;
......
2043 2043

  
2044 2044
      // get the object format list
2045 2045
      try {
2046
	      ObjectFormatList objectFormatList = CNCoreImpl.getInstance().listFormats();
2046
	      ObjectFormatList objectFormatList = CNodeService.getInstance().listFormats();
2047 2047
	      serializeServiceType(ObjectFormatList.class, objectFormatList, out);
2048 2048
      
2049 2049
      } catch (InvalidRequest e) {
......
2103 2103
      
2104 2104
      try {
2105 2105
      	// get the specified object format
2106
	      ObjectFormat objectFormat = CNCoreImpl.getInstance().getFormat(fmtid);
2106
	      ObjectFormat objectFormat = CNodeService.getInstance().getFormat(fmtid);
2107 2107
	      serializeServiceType(ObjectFormat.class, objectFormat, out);
2108 2108

  
2109 2109
      } catch (InvalidRequest e) {
......
2251 2251
			guid.setValue(pid);
2252 2252
			logMetacat.debug("registering system metadata with pid "
2253 2253
					+ guid.getValue());
2254
			boolean result = CNCoreImpl.getInstance().registerSystemMetadata(
2254
			boolean result = CNodeService.getInstance().registerSystemMetadata(
2255 2255
					session, guid, systemMetadata);
2256 2256
			serializeServiceType(Boolean.class, result, out);
2257 2257

  

Also available in: Unified diff