Project

General

Profile

1
/**
2
 * This work was created by participants in the DataONE project, and is
3
 * jointly copyrighted by participating institutions in DataONE. For
4
 * more information on DataONE, see our web site at http://dataone.org.
5
 *
6
 *   Copyright ${year}
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *   http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20

    
21
package edu.ucsb.nceas.metacat.dataone;
22

    
23
import java.io.InputStream;
24
import java.io.Serializable;
25
import java.util.concurrent.Callable;
26

    
27
import org.dataone.client.D1Client;
28
import org.dataone.configuration.Settings;
29
import org.dataone.service.exceptions.NotFound;
30
import org.dataone.service.types.v1.Identifier;
31
import org.dataone.service.types.v1.Node;
32
import org.dataone.service.types.v1.Permission;
33
import org.dataone.service.types.v1.SystemMetadata;
34

    
35
import com.hazelcast.core.Hazelcast;
36
import com.hazelcast.core.IMap;
37

    
38
import edu.ucsb.nceas.metacat.IdentifierManager;
39
import edu.ucsb.nceas.metacat.McdbDocNotFoundException;
40

    
41
/**
42
 * A single CN replication task to be executed by the CN Replication Service. This 
43
 * applies to replication of system metadata, science metadata, and resource maps 
44
 * across CNs.
45
 * 
46
 * The task is built when a change occurs in the hzSystemMetadata map in the
47
 * storage cluster initiated by Metacat for a given PID. If the change involves
48
 * only modifications to system metadata, those changes will occur in the shared
49
 * map and in the backing store of the member that owns the map entry. Other 
50
 * members must be updated using this task.  Likewise, changes to the system
51
 * metadata map that involve science metadata creation or changes will be
52
 * distributed to all members via this task.  The same is for OAI-ORE resource maps.
53
 * 
54
 * @author cjones
55
 *
56
 */
