Project

General

Profile

« Previous | Next » 

Revision 6869

Added by Chris Jones over 12 years ago

Update the CN methods to throw a VersionMismatch where the API changed (where serialVersion is a required parameter). These were previously throwing an InvalidRequest exception.
Change the exception handling for calls to Hazelcast to catch a RuntimeException (not Exception) so we don't catch exceptions that we purposefully throw.
Modify methods to allow for CN administrative access (like setRightsHolder()) by using isAdminAuthorized and the CN session subject.
In setReplicationStatus(), it's possible that a CN may try to set the status on a non-existent replica entry. Call updateReplicationMetadata() to create the new entry in this case, and then update the entry as normal.
Update CNResourceHandler to throw VersionMismatch where needed.

View differences:

src/edu/ucsb/nceas/metacat/restservice/CNResourceHandler.java
54 54
import org.dataone.service.exceptions.NotImplemented;
55 55
import org.dataone.service.exceptions.ServiceFailure;
56 56
import org.dataone.service.exceptions.UnsupportedType;
57
import org.dataone.service.exceptions.VersionMismatch;
57 58
import org.dataone.service.types.v1.AccessPolicy;
58 59
import org.dataone.service.types.v1.Checksum;
59 60
import org.dataone.service.types.v1.ChecksumAlgorithmList;
......
884 885
     * @throws IOException
885 886
     * @throws IllegalAccessException
886 887
     * @throws InstantiationException
888
     * @throws VersionMismatch 
887 889
     */
888 890
    private void owner(String id) throws JiBXException, InvalidToken,
889 891
            ServiceFailure, NotFound, NotAuthorized, NotImplemented,
890 892
            InvalidRequest, IOException, InstantiationException,
