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.hazelcast;
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.types.v1.Identifier;
30
import org.dataone.service.types.v1.Node;
31
import org.dataone.service.types.v1.Permission;
32
import org.dataone.service.types.v1.SystemMetadata;
33

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

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

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

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

    
79
  /**
80
   * Constructor - create an empty replication task instance
81
   */
82
  public CNReplicationTask() {
83
  }
84

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

    
107
  /**
108
   * Get the task identifier for this task
109
   * @return the taskid
110
   */
111
  public String getTaskid() {
112
    return taskid;
113
  }
114

    
115
  /**
116
   * Set the task identifier for this task
117
   * @param taskid the taskid to set
118
   */
119
  public void setTaskid(String taskid) {
120
    this.taskid = taskid;
121
  }
122

    
123
  /**
124
   * Get the object identifier to be replicated
125
   * @return the pid
126
   */
127
  public Identifier getPid() {
128
    return pid;
129
  }
130

    
131
  /**
132
   * Set the object identifier to be replicated
133
   * @param pid the pid to set
134
   */
135
  public void setPid(Identifier pid) {
136
    this.pid = pid;
137
  }
138

    
139

    
140
  /**
141
   * Get the format type of the object to be replicated
142
   * @return the pid
143
   */
144
  public String getFormatType() {
145
    return this.formatType;
146
    
147
  }
148

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

    
158
  /**
159
   * Get the target node
160
   * @return the targetNode
161
   */
162
  public Node getTargetNode() {
163
    return targetNode;
164
  }
165

    
166
  /**
167
   * Set the target node
168
   * @param targetNode the targetNode to set
169
   */
170
  public void setTargetNode(Node targetNode) {
171
    this.targetNode = targetNode;
172
  }
173

    
174
  /**
175
   * Get the originating node
176
   * @return the originatingNode
177
   */
178
  public Node getOriginatingNode() {
179
    return originatingNode;
180
  }
181

    
182
  /**
183
   * Set the originating node
184
   * @param originatingNode the originatingNode to set
185
   */
186
  public void setOriginatingNode(Node originatingNode) {
187
    this.originatingNode = originatingNode;
188
  }
189

    
190
  /**
191
   * For the given Replication task, return the Subject listed in the target
192
   * node.  Usually used in authorizing a replication event.
193
   * 
194
   * @return subject - the subject listed in the target Node object as a string
195
   */
196
  public String getTargetNodeSubject() {
197
    
198
    return this.targetNodeSubject;
199
    
200
  }
201
  
202
  /**
203
   * Set the target node subject identifying the node
204
   * @param subject the targetNode subject
205
   */
206
  public void setTargetNodeSubject(String subject) {
207
    this.targetNodeSubject = subject;
208
  }
209
  
210
  /**
211
   * For the given Replication task, return the Subject listed in the target
212
   * node.  Usually used in authorizing a replication event.
213
   * 
214
   * @return subject - the subject listed in the target Node object as a string
215
   */
216
  public String getOriginatingNodeSubject() {
217
    
218
    return this.originatingNodeSubject;
219
    
220
  }
221
  
222
  /**
223
   * Set the target node subject identifying the node
224
   * @param subject the targetNode subject
225
   */
226
  public void setOriginatingNodeSubject(String subject) {
227
    this.originatingNodeSubject = subject;
228
  }
229
  
230
  /**
231
   * Get the permission being allowed for this task
232
   * 
233
   * @return subject - the subject listed in the target Node object
234
   */
235
  public String getPermission() {
236
    return this.permission;
237
    
238
  }
239
  
240
  /**
241
   * Set the permission being allowed for this task
242
   * @param subject the targetNode subject
243
   */
244
  public void setPermission(Permission permission) {
245
    this.permission = permission.name();
246
    
247
  }
248
 
249
  /**
250
   * Implement the Callable interface, providing code that initiates replication.
251
   * 
252
   * @return pid - the identifier of the replicated object upon success
253
   */
254
  public Identifier call() {
255
		
256
	// Get the D1 Hazelcast configuration parameters
257
	String hzSystemMetadata = 
258
		Settings.getConfiguration().getString("dataone.hazelcast.systemMetadata");
259
	
260
	// get the system metadata for the pid	
261
	IMap<Identifier, SystemMetadata> sysMetaMap = Hazelcast.getMap(hzSystemMetadata);
262
	
263
	// get the systemMetadata
264
	SystemMetadata sm = sysMetaMap.get(pid);
265
	// TODO: need any info from the system metadata?
266
	
267
	// get the object from source
268
	InputStream sciMetaORE = null;
269
	try {
270
		// get from the MN
271
		sciMetaORE = D1Client.getMN(originatingNode.getIdentifier()).get(null, pid);
272
		
273
		// save it to target
274
		D1Client.getMN(targetNode.getIdentifier()).create(null, pid, sciMetaORE, sm);
275
	} catch (Exception e) {
276
		// report up the stack, even though we can't declare it
277
		throw new RuntimeException(e.getMessage(), e);
278
	}
279

    
280
    return pid;
281
  }
282

    
283
}
(1-1/4)