Project

General

Profile

« Previous | Next » 

Revision 9079

Added by Jing Tao almost 10 years ago

Implemented 4 rules to determine the head version of a sid chain.
Add the test case 14 for testing.

View differences:

test/edu/ucsb/nceas/metacat/dataone/SIDTest.java
1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2010 Regents of the University of California and the
4
 *              National Center for Ecological Analysis and Synthesis
5
 *  Purpose: To test the Access Controls in metacat by JUnit
6
 *
7
 *   '$Author: leinfelder $'
8
 *     '$Date: 2014-08-07 14:28:35 -0700 (Thu, 07 Aug 2014) $'
9
 * '$Revision: 8834 $'
10
 *
11
 * This program is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
 */
25

  
26
package edu.ucsb.nceas.metacat.dataone;
27

  
28
import java.io.InputStream;
29
import java.io.InputStreamReader;
30
import java.io.Reader;
31
import java.math.BigInteger;
32
import java.util.Collections;
33
import java.util.Date;
34
import java.util.Vector;
35

  
36
import junit.framework.Test;
37
import junit.framework.TestSuite;
38

  
39
import org.apache.wicket.protocol.http.mock.MockHttpServletRequest;
40
import org.dataone.client.D1Node;
41
import org.dataone.client.NodeLocator;
42
import org.dataone.client.exception.ClientSideException;
43
import org.dataone.client.v2.CNode;
44
import org.dataone.client.v2.itk.D1Client;
45
import org.dataone.client.v2.formats.ObjectFormatCache;
46
import org.dataone.service.types.v1.AccessPolicy;
47
import org.dataone.service.types.v1.AccessRule;
48
import org.dataone.service.types.v1.Checksum;
49
import org.dataone.service.types.v1.Identifier;
50
import org.dataone.service.types.v2.Node;
51
import org.dataone.service.types.v2.ObjectFormatList;
52
import org.dataone.service.types.v1.NodeReference;
53
import org.dataone.service.types.v1.NodeType;
54
import org.dataone.service.types.v1.Permission;
55
import org.dataone.service.types.v1.Session;
56
import org.dataone.service.types.v1.Subject;
57
import org.dataone.service.types.v2.SystemMetadata;
58
import org.dataone.service.types.v1.comparators.SystemMetadataDateUploadedComparator;
59
import org.dataone.service.types.v1.util.ChecksumUtil;
60
import org.dataone.service.types.v2.util.ObjectFormatServiceImpl;
61
import org.dataone.service.util.Constants;
62
import org.dataone.service.util.TypeMarshaller;
63

  
64

  
65
import edu.ucsb.nceas.MCTestCase;
66
import edu.ucsb.nceas.metacat.client.Metacat;
67
import edu.ucsb.nceas.metacat.client.MetacatFactory;
68

  
69
/**
70
 * A class for testing the scenarios of getting the the head version of an SID chain
71
 */