891
            IllegalAccessException {
893
            IllegalAccessException, VersionMismatch {
892 894

  
893 895
        Identifier pid = new Identifier();
894 896
        pid.setValue(id);
......
999 1001
     * @throws IOException
1000 1002
     * @throws SAXException
1001 1003
     * @throws ParserConfigurationException
1004
     * @throws VersionMismatch 
1002 1005
     */
1003 1006
    protected void setAccess(String pid) throws JiBXException, InvalidToken,
1004 1007
            ServiceFailure, NotFound, NotAuthorized, NotImplemented,
1005 1008
            InvalidRequest, IOException, InstantiationException,
1006
            IllegalAccessException, ParserConfigurationException, SAXException {
1009
            IllegalAccessException, ParserConfigurationException, SAXException, VersionMismatch {
1007 1010

  
1008 1011
        long serialVersion = 0L;
1009 1012
        String serialVersionStr = null;
......
1181 1184
     * @throws InstantiationException
1182 1185
     * @throws IllegalAccessException
1183 1186
     * @throws JiBXException
1187
     * @throws VersionMismatch 
1184 1188
     */
1185 1189
    public boolean setReplicationPolicy(String pid) throws NotImplemented,
1186 1190
            NotFound, NotAuthorized, ServiceFailure, InvalidRequest,
1187 1191
            InvalidToken, IOException, InstantiationException,
1188
            IllegalAccessException, JiBXException {
1192
            IllegalAccessException, JiBXException, VersionMismatch {
1189 1193

  
1190 1194
        boolean result = false;
1191 1195
        ReplicationPolicy policy = null;
......
1340 1344
     * @throws NotAuthorized
1341 1345
     * @throws InvalidRequest
1342 1346
     * @throws NotFound
1347
     * @throws VersionMismatch 
1343 1348
     */
1344 1349
    public boolean updateReplicationMetadata(String pid) throws ServiceFailure,
1345 1350
            NotImplemented, InvalidToken, NotAuthorized, InvalidRequest,
1346
            NotFound {
1351
            NotFound, VersionMismatch {
1347 1352

  
1348 1353
        boolean result = false;
1349 1354
        long serialVersion = 0L;
src/edu/ucsb/nceas/metacat/dataone/CNodeService.java
51 51
import org.dataone.service.exceptions.NotImplemented;
52 52
import org.dataone.service.exceptions.ServiceFailure;
53 53
import org.dataone.service.exceptions.UnsupportedType;
54
import org.dataone.service.exceptions.VersionMismatch;
54 55
import org.dataone.service.types.v1.AccessPolicy;
55 56
import org.dataone.service.types.v1.Checksum;
56 57
import org.dataone.service.types.v1.ChecksumAlgorithmList;
......
118 119
   * @throws NotAuthorized
119 120
   * @throws ServiceFailure
120 121
   * @throws InvalidRequest
122
   * @throws VersionMismatch
121 123
   * 
122 124
   */
123 125
  @Override
124 126
  public boolean setReplicationPolicy(Session session, Identifier pid,
125 127
      ReplicationPolicy policy, long serialVersion) 
126 128
      throws NotImplemented, NotFound, NotAuthorized, ServiceFailure, 
127
      InvalidRequest, InvalidToken {
129
      InvalidRequest, InvalidToken, VersionMismatch {
128 130
      
129 131
      // The lock to be used for this identifier
130 132
      Lock lock = null;
......
134 136
      
135 137
      // are we allowed to do this?
136 138
      if (!isAdminAuthorized(session, pid, Permission.CHANGE_PERMISSION)) {
137
        if (!isAuthorized(session, pid, Permission.CHANGE_PERMISSION)) {
138
            throw new NotAuthorized("4881", Permission.CHANGE_PERMISSION
139
                    + " not allowed by " + subject.getValue() + " on "
140
                    + pid.getValue());
141
        }
142
    }
143
    SystemMetadata systemMetadata = null;
139
          if (!isAuthorized(session, pid, Permission.CHANGE_PERMISSION)) {
140
              throw new NotAuthorized("4881", Permission.CHANGE_PERMISSION
141
                      + " not allowed by " + subject.getValue() + " on "
142
                      + pid.getValue());
143
              
144
          }
145
      }
146
      
147
      SystemMetadata systemMetadata = null;
144 148
      try {
145 149
          lock = HazelcastService.getInstance().getLock(pid.getValue());
146 150
          lock.lock();
......
151 155
                  systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
152 156
                  
153 157
              }
154
            
158
              
159
              // did we get it correctly?
160
              if ( systemMetadata == null ) {
161
                  throw new NotFound("4884", "Couldn't find an object identified by " + pid.getValue());
162
                  
163
              }
155 164

  
156 165
              // does the request have the most current system metadata?
157 166
              if ( systemMetadata.getSerialVersion().longValue() != serialVersion ) {
......
159 168
                     serialVersion + " differs from the current version at " +
160 169
                     systemMetadata.getSerialVersion().longValue() +
161 170
                     ". Please get the latest copy in order to modify it.";
162
                 throw new InvalidRequest("4883", msg);
171
                 throw new VersionMismatch("4886", msg);
172
                 
163 173
              }
164 174
              
165
          } catch (Exception e) { // Catch is generic since HZ throws RuntimeException
175
          } catch (RuntimeException e) { // Catch is generic since HZ throws RuntimeException
166 176
              throw new NotFound("4884", "No record found for: " + pid.getValue());
167 177
            
168 178
          }
......
176 186
              systemMetadata.setDateSysMetadataModified(Calendar.getInstance().getTime());
177 187
              HazelcastService.getInstance().getSystemMetadataMap().put(systemMetadata.getIdentifier(), systemMetadata);
178 188
            
179
          } catch (Exception e) {
189
          } catch (RuntimeException e) {
180 190
              throw new ServiceFailure("4882", e.getMessage());
181 191
          
182 192
          }
183 193
          
184
    } catch (Exception e) {
185
        throw new ServiceFailure("4882", e.getMessage());
186
        
187
    } finally {
188
        lock.unlock();
189
        logMetacat.debug("Unlocked identifier " + pid.getValue());
190
        
191
    }
194
      } catch (RuntimeException e) {
195
          throw new ServiceFailure("4882", e.getMessage());
196
          
197
      } finally {
198
          lock.unlock();
199
          logMetacat.debug("Unlocked identifier " + pid.getValue());
200
          
201
      }
192 202
    
193 203
      return true;
194 204
  }
......
237 247
          try {      
238 248
              systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
239 249

  
250
              // did we get it correctly?
240 251
              if ( systemMetadata == null ) {
241 252
                  logMetacat.debug("systemMetadata is null for " + pid.getValue());
253
                  throw new NotFound("4740", "Couldn't find an object identified by " + pid.getValue());
242 254
                  
243 255
              }
244 256
              replicas = systemMetadata.getReplicaList();
245 257
              int count = 0;
246 258
              
247 259
              if ( replicas == null || replicas.size() < 1 ) {
248
                  logMetacat.debug("no replicas to evaluate");
249
                  throw new InvalidRequest("4730", "There are no replicas to update.");
260
                  logMetacat.debug("No replicas to evaluate for " + pid.getValue());
261
                  Replica newReplica = new Replica();
262
                  newReplica.setReplicaMemberNode(targetNode);
263
                  newReplica.setReplicationStatus(status);
264
                  newReplica.setReplicaVerified(Calendar.getInstance().getTime());
265
                  try {
266
                    // if there is no replica entry, create one
267
                    updateReplicationMetadata(session, pid, newReplica, 
268
                        systemMetadata.getSerialVersion().longValue());
269
                    
270
                  } catch (VersionMismatch e) {
271
                      // try again if we somehow don't have the correct version
272
                      String msg = "The serial version of the system metadata doesn't match. Trying again.";
273
                      logMetacat.info(msg);
274
                      systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
275
                      try {
276
                        updateReplicationMetadata(session, pid, newReplica, 
277
                            systemMetadata.getSerialVersion().longValue());
278
                        
279
                      } catch (VersionMismatch e1) {
280
                          throw new ServiceFailure("4700", 
281
                              "Couldn't get the correct serial version of the system metadata: " +
282
                              e1.getCause().getMessage());
283
                          
284
                      }
285

  
286
                  }
250 287
                  
251 288
              }
252

  
289
              
290
              // refresh the system metadata and replica list
291
              systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
292
              replicas = systemMetadata.getReplicaList();
293
                  
253 294
              // find the target replica index in the replica list
254 295
              for (Replica replica: replicas) {
255 296
                  String replicaNodeStr = replica.getReplicaMemberNode().getValue();
......
339 380
                      " on target node " + targetNode + ". The exception was: " +
340 381
                      failure.getMessage());
341 382
              }
342
          } catch (Exception e) {
383
          } catch (RuntimeException e) {
343 384
              throw new ServiceFailure("4700", e.getMessage());
344 385
          
345 386
          }
......
459 500
  public Checksum getChecksum(Session session, Identifier pid)
460 501
    throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, 
461 502
    NotImplemented {
462
        
463
    // The lock to be used for thyis identifier
464
    Lock lock = null;
465
    
503
            
466 504
    if (!isAuthorized(session, pid, Permission.READ)) {
467 505
        throw new NotAuthorized("1400", Permission.READ + " not allowed on " + pid.getValue());  
468 506
    }
......
471 509
    Checksum checksum = null;
472 510
    
473 511
    try {
474
        systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
512
        systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);        
513

  
514
        if (systemMetadata == null ) {
515
            throw new NotFound("1420", "Couldn't find an object identified by " + pid.getValue());
516
        }
475 517
        checksum = systemMetadata.getChecksum();
476

  
477
    } catch (Exception e) {
518
        
519
    } catch (RuntimeException e) {
478 520
        throw new ServiceFailure("1410", "An error occurred getting the checksum for " + 
479 521
            pid.getValue() + ". The error message was: " + e.getMessage());
480 522
      
......
713 755
              sysmeta.setDateSysMetadataModified(Calendar.getInstance().getTime());
714 756
              HazelcastService.getInstance().getSystemMetadataMap().put(sysmeta.getIdentifier(), sysmeta);
715 757
              
716
          } catch (Exception e) {
758
          } catch (RuntimeException e) {
717 759
            logMetacat.error("Problem registering system metadata: " + pid.getValue(), e);
718 760
              throw new ServiceFailure("4862", "Error inserting system metadata: " + 
719 761
                  e.getClass() + ": " + e.getMessage());
720 762
              
721 763
          }
722 764
          
723
      } catch (Exception e) {
765
      } catch (RuntimeException e) {
724 766
          throw new ServiceFailure("4862", "Error inserting system metadata: " + 
725 767
                  e.getClass() + ": " + e.getMessage());
726 768
          
......
826 868
  public Identifier setRightsHolder(Session session, Identifier pid, Subject userId,
827 869
      long serialVersion)
828 870
      throws InvalidToken, ServiceFailure, NotFound, NotAuthorized,
829
      NotImplemented, InvalidRequest {
871
      NotImplemented, InvalidRequest, VersionMismatch {
830 872
      
831 873
      // The lock to be used for this identifier
832 874
      Lock lock = null;
......
836 878
      
837 879
      // are we allowed to do this?
838 880
      if (!isAdminAuthorized(session, pid, Permission.CHANGE_PERMISSION)) {
839
        if (!isAuthorized(session, pid, Permission.CHANGE_PERMISSION)) {
840
            throw new NotAuthorized("4440", "not allowed by "
841
                    + subject.getValue() + " on " + pid.getValue());
842
        }
843
    }
844
    SystemMetadata systemMetadata = null;
881
          if (!isAuthorized(session, pid, Permission.CHANGE_PERMISSION)) {
882
              throw new NotAuthorized("4440", "not allowed by "
883
                      + subject.getValue() + " on " + pid.getValue());
884
              
885
          }
886
      }
887
      
888
      SystemMetadata systemMetadata = null;
845 889
      try {
846 890
          lock = HazelcastService.getInstance().getLock(pid.getValue());
847 891
          logMetacat.debug("Locked identifier " + pid.getValue());
......
855 899
                     serialVersion + " differs from the current version at " +
856 900
                     systemMetadata.getSerialVersion().longValue() +
857 901
                     ". Please get the latest copy in order to modify it.";
858
                 throw new InvalidRequest("4442", msg);
902
                 throw new VersionMismatch("4443", msg);
859 903
              }
860 904
              
861
          } catch (Exception e) { // Catch is generic since HZ throws RuntimeException
905
          } catch (RuntimeException e) { // Catch is generic since HZ throws RuntimeException
862 906
              throw new NotFound("4460", "No record found for: " + pid.getValue());
863 907
              
864 908
          }
......
872 916
              systemMetadata.setDateSysMetadataModified(Calendar.getInstance().getTime());
873 917
              HazelcastService.getInstance().getSystemMetadataMap().put(pid, systemMetadata);
874 918
              
875
          } catch (Exception e) {
876
          throw new ServiceFailure("4490", e.getMessage());
919
          } catch (RuntimeException e) {
920
              throw new ServiceFailure("4490", e.getMessage());
877 921
          
878 922
          }
879 923
          
880
      } catch (Exception e) {
924
      } catch (RuntimeException e) {
881 925
          throw new ServiceFailure("4490", e.getMessage());
882 926
          
883 927
      } finally {
......
886 930
      
887 931
      }
888 932
      
889
    return pid;
933
      return pid;
890 934
  }
