/*
*
* * Copyright 2014 Orient Technologies LTD (info(at)orientechnologies.com)
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
* *
* * For more information: http://www.orientechnologies.com
*
*/
package com.orientechnologies.orient.server.distributed.impl.task;
import com.orientechnologies.orient.core.command.OCommandDistributedReplicateRequest;
import com.orientechnologies.orient.core.db.ODatabaseDocumentInternal;
import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal;
import com.orientechnologies.orient.core.id.ORecordId;
import com.orientechnologies.orient.server.OServer;
import com.orientechnologies.orient.server.distributed.*;
import com.orientechnologies.orient.server.distributed.task.OAbstractRecordReplicatedTask;
import com.orientechnologies.orient.server.distributed.task.ORemoteTask;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
/**
* Repairs a cluster through the distributed server. This task creates the missing records to realign all the servers to the same
* clusterPosition, in order to guarantee the RID integrity.
*
* @author Luca Garulli (l.garulli--at--orientechnologies.com)
*/
public class ORepairClusterTask extends OTxTask {
public static final int FACTORYID = 18;
private int clusterId;
public ORepairClusterTask() {
}
public ORepairClusterTask(final int clusterId) {
this.clusterId = clusterId;
}
@Override
public Object execute(final ODistributedRequestId requestId, final OServer iServer, final ODistributedServerManager iManager,
final ODatabaseDocumentInternal database) throws Exception {
final String clusterName = database.getClusterNameById(clusterId);
ODistributedServerLog.debug(this, iManager.getLocalNodeName(), getNodeSource(), ODistributedServerLog.DIRECTION.IN,
"Repair cluster: repairing cluster '%s' db=%s (reqId=%s)...", clusterName, database.getName(), requestId);
ODatabaseRecordThreadLocal.INSTANCE.set(database);
final ODistributedDatabase ddb = iManager.getMessageService().getDatabase(database.getName());
// CREATE A CONTEXT OF TX
final ODistributedTxContext reqContext = ddb.registerTxContext(requestId);
try {
final ODistributedConfiguration dCfg = iManager.getDatabaseConfiguration(database.getName());
// LOCK INSERTION ON THIS CLUSTER
reqContext.lock(new ORecordId(clusterId, -1));
for (OAbstractRecordReplicatedTask task : tasks) {
final Object taskResult;
// CHECK LOCAL CLUSTER IS AVAILABLE ON CURRENT SERVER
if (!task.checkForClusterAvailability(iManager.getLocalNodeName(), dCfg))
// SKIP EXECUTION BECAUSE THE CLUSTER IS NOT ON LOCAL NODE: THIS CAN HAPPENS IN CASE OF DISTRIBUTED TX WITH SHARDING
taskResult = NON_LOCAL_CLUSTER;
else {
task.setLockRecords(false);
task.checkRecordExists();
task.execute(requestId, iServer, iManager, database);
reqContext.addUndoTask(task.getUndoTask(requestId));
}
}
return null;
} catch (Throwable e) {
// if (e instanceof ODistributedRecordLockedException)
// ddb.dumpLocks();
ODistributedServerLog.debug(this, iManager.getLocalNodeName(), getNodeSource(), ODistributedServerLog.DIRECTION.IN,
"Repair cluster: rolling back transaction db=%s (reqId=%s error=%s)...", database.getName(), requestId, e);
// ddb.popTxContext(requestId);
reqContext.unlock();
return e;
} finally {
ODistributedServerLog.debug(this, iManager.getLocalNodeName(), getNodeSource(), ODistributedServerLog.DIRECTION.IN,
"Repair cluster: transaction completed db=%s (reqId=%s)...", database.getName(), requestId);
}
}
@Override
public void toStream(final DataOutput out) throws IOException {
super.toStream(out);
out.writeInt(clusterId);
}
@Override
public void fromStream(final DataInput in, final ORemoteTaskFactory factory) throws IOException {
super.fromStream(in, factory);
clusterId = in.readInt();
}
public OCommandDistributedReplicateRequest.QUORUM_TYPE getQuorumType() {
return OCommandDistributedReplicateRequest.QUORUM_TYPE.ALL;
}
@Override
public RESULT_STRATEGY getResultStrategy() {
return RESULT_STRATEGY.UNION;
}
@Override
public String getName() {
return "repair_cluster";
}
@Override
public int getFactoryId() {
return FACTORYID;
}
@Override
public ORemoteTask getUndoTask(ODistributedRequestId reqId) {
return null;
}
@Override
public ORemoteTask getFixTask(ODistributedRequest iRequest, ORemoteTask iOriginalTask, Object iBadResponse, Object iGoodResponse,
String executorNodeName, ODistributedServerManager dManager) {
return null;
}
}