57
public class CNReplicationTask implements Serializable, Callable<Identifier> {
58

    
59
  /* The identifier of this task */
60
  private String taskid;
61
  
62
  /* The identifier of the object to replicate */
63
  private Identifier pid;
64
  
65
  /* The object format type stated in the system metadata (DATA/METADATA/RESOURCE) */
66
  private String formatType;
67
  
68
  /* The target Node object */
69
  private Node targetNode;
70
  
71
  /* The originating Node object */
72
  private Node originatingNode;
73

    
74
  /* The subject of the target node, extracted from the Node object */
75
  private String targetNodeSubject;
76
  
77
  /* The subject of the originating node, extracted from the Node object */
78
  private String originatingNodeSubject;
79
  
80
  /* The permission to be executed (in this case, always 'replicate') */
81
  String permission;
82

    
83
  /**
84
   * Constructor - create an empty replication task instance
85
   */
86
  public CNReplicationTask() {
87
  }
88

    
89
  /**
90
   * Constructor - create a replication task instance
91
   * 
92
   * @param taskid
93
   * @param pid
94
   * @param targetNode
95
   */
96
  public CNReplicationTask(String taskid, Identifier pid, String formatType,
97
    Node originatingNode, Node targetNode,
98
    Permission replicatePermission) {
99
    
100
    this.taskid = taskid;
101
    this.pid = pid;
102
    this.formatType = formatType;
103
    this.originatingNode = originatingNode;
104
    this.targetNode = targetNode;
105
    this.originatingNodeSubject = originatingNode.getSubject(0).getValue();
106
    this.targetNodeSubject = targetNode.getSubject(0).getValue();
107
    this.permission = replicatePermission.name();
108
    
109
  }
110

    
111
  /**
112
   * Get the task identifier for this task
113
   * @return the taskid
114
   */
115
  public String getTaskid() {
116
    return taskid;
117
  }
118

    
119
  /**
120
   * Set the task identifier for this task
121
   * @param taskid the taskid to set
122
   */
123
  public void setTaskid(String taskid) {
124
    this.taskid = taskid;
125
  }
126

    
127
  /**
128
   * Get the object identifier to be replicated
129
   * @return the pid
130
   */
131
  public Identifier getPid() {
132
    return pid;
133
  }
134

    
135
  /**
136
   * Set the object identifier to be replicated
137
   * @param pid the pid to set
138
   */
139
  public void setPid(Identifier pid) {
140
    this.pid = pid;
141
  }
142

    
143

    
144
  /**
145
   * Get the format type of the object to be replicated
146
   * @return the pid
147
   */
148
  public String getFormatType() {
149
    return this.formatType;
150
    
151
  }
152

    
153
  /**
154
   * Set the format type of the object to be replicated
155
   * @param pid the pid to set
156
   */
157
  public void setFormatType(String formatType) {
158
    this.formatType = formatType;
159
    
160
  }
161

    
162
  /**
163
   * Get the target node
164
   * @return the targetNode
165
   */
166
  public Node getTargetNode() {
167
    return targetNode;
168
  }
169

    
170
  /**
171
   * Set the target node
172
   * @param targetNode the targetNode to set
173
   */
174
  public void setTargetNode(Node targetNode) {
175
    this.targetNode = targetNode;
176
  }
177

    
178
  /**
179
   * Get the originating node
180
   * @return the originatingNode
181
   */
182
  public Node getOriginatingNode() {
183
    return originatingNode;
184
  }
185

    
186
  /**
187
   * Set the originating node
188
   * @param originatingNode the originatingNode to set
189
   */
190
  public void setOriginatingNode(Node originatingNode) {
191
    this.originatingNode = originatingNode;
192
  }
193

    
194
  /**
195
   * For the given Replication task, return the Subject listed in the target
196
   * node.  Usually used in authorizing a replication event.
197
   * 
198
   * @return subject - the subject listed in the target Node object as a string
199
   */
200
  public String getTargetNodeSubject() {
201
    
202
    return this.targetNodeSubject;
203
    
204
  }
205
  
206
  /**
207
   * Set the target node subject identifying the node
208
   * @param subject the targetNode subject
209
   */
210
  public void setTargetNodeSubject(String subject) {
211
    this.targetNodeSubject = subject;
212
  }
213
  
214
  /**
215
   * For the given Replication task, return the Subject listed in the target
216
   * node.  Usually used in authorizing a replication event.
217
   * 
218
   * @return subject - the subject listed in the target Node object as a string
219
   */
220
  public String getOriginatingNodeSubject() {
221
    
222
    return this.originatingNodeSubject;
223
    
224
  }
225
  
226
  /**
227
   * Set the target node subject identifying the node
228
   * @param subject the targetNode subject
229
   */
230
  public void setOriginatingNodeSubject(String subject) {
231
    this.originatingNodeSubject = subject;
232
  }
233
  
234
  /**
235
   * Get the permission being allowed for this task
236
   * 
237
   * @return subject - the subject listed in the target Node object
238
   */
239
  public String getPermission() {
240
    return this.permission;
241
    
242
  }
243
  
244
  /**
245
   * Set the permission being allowed for this task
246
   * @param subject the targetNode subject
247
   */
248
  public void setPermission(Permission permission) {
249
    this.permission = permission.name();
250
    
251
  }
252
 
253
  /**
254
   * Implement the Callable interface, providing code that initiates replication.
255
   * 
256
   * @return pid - the identifier of the replicated object upon success
257
   */
258
  public Identifier call() {
259
		
260
	// Get the D1 Hazelcast configuration parameters
261
	String hzSystemMetadata = 
262
		Settings.getConfiguration().getString("dataone.hazelcast.systemMetadata");
263
	
264
	// get the system metadata for the pid	
265
	IMap<Identifier, SystemMetadata> sysMetaMap = Hazelcast.getMap(hzSystemMetadata);
266
	
267
	// get the systemMetadata
268
	SystemMetadata sm = sysMetaMap.get(pid);
269
	
270
	
271
  	
272
  	// only system metadata - no data replicated
273
  	boolean isData = formatType.equals("??");
274
  	if (!isData) {
275
  		// TODO: get the science metadata/ORE from somewhere
276
  		InputStream sciMetaORE = null;
277
		try {
278
			sciMetaORE = CNodeService.getInstance().get(null, pid);
279
		} catch (NotFound nf) {
280
			try {
281
				sciMetaORE = D1Client.getCN().get(null, pid);
282
				// save it locally
283
		  		CNodeService.getInstance().create(null, pid, sciMetaORE, sm);
284
			} catch (Exception e) {
285
				// TODO Auto-generated catch block
286
				e.printStackTrace();
287
			}
288
		} catch (Exception e) {
289
			e.printStackTrace();
290
		}
291
  	} else {
292
  		// just system metadata
293
  		try {
294
  			if (!IdentifierManager.getInstance().identifierExists(pid.getValue())) {
295
  				IdentifierManager.getInstance().createSystemMetadata(sm);
296
  			} else {
297
  				IdentifierManager.getInstance().updateSystemMetadata(sm);
298
  			}  
299
  	  	} catch (McdbDocNotFoundException e) {
300
  			// TODO Auto-generated catch block
301
  			e.printStackTrace();
302
  			return null;
303
  		}
304
  	}
305
  	
306
    return pid;
307
  }
308

    
309
}
(1-1/7)