891 935

  
892 936
  /**
......
912 956
    Subject targetNodeSubject, Identifier pid) 
913 957
    throws NotImplemented, NotAuthorized, InvalidToken, ServiceFailure, 
914 958
    NotFound, InvalidRequest {
915

  
916
    // The lock to be used for this identifier
917
    Lock lock = null;
918 959
    
919 960
    boolean isAllowed = false;
920 961
    SystemMetadata sysmeta = null;
......
990 1031
      } else {
991 1032
          logMetacat.debug("System metadata for identifier " + pid.getValue() +
992 1033
          " is null.");          
1034
          throw new NotFound("4874", "Couldn't find an object identified by " + pid.getValue());
993 1035
          
994 1036
      }
995 1037

  
......
1037 1079
      Lock lock = null;
1038 1080
      
1039 1081
      try {
1040
        // are we allowed?
1082
          lock = HazelcastService.getInstance().getLock(pid.getValue());
1083
          // are we allowed?
1041 1084
          boolean isAllowed = false;
1042 1085
          CNode cn = D1Client.getCN();
1043 1086
          NodeList nodeList = cn.listNodes();
......
1058 1101
          // proceed if we're called by a CN
1059 1102
          if ( isAllowed ) {
1060 1103
              // create the coordinating node version of the document      
1061
              lock = HazelcastService.getInstance().getLock(pid.getValue());
1062 1104
              lock.lock();
1063 1105
              logMetacat.debug("Locked identifier " + pid.getValue());
1064 1106
              sysmeta.setSerialVersion(BigInteger.ONE);
......
1108 1150
  public boolean setAccessPolicy(Session session, Identifier pid, 
1109 1151
      AccessPolicy accessPolicy, long serialVersion) 
1110 1152
      throws InvalidToken, ServiceFailure, NotFound, NotAuthorized, 
1111
      NotImplemented, InvalidRequest {
1153
      NotImplemented, InvalidRequest, VersionMismatch {
1112 1154
      
1113 1155
      // The lock to be used for this identifier
1114 1156
      Lock lock = null;
1157
      SystemMetadata systemMetadata = null;
1115 1158
      
1116 1159
      boolean success = false;
1117 1160
      
1118 1161
      // get the subject
1119 1162
      Subject subject = session.getSubject();
1120 1163
      
1121
      // are we allowed to do this?
1122
      if (!isAuthorized(session, pid, Permission.CHANGE_PERMISSION)) {
1123
          throw new NotAuthorized("4420", "not allowed by " + subject.getValue() + 
1124
          " on " + pid.getValue());  
1164
      if (!isAdminAuthorized(session, pid, Permission.CHANGE_PERMISSION)) {
1165
          // are we allowed to do this?
1166
          if (!isAuthorized(session, pid, Permission.CHANGE_PERMISSION)) {
1167
              throw new NotAuthorized("4420", "not allowed by "
1168
                      + subject.getValue() + " on " + pid.getValue());
1169
          }
1125 1170
      }
1126 1171
      
1127
      SystemMetadata systemMetadata = null;
1128 1172
      try {
1129 1173
          lock = HazelcastService.getInstance().getLock(pid.getValue());
1130 1174
          lock.lock();
......
1133 1177
          try {
1134 1178
              systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
1135 1179

  
1180
              if ( systemMetadata == null ) {
1181
                  throw new NotFound("4400", "Couldn't find an object identified by " + pid.getValue());
1182
                  
1183
              }
1136 1184
              // does the request have the most current system metadata?
1137 1185
              if ( systemMetadata.getSerialVersion().longValue() != serialVersion ) {
1138 1186
                 String msg = "The requested system metadata version number " + 
1139 1187
                     serialVersion + " differs from the current version at " +
1140 1188
                     systemMetadata.getSerialVersion().longValue() +
1141 1189
                     ". Please get the latest copy in order to modify it.";
1142
                 throw new InvalidRequest("4402", msg);
1190
                 throw new VersionMismatch("4402", msg);
1191
                 
1143 1192
              }
1144 1193
              
1145
          } catch (Exception e) {
1194
          } catch (RuntimeException e) {
1146 1195
              // convert Hazelcast RuntimeException to NotFound
1147 1196
              throw new NotFound("4400", "No record found for: " + pid);
1148 1197
            
......
1157 1206
              systemMetadata.setDateSysMetadataModified(Calendar.getInstance().getTime());
1158 1207
              HazelcastService.getInstance().getSystemMetadataMap().put(systemMetadata.getIdentifier(), systemMetadata);
1159 1208
            
1160
          } catch (Exception e) {
1209
          } catch (RuntimeException e) {
1161 1210
              // convert Hazelcast RuntimeException to ServiceFailure
1162 1211
              throw new ServiceFailure("4430", e.getMessage());
1163 1212
            
1164 1213
          }
1165 1214
          
1166
      } catch (Exception e) {
1215
      } catch (RuntimeException e) {
1167 1216
          throw new ServiceFailure("4430", e.getMessage());
1168 1217
          
1169 1218
      } finally {
......
1192 1241
   * @throws ServiceFailure
1193 1242
   * @throws InvalidRequest
1194 1243
   * @throws NotFound
1244
   * @throws VersionMismatch
1195 1245
   */