72
public class SIDTest extends MCTestCase {   
73
    
74
    private static final String OBSOLETES = "obsoletes";
75
    private static final String OBSOLETEDBY = "obsoletedBy";
76
   
77
	/**
78
    * constructor for the test
79
    */
80
    public SIDTest(String name) {
81
        super(name);
82
    }
83
  
84
    /**
85
	 * Establish a testing framework by initializing appropriate objects
86
	 */
87
    public void setUp() throws Exception {
88
    	
89
    }
90

  
91
	/**
92
	 * Release any objects after tests are complete
93
	 */
94
	public void tearDown() {
95
		
96
	}
97
	
98
	/**
99
     * Create a suite of tests to be run together
100
     */
101
    public static Test suite() 
102
    {
103
        TestSuite suite = new TestSuite();
104
        suite.addTest(new SIDTest("initialize"));
105
        suite.addTest(new SIDTest("testCases"));
106
        return suite;
107
    }
108
	
109
	
110
	
111
	/**
112
	 * Run an initial test that always passes to check that the test harness is
113
	 * working.
114
	 */
115
	public void initialize() 
116
	{
117
		assertTrue(1 == 1);
118
	}
119
	
120
	public void testCases() throws Exception {
121
	    testCase14();
122
	}
123
	
124
	/**
125
	 * Case 14: P1(S1) <- P2(S1) -> P3(S2).
126
	 * After decorating sysmeta, it changed to P1(S1) <-> P2(S1) <-> P3(S2).
127
	 * S1 = P2 (Rule 3) 
128
	 * @throws Exception
129
	 */
130
	private void testCase14() throws Exception {
131
	    Identifier s1 = new Identifier();
132
	    s1.setValue("S1");
133
	    Identifier s2 = new Identifier();
134
        s2.setValue("S2");
135
	    Identifier p1 = new Identifier();
136
	    p1.setValue("P1");
137
	    Identifier p2 = new Identifier();
138
        p2.setValue("P2");
139
        Identifier p3 = new Identifier();
140
        p3.setValue("P3");
141
	    
142
        SystemMetadata p1Sys = new SystemMetadata();
143
	    p1Sys.setIdentifier(p1);
144
	    p1Sys.setSeriesId(s1);
145
	    
146
	    SystemMetadata p2Sys = new SystemMetadata();
147
        p2Sys.setIdentifier(p2);
148
        p2Sys.setSeriesId(s1);
149
        p2Sys.setObsoletes(p1);
150
        p2Sys.setObsoletedBy(p3);
151
        
152
        SystemMetadata p3Sys = new SystemMetadata();
153
        p3Sys.setIdentifier(p3);
154
        p3Sys.setSeriesId(s2);
155
        
156
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
157
        chain.add(p1Sys);
158
        chain.add(p2Sys);
159
        chain.add(p3Sys);
160
        
161
        Identifier head = getHeadVersion(s1, chain);
162
        //System.out.println("The head is "+head.getValue());
163
        assertTrue(head.equals(p2));
164
	}
165
	
166
	
167
	/*
168
	 * completed the obsoletes and obsoletedBy information for the given pid. 
169
	 * We will look up the information from the given chain if its obsoletes or obsoletedBy field is missing.
170
	 */
171
	private void decorateSystemMetadata(SystemMetadata targetSysmeta, Vector<SystemMetadata> chain) {
172
	    if(targetSysmeta != null) {
173
	        if (targetSysmeta.getObsoletes() == null && targetSysmeta.getObsoletedBy() == null) {
174
	            Identifier obsoletes = getRelatedIdentifier(targetSysmeta.getIdentifier(), OBSOLETES, chain);
175
	            if(obsoletes != null) {
176
	                targetSysmeta.setObsoletedBy(obsoletes);
177
	            }
178
	            Identifier obsoleted = getRelatedIdentifier(targetSysmeta.getIdentifier(), OBSOLETEDBY, chain);
179
	            if(obsoleted != null) {
180
	                targetSysmeta.setObsoletes(obsoleted);
181
	            }
182
	        } else if (targetSysmeta.getObsoletes() != null && targetSysmeta.getObsoletedBy() == null) {
183
	            Identifier obsoleted = getRelatedIdentifier(targetSysmeta.getIdentifier(), OBSOLETEDBY, chain);
184
                if(obsoleted != null) {
185
                    targetSysmeta.setObsoletes(obsoleted);
186
                }
187
	            
188
	        } else if (targetSysmeta.getObsoletes() == null && targetSysmeta.getObsoletedBy() != null) {
189
	            Identifier obsoletes = getRelatedIdentifier(targetSysmeta.getIdentifier(), OBSOLETES, chain);
190
                if(obsoletes != null) {
191
                    targetSysmeta.setObsoletedBy(obsoletes);
192
                }
193
            }
194
	    }
195
	}
196
	
197
	/*
198
	 * Get the identifier in chain which obsoleted or obsoletedBy the target id.
199
	 */
200
	private Identifier getRelatedIdentifier(Identifier target, String keyword, Vector<SystemMetadata> chain) {
201
	    Identifier identifier = null;
202
	    if(keyword.equals(OBSOLETES)) {
203
	        for(SystemMetadata sysmeta :chain) {
204
	            Identifier obsoletes = sysmeta.getObsoletes();
205
	            if(obsoletes != null && obsoletes.equals(target)) {
206
	                identifier = sysmeta.getIdentifier();
207
	            }
208
	        }
209
	    } else if(keyword.equals(OBSOLETEDBY)) {
210
	        for(SystemMetadata sysmeta :chain) {
211
	            Identifier obsoletedBy = sysmeta.getObsoletedBy();
212
	            if(obsoletedBy != null && obsoletedBy.equals(target)) {
213
	                identifier = sysmeta.getIdentifier();
214
	            }
215
	        }
216
	        
217
	    }
218
	    return identifier;
219
	}
220
	
221
	
222
	/**
223
	 * Get the head version of the chain
224
	 * @param sid
225
	 * @return
226
	 */
227
	public Identifier getHeadVersion(Identifier sid, Vector<SystemMetadata> chain) {
228
	    Identifier pid = null;
229
	    Vector<SystemMetadata> sidChain = new Vector<SystemMetadata>();
230
	    int noObsoletedByCount =0;
231
	    if(chain != null) {
232
	        for(SystemMetadata sysmeta : chain) {
233
	            if(sysmeta.getSeriesId() != null && sysmeta.getSeriesId().equals(sid)) {
234
	                decorateSystemMetadata(sysmeta, chain);
235
	                /*System.out.println("identifier "+sysmeta.getIdentifier().getValue()+" :");
236
	                if(sysmeta.getObsoletes() == null) {
237
	                    System.out.println("obsolets "+sysmeta.getObsoletes());
238
	                } else {
239
	                    System.out.println("obsolets "+sysmeta.getObsoletes().getValue());
240
	                }
241
	                if(sysmeta.getObsoletedBy() == null) {
242
	                    System.out.println("obsoletedBy "+sysmeta.getObsoletedBy());
243
	                } else {
244
	                    System.out.println("obsoletedBy "+sysmeta.getObsoletedBy().getValue());
245
	                }*/
246
	                
247
	                if(sysmeta.getObsoletedBy() == null) {
248
	                    pid = sysmeta.getIdentifier();
249
	                    noObsoletedByCount++;
250
	                }
251
	                sidChain.add(sysmeta);
252
	            }
253
	        }
254
	    }
255
	    
256
	    
257
	    if(noObsoletedByCount == 1) {
258
	       //rule 1 . If there is only one object having NULL value in the chain, return the value
259
	        System.out.println("rule 1");
260
	        return pid;
261
	    } else if (noObsoletedByCount > 1 ) {
262
	        // rule 2. If there is more than one object having NULL value in the chain, return last dateUploaded
263
	        System.out.println("rule 2");
264
	        Collections.sort(sidChain, new SystemMetadataDateUploadedComparator());
265
	        pid =sidChain.lastElement().getIdentifier();
266
	        
267
	    } else if (noObsoletedByCount == 0) {
268
	        // all pids were obsoleted
269
	        for(SystemMetadata sysmeta : sidChain) {
270
	            //System.out.println("=== the pid in system metadata "+sysmeta.getIdentifier().getValue());
271
	            Identifier obsoletedBy = sysmeta.getObsoletedBy();
272
	            SystemMetadata sysOfObsoletedBy = getSystemMetadata(obsoletedBy, chain);
273
	            if(sysOfObsoletedBy == null) {
274
	                //Rule 4 We have a obsoletedBy id without system metadata. So we can't decide if a different sid exists. we have to sort it.
275
	                System.out.println("rule 4");
276
	                Collections.sort(sidChain, new SystemMetadataDateUploadedComparator());
277
	                pid = sidChain.lastElement().getIdentifier();
278
	                break;
279
	            } else {
280
	                Identifier sidOfObsoletedBy = sysOfObsoletedBy.getSeriesId();
281
	                if(sidOfObsoletedBy != null && !sidOfObsoletedBy.equals(sid)) {
282
	                    //rule 3, if everything in {S1} is obsoleted, then select object that is obsoleted by another object that does not have the same SID
283
	                    System.out.println("rule 3-1 (close with another sid "+sidOfObsoletedBy.getValue()+")");
284
	                    pid = sysmeta.getIdentifier();
285
	                    break;
286
	                } else if (sidOfObsoletedBy == null ) {
287
	                    //rule 3, If everything in {S1} is obsoleted, then select object that is obsoleted by another object that does not have the same SID (this case, no sid)
288
	                    System.out.println("rule 3-2 (close without sid");
289
	                    pid = sysmeta.getIdentifier();
290
	                    break;
291
	                }
292
	            }
293
	            
294
	        }
295
	    }
296
	    return pid;
297
	}
298
	
299
	
300
	private SystemMetadata getSystemMetadata(Identifier id, Vector<SystemMetadata> chain ){
301
	    SystemMetadata sysmeta = null;
302
	    if(id != null) {
303
	        for(SystemMetadata sys : chain) {
304
	            if(sys.getIdentifier().equals(id)) {
305
	                sysmeta = sys;
306
	                break;
307
	            }
308
	        }
309
	    }
310
	    return sysmeta;
311
	}
312
}

Also available in: Unified diff