Project

General

Profile

1 6405 cjones
/**
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 6418 leinfelder
import java.io.InputStream;
24 6405 cjones
import java.io.Serializable;
25
import java.util.concurrent.Callable;
26
27
import org.dataone.client.D1Client;
28
import org.dataone.configuration.Settings;
29 6418 leinfelder
import org.dataone.service.exceptions.NotFound;
30 6405 cjones
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 6418 leinfelder
import edu.ucsb.nceas.metacat.IdentifierManager;
39
import edu.ucsb.nceas.metacat.McdbDocNotFoundException;
40
41 6405 cjones
/**
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 6418 leinfelder
public class CNReplicationTask implements Serializable, Callable<Identifier> {
58 6405 cjones
59
  /* The identifier of this task */
60
  private String taskid;
61
62
  /* The identifier of the object to replicate */
63 6418 leinfelder
  private Identifier pid;
64 6405 cjones
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 6418 leinfelder
    this.pid = pid;
102 6405 cjones
    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 6418 leinfelder
    return pid;
133 6405 cjones
  }
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 6418 leinfelder
    this.pid = pid;
141 6405 cjones
  }
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 6418 leinfelder
  public Identifier call() {
259 6405 cjones
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 6418 leinfelder
	// get the systemMetadata
268
	SystemMetadata sm = sysMetaMap.get(pid);
269 6405 cjones
270 6418 leinfelder
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 6405 cjones
  }
308
309
}