1246
  @Override
1196 1247
  public boolean updateReplicationMetadata(Session session, Identifier pid,
1197 1248
      Replica replica, long serialVersion) 
1198 1249
      throws NotImplemented, NotAuthorized, ServiceFailure, InvalidRequest,
1199
      NotFound {
1250
      NotFound, VersionMismatch {
1200 1251
      
1201 1252
      // The lock to be used for this identifier
1202 1253
      Lock lock = null;
......
1235 1286
                     serialVersion + " differs from the current version at " +
1236 1287
                     systemMetadata.getSerialVersion().longValue() +
1237 1288
                     ". Please get the latest copy in order to modify it.";
1238
                 throw new InvalidRequest("4853", msg);
1289
                 throw new VersionMismatch("4855", msg);
1239 1290
              }
1240 1291
              
1241
          } catch (Exception e) { // Catch is generic since HZ throws RuntimeException
1242
            throw new NotFound("4854", "No record found for: " + pid.getValue() +
1243
                " : " + e.getMessage());
1292
          } catch (RuntimeException e) { // Catch is generic since HZ throws RuntimeException
1293
              throw new NotFound("4854", "No record found for: " + pid.getValue() +
1294
                  " : " + e.getMessage());
1244 1295
            
1245 1296
          }
1246 1297
              
......
1269 1320
              systemMetadata.setDateSysMetadataModified(Calendar.getInstance().getTime());
1270 1321
              HazelcastService.getInstance().getSystemMetadataMap().put(systemMetadata.getIdentifier(), systemMetadata);
1271 1322
            
1272
          } catch (Exception e) {
1323
          } catch (RuntimeException e) {
1324
              logMetacat.info("Unknown RuntimeException thrown: " + e.getCause().getMessage());
1273 1325
              throw new ServiceFailure("4852", e.getMessage());
1274 1326
          
1275 1327
          }
1276 1328
          
1277
    } catch (Exception e) {
1278
        throw new ServiceFailure("4852", e.getMessage());
1279

  
1280
    } finally {
1281
        lock.unlock();
1282
        logMetacat.debug("Unlocked identifier " + pid.getValue());
1283
        
1284
    }
1329
      } catch (RuntimeException e) {
1330
          logMetacat.info("Unknown RuntimeException thrown: " + e.getCause().getMessage());
1331
          throw new ServiceFailure("4852", e.getMessage());
1332
      
1333
      } finally {
1334
          lock.unlock();
1335
          logMetacat.debug("Unlocked identifier " + pid.getValue());
1336
          
1337
      }
1285 1338
    
1286 1339
      return true;
1287 1340
      
1288 1341
  }
1289 1342
  
1290
    @Override
1343
  /**
1344
   * 
1345
   */
1346
  @Override
1291 1347
  public ObjectList listObjects(Session session, Date startTime, 
1292 1348
      Date endTime, ObjectFormatIdentifier formatid, Boolean replicaStatus,
1293 1349
      Integer start, Integer count)
......
1304 1360
        return objectList;
1305 1361
  }
1306 1362

  
1307
	@Override
1363
	/**
1364
	 * 
1365
	 */
1366
  @Override
1308 1367
	public ChecksumAlgorithmList listChecksumAlgorithms()
1309 1368
			throws ServiceFailure, NotImplemented {
1310 1369
		ChecksumAlgorithmList cal = new ChecksumAlgorithmList();

Also available in: Unified diff