Search in sources :

Example 1 with OOfflineNodeException

use of com.orientechnologies.common.concur.OOfflineNodeException in project orientdb by orientechnologies.

the class OStorageRemote method reopenRemoteDatabase.

protected String reopenRemoteDatabase() throws IOException {
    String currentURL = getCurrentServerURL();
    do {
        do {
            final OChannelBinaryAsynchClient network = getNetwork(currentURL);
            try {
                OStorageRemoteSession session = getCurrentSession();
                OStorageRemoteNodeSession nodeSession = session.getOrCreateServerSession(network.getServerURL());
                if (nodeSession == null || !nodeSession.isValid()) {
                    openRemoteDatabase(network);
                    connectionManager.release(network);
                    return network.getServerURL();
                } else {
                    try {
                        network.writeByte(OChannelBinaryProtocol.REQUEST_DB_REOPEN);
                        network.writeInt(nodeSession.getSessionId());
                        network.writeBytes(nodeSession.getToken());
                    } finally {
                        endRequest(network);
                    }
                    final int sessionId;
                    try {
                        byte[] newToken = network.beginResponse(nodeSession.getSessionId(), true);
                        sessionId = network.readInt();
                        if (newToken != null && newToken.length > 0) {
                            nodeSession.setSession(sessionId, newToken);
                        } else {
                            nodeSession.setSession(sessionId, nodeSession.getToken());
                        }
                        OLogManager.instance().debug(this, "Client connected to %s with session id=%d", network.getServerURL(), sessionId);
                        return currentURL;
                    } finally {
                        endResponse(network);
                        connectionManager.release(network);
                    }
                }
            } catch (OIOException e) {
                if (network != null) {
                    // REMOVE THE NETWORK CONNECTION IF ANY
                    connectionManager.remove(network);
                }
                OLogManager.instance().error(this, "Cannot open database with url " + currentURL, e);
            } catch (OOfflineNodeException e) {
                if (network != null) {
                    // REMOVE THE NETWORK CONNECTION IF ANY
                    connectionManager.remove(network);
                }
                OLogManager.instance().debug(this, "Cannot open database with url " + currentURL, e);
            } catch (OSecurityException ex) {
                OLogManager.instance().debug(this, "Invalidate token for url=%s", ex, currentURL);
                OStorageRemoteSession session = getCurrentSession();
                session.removeServerSession(currentURL);
                if (network != null) {
                    // REMOVE THE NETWORK CONNECTION IF ANY
                    try {
                        connectionManager.remove(network);
                    } catch (Exception e) {
                        // IGNORE ANY EXCEPTION
                        OLogManager.instance().debug(this, "Cannot remove connection or database url=" + currentURL, e);
                    }
                }
            } catch (OException e) {
                connectionManager.release(network);
                // PROPAGATE ANY OTHER ORIENTDB EXCEPTION
                throw e;
            } catch (Exception e) {
                OLogManager.instance().debug(this, "Cannot open database with url " + currentURL, e);
                if (network != null) {
                    // REMOVE THE NETWORK CONNECTION IF ANY
                    try {
                        connectionManager.remove(network);
                    } catch (Exception ex) {
                        // IGNORE ANY EXCEPTION
                        OLogManager.instance().debug(this, "Cannot remove connection or database url=" + currentURL, e);
                    }
                }
            }
        } while (connectionManager.getAvailableConnections(currentURL) > 0);
        currentURL = useNewServerURL(currentURL);
    } while (currentURL != null);
    // REFILL ORIGINAL SERVER LIST
    parseServerURLs();
    synchronized (serverURLs) {
        throw new OStorageException("Cannot create a connection to remote server address(es): " + serverURLs);
    }
}
Also used : OOfflineNodeException(com.orientechnologies.common.concur.OOfflineNodeException) OException(com.orientechnologies.common.exception.OException) OIOException(com.orientechnologies.common.io.OIOException) IOException(java.io.IOException) OChannelBinaryAsynchClient(com.orientechnologies.orient.client.binary.OChannelBinaryAsynchClient) OIOException(com.orientechnologies.common.io.OIOException) OException(com.orientechnologies.common.exception.OException) NamingException(javax.naming.NamingException) OTokenException(com.orientechnologies.orient.core.metadata.security.OTokenException) ODistributedRedirectException(com.orientechnologies.orient.enterprise.channel.binary.ODistributedRedirectException) OInterruptedException(com.orientechnologies.common.concur.lock.OInterruptedException) OTokenSecurityException(com.orientechnologies.orient.enterprise.channel.binary.OTokenSecurityException) OIOException(com.orientechnologies.common.io.OIOException) IOException(java.io.IOException) OOfflineNodeException(com.orientechnologies.common.concur.OOfflineNodeException) OModificationOperationProhibitedException(com.orientechnologies.common.concur.lock.OModificationOperationProhibitedException)

Example 2 with OOfflineNodeException

use of com.orientechnologies.common.concur.OOfflineNodeException in project orientdb by orientechnologies.

the class ODistributedStorage method updateRecord.

@Override
public OStorageOperationResult<Integer> updateRecord(final ORecordId iRecordId, final boolean updateContent, final byte[] iContent, final int iVersion, final byte iRecordType, final int iMode, final ORecordCallback<Integer> iCallback) {
    resetLastValidBackup();
    if (OScenarioThreadLocal.INSTANCE.isRunModeDistributed()) {
        // ALREADY DISTRIBUTED
        return wrapped.updateRecord(iRecordId, updateContent, iContent, iVersion, iRecordType, iMode, iCallback);
    }
    final ODistributedConfiguration dbCfg = distributedConfiguration;
    final String clusterName = getClusterNameByRID(iRecordId);
    final String localNodeName = dManager.getLocalNodeName();
    checkWriteQuorum(dbCfg, clusterName, localNodeName);
    try {
        checkNodeIsMaster(localNodeName, dbCfg, "Update record " + iRecordId);
        final List<String> nodes = dbCfg.getServers(clusterName, null);
        if (nodes.isEmpty())
            // NO REPLICATION: EXECUTE IT LOCALLY
            return wrapped.updateRecord(iRecordId, updateContent, iContent, iVersion, iRecordType, iMode, iCallback);
        final Set<String> clusterNames = Collections.singleton(clusterName);
        Boolean executionModeSynch = dbCfg.isExecutionModeSynchronous(clusterName);
        if (executionModeSynch == null)
            executionModeSynch = iMode == 0;
        final boolean syncMode = executionModeSynch;
        return (OStorageOperationResult<Integer>) executeRecordOperationInLock(syncMode, iRecordId, new OCallable<Object, OCallable<Void, ODistributedRequestId>>() {

            @Override
            public Object call(OCallable<Void, ODistributedRequestId> unlockCallback) {
                final OUpdateRecordTask task = (OUpdateRecordTask) dManager.getTaskFactoryManager().getFactoryByServerNames(nodes).createTask(OUpdateRecordTask.FACTORYID);
                task.init(iRecordId, iContent, iVersion, iRecordType);
                final OStorageOperationResult<Integer> localResult;
                final boolean executedLocally = nodes.contains(localNodeName);
                if (executedLocally) {
                    // EXECUTE ON LOCAL NODE FIRST
                    try {
                        // LOAD CURRENT RECORD
                        task.checkRecordExists();
                        localResult = (OStorageOperationResult<Integer>) OScenarioThreadLocal.executeAsDistributed(new Callable() {

                            @Override
                            public Object call() throws Exception {
                                task.setLastLSN(wrapped.getLSN());
                                return wrapped.updateRecord(iRecordId, updateContent, iContent, iVersion, iRecordType, iMode, iCallback);
                            }
                        });
                    } catch (RuntimeException e) {
                        throw e;
                    } catch (Exception e) {
                        throw OException.wrapException(new ODistributedException("Cannot delete record " + iRecordId), e);
                    }
                    nodes.remove(localNodeName);
                } else
                    localResult = null;
                if (nodes.isEmpty()) {
                    unlockCallback.call(null);
                    if (!executedLocally)
                        throw new ODistributedException("Cannot execute distributed update on record " + iRecordId + " because no nodes are available");
                } else {
                    final Integer localResultPayload = localResult != null ? localResult.getResult() : null;
                    if (syncMode || localResult == null) {
                        // REPLICATE IT
                        try {
                            final ODistributedResponse dResponse = dManager.sendRequest(getName(), clusterNames, nodes, task, dManager.getNextMessageIdCounter(), EXECUTION_MODE.RESPONSE, localResultPayload, unlockCallback, null);
                            final Object payload = dResponse.getPayload();
                            if (payload instanceof Exception) {
                                if (payload instanceof ORecordNotFoundException) {
                                    // REPAIR THE RECORD IMMEDIATELY
                                    localDistributedDatabase.getDatabaseRepairer().enqueueRepairRecord((ORecordId) ((ORecordNotFoundException) payload).getRid());
                                }
                                executeUndoOnLocalServer(dResponse.getRequestId(), task);
                                if (payload instanceof ONeedRetryException)
                                    throw (ONeedRetryException) payload;
                                throw OException.wrapException(new ODistributedException("Error on execution distributed update record"), (Exception) payload);
                            }
                            // UPDATE LOCALLY
                            return new OStorageOperationResult<Integer>((Integer) payload);
                        } catch (RuntimeException e) {
                            executeUndoOnLocalServer(null, task);
                            throw e;
                        } catch (Exception e) {
                            executeUndoOnLocalServer(null, task);
                            throw ODatabaseException.wrapException(new ODistributedException("Cannot execute distributed update record"), e);
                        }
                    }
                    // ASYNCHRONOUS CALL: EXECUTE LOCALLY AND THEN DISTRIBUTE
                    asynchronousExecution(new OAsynchDistributedOperation(getName(), Collections.singleton(clusterName), nodes, task, dManager.getNextMessageIdCounter(), localResultPayload, unlockCallback, null));
                }
                return localResult;
            }
        });
    } catch (ONeedRetryException e) {
        localDistributedDatabase.getDatabaseRepairer().enqueueRepairRecord(iRecordId);
        // PASS THROUGH
        throw e;
    } catch (HazelcastInstanceNotActiveException e) {
        throw new OOfflineNodeException("Hazelcast instance is not available");
    } catch (HazelcastException e) {
        throw new OOfflineNodeException("Hazelcast instance is not available");
    } catch (Exception e) {
        localDistributedDatabase.getDatabaseRepairer().enqueueRepairRecord(iRecordId);
        handleDistributedException("Cannot route UPDATE_RECORD operation for %s to the distributed node", e, iRecordId);
        // UNREACHABLE
        return null;
    }
}
Also used : OOfflineNodeException(com.orientechnologies.common.concur.OOfflineNodeException) OCallable(com.orientechnologies.common.util.OCallable) Callable(java.util.concurrent.Callable) OCallable(com.orientechnologies.common.util.OCallable) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HazelcastException(com.hazelcast.core.HazelcastException) HazelcastInstanceNotActiveException(com.hazelcast.core.HazelcastInstanceNotActiveException) OException(com.orientechnologies.common.exception.OException) ONeedRetryException(com.orientechnologies.common.concur.ONeedRetryException) HazelcastException(com.hazelcast.core.HazelcastException) ODistributedRedirectException(com.orientechnologies.orient.enterprise.channel.binary.ODistributedRedirectException) OIOException(com.orientechnologies.common.io.OIOException) OOfflineNodeException(com.orientechnologies.common.concur.OOfflineNodeException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) HazelcastInstanceNotActiveException(com.hazelcast.core.HazelcastInstanceNotActiveException) ONeedRetryException(com.orientechnologies.common.concur.ONeedRetryException)

Example 3 with OOfflineNodeException

use of com.orientechnologies.common.concur.OOfflineNodeException in project orientdb by orientechnologies.

the class ODistributedStorage method readRecord.

public OStorageOperationResult<ORawBuffer> readRecord(final ORecordId iRecordId, final String iFetchPlan, final boolean iIgnoreCache, final boolean prefetchRecords, final ORecordCallback<ORawBuffer> iCallback) {
    final ORawBuffer memCopy = localDistributedDatabase.getRecordIfLocked(iRecordId);
    if (memCopy != null)
        return new OStorageOperationResult<ORawBuffer>(memCopy);
    try {
        final String clusterName = getClusterNameByRID(iRecordId);
        final ODistributedConfiguration dbCfg = distributedConfiguration;
        final List<String> nodes = dbCfg.getServers(clusterName, null);
        final int availableNodes = nodes.size();
        // CHECK IF LOCAL NODE OWNS THE DATA AND READ-QUORUM = 1: GET IT LOCALLY BECAUSE IT'S FASTER
        final String localNodeName = dManager.getLocalNodeName();
        if (nodes.isEmpty() || nodes.contains(dManager.getLocalNodeName()) && dbCfg.getReadQuorum(clusterName, availableNodes, localNodeName) <= 1) {
            // DON'T REPLICATE
            return (OStorageOperationResult<ORawBuffer>) OScenarioThreadLocal.executeAsDistributed(new Callable() {

                @Override
                public Object call() throws Exception {
                    return wrapped.readRecord(iRecordId, iFetchPlan, iIgnoreCache, prefetchRecords, iCallback);
                }
            });
        }
        final OReadRecordTask task = ((OReadRecordTask) dManager.getTaskFactoryManager().getFactoryByServerNames(nodes).createTask(OReadRecordTask.FACTORYID)).init(iRecordId);
        // DISTRIBUTE IT
        final ODistributedResponse response = dManager.sendRequest(getName(), Collections.singleton(clusterName), nodes, task, dManager.getNextMessageIdCounter(), EXECUTION_MODE.RESPONSE, null, null, null);
        final Object dResult = response != null ? response.getPayload() : null;
        if (dResult instanceof ONeedRetryException)
            throw (ONeedRetryException) dResult;
        else if (dResult instanceof Exception)
            throw OException.wrapException(new ODistributedException("Error on execution distributed read record"), (Exception) dResult);
        return new OStorageOperationResult<ORawBuffer>((ORawBuffer) dResult);
    } catch (ONeedRetryException e) {
        // PASS THROUGH
        throw e;
    } catch (HazelcastInstanceNotActiveException e) {
        throw new OOfflineNodeException("Hazelcast instance is not available");
    } catch (HazelcastException e) {
        throw new OOfflineNodeException("Hazelcast instance is not available");
    } catch (Exception e) {
        handleDistributedException("Cannot route read record operation for %s to the distributed node", e, iRecordId);
        // UNREACHABLE
        return null;
    }
}
Also used : HazelcastException(com.hazelcast.core.HazelcastException) OOfflineNodeException(com.orientechnologies.common.concur.OOfflineNodeException) OCallable(com.orientechnologies.common.util.OCallable) Callable(java.util.concurrent.Callable) HazelcastInstanceNotActiveException(com.hazelcast.core.HazelcastInstanceNotActiveException) OException(com.orientechnologies.common.exception.OException) ONeedRetryException(com.orientechnologies.common.concur.ONeedRetryException) HazelcastException(com.hazelcast.core.HazelcastException) ODistributedRedirectException(com.orientechnologies.orient.enterprise.channel.binary.ODistributedRedirectException) OIOException(com.orientechnologies.common.io.OIOException) OOfflineNodeException(com.orientechnologies.common.concur.OOfflineNodeException) HazelcastInstanceNotActiveException(com.hazelcast.core.HazelcastInstanceNotActiveException) ONeedRetryException(com.orientechnologies.common.concur.ONeedRetryException)

Example 4 with OOfflineNodeException

use of com.orientechnologies.common.concur.OOfflineNodeException in project orientdb by orientechnologies.

the class OStorageRemote method baseNetworkOperation.

public <T> T baseNetworkOperation(final OStorageRemoteOperation<T> operation, final String errorMessage, int retry) {
    OStorageRemoteSession session = getCurrentSession();
    if (session.commandExecuting)
        throw new ODatabaseException("Cannot execute the request because an asynchronous operation is in progress. Please use a different connection");
    String serverUrl = null;
    do {
        OChannelBinaryAsynchClient network = null;
        if (serverUrl == null)
            serverUrl = getNextAvailableServerURL(false, session);
        do {
            try {
                network = getNetwork(serverUrl);
            } catch (OException e) {
                serverUrl = useNewServerURL(serverUrl);
                if (serverUrl == null)
                    throw e;
            }
        } while (network == null);
        try {
            // In case i do not have a token or i'm switching between server i've to execute a open operation.
            OStorageRemoteNodeSession nodeSession = session.getServerSession(network.getServerURL());
            if (nodeSession == null || !nodeSession.isValid()) {
                openRemoteDatabase(network);
                if (!network.tryLock()) {
                    connectionManager.release(network);
                    continue;
                }
            }
            return operation.execute(network, session);
        } catch (ODistributedRedirectException e) {
            connectionManager.release(network);
            OLogManager.instance().debug(this, "Redirecting the request from server '%s' to the server '%s' because %s", e.getFromServer(), e.toString(), e.getMessage());
            // RECONNECT TO THE SERVER SUGGESTED IN THE EXCEPTION
            serverUrl = e.getToServerAddress();
        } catch (OModificationOperationProhibitedException mope) {
            connectionManager.release(network);
            handleDBFreeze();
            serverUrl = null;
        } catch (OTokenException e) {
            connectionManager.release(network);
            session.removeServerSession(network.getServerURL());
            if (--retry <= 0)
                throw OException.wrapException(new OStorageException(errorMessage), e);
            serverUrl = null;
        } catch (OTokenSecurityException e) {
            connectionManager.release(network);
            session.removeServerSession(network.getServerURL());
            if (--retry <= 0)
                throw OException.wrapException(new OStorageException(errorMessage), e);
            serverUrl = null;
        } catch (OOfflineNodeException e) {
            connectionManager.release(network);
            // Remove the current url because the node is offline
            synchronized (serverURLs) {
                serverURLs.remove(serverUrl);
            }
            for (OStorageRemoteSession activeSession : sessions) {
                // Not thread Safe ...
                activeSession.removeServerSession(serverUrl);
            }
            serverUrl = null;
        } catch (IOException e) {
            connectionManager.release(network);
            retry = handleIOException(retry, network, e);
            serverUrl = null;
        } catch (OIOException e) {
            connectionManager.release(network);
            retry = handleIOException(retry, network, e);
            serverUrl = null;
        } catch (OException e) {
            connectionManager.release(network);
            throw e;
        } catch (Exception e) {
            connectionManager.release(network);
            throw OException.wrapException(new OStorageException(errorMessage), e);
        }
    } while (true);
}
Also used : OOfflineNodeException(com.orientechnologies.common.concur.OOfflineNodeException) OException(com.orientechnologies.common.exception.OException) OIOException(com.orientechnologies.common.io.OIOException) IOException(java.io.IOException) OIOException(com.orientechnologies.common.io.OIOException) IOException(java.io.IOException) OChannelBinaryAsynchClient(com.orientechnologies.orient.client.binary.OChannelBinaryAsynchClient) OIOException(com.orientechnologies.common.io.OIOException) OException(com.orientechnologies.common.exception.OException) NamingException(javax.naming.NamingException) OTokenException(com.orientechnologies.orient.core.metadata.security.OTokenException) ODistributedRedirectException(com.orientechnologies.orient.enterprise.channel.binary.ODistributedRedirectException) OInterruptedException(com.orientechnologies.common.concur.lock.OInterruptedException) OTokenSecurityException(com.orientechnologies.orient.enterprise.channel.binary.OTokenSecurityException) OIOException(com.orientechnologies.common.io.OIOException) IOException(java.io.IOException) OOfflineNodeException(com.orientechnologies.common.concur.OOfflineNodeException) OModificationOperationProhibitedException(com.orientechnologies.common.concur.lock.OModificationOperationProhibitedException) OTokenSecurityException(com.orientechnologies.orient.enterprise.channel.binary.OTokenSecurityException) OTokenException(com.orientechnologies.orient.core.metadata.security.OTokenException) ODistributedRedirectException(com.orientechnologies.orient.enterprise.channel.binary.ODistributedRedirectException) OModificationOperationProhibitedException(com.orientechnologies.common.concur.lock.OModificationOperationProhibitedException)

Example 5 with OOfflineNodeException

use of com.orientechnologies.common.concur.OOfflineNodeException in project orientdb by orientechnologies.

the class ODistributedAbstractPlugin method onOpen.

/**
 * Auto register myself as hook.
 */
@Override
public void onOpen(final ODatabaseInternal iDatabase) {
    if (!isRelatedToLocalServer(iDatabase))
        return;
    if (status != NODE_STATUS.ONLINE && status != NODE_STATUS.STARTING)
        return;
    final ODatabaseDocumentInternal currDb = ODatabaseRecordThreadLocal.INSTANCE.getIfDefined();
    try {
        final String dbName = iDatabase.getName();
        final ODistributedConfiguration cfg = getDatabaseConfiguration(dbName);
        if (cfg == null)
            return;
        ODistributedDatabaseImpl distribDatabase = getMessageService().getDatabase(dbName);
        if (distribDatabase == null) {
            // CHECK TO PUBLISH IT TO THE CLUSTER
            distribDatabase = messageService.registerDatabase(dbName, cfg);
            distribDatabase.checkNodeInConfiguration(cfg, getLocalNodeName());
            distribDatabase.resume();
            distribDatabase.setOnline();
        }
        if (!(iDatabase.getStorage() instanceof ODistributedStorage) || ((ODistributedStorage) iDatabase.getStorage()).getDistributedManager().isOffline()) {
            final ODistributedStorage storage = getStorage(dbName);
            // INIT IT
            storage.wrap((OAbstractPaginatedStorage) iDatabase.getStorage().getUnderlying());
            iDatabase.replaceStorage(storage);
            if (isNodeOnline(nodeName, dbName))
                installDbClustersLocalStrategy(iDatabase);
        }
    } catch (HazelcastException e) {
        throw new OOfflineNodeException("Hazelcast instance is not available");
    } catch (HazelcastInstanceNotActiveException e) {
        throw new OOfflineNodeException("Hazelcast instance is not available");
    } finally {
        // RESTORE ORIGINAL DATABASE INSTANCE IN TL
        ODatabaseRecordThreadLocal.INSTANCE.set(currDb);
    }
}
Also used : HazelcastInstanceNotActiveException(com.hazelcast.core.HazelcastInstanceNotActiveException) HazelcastException(com.hazelcast.core.HazelcastException) OOfflineNodeException(com.orientechnologies.common.concur.OOfflineNodeException)

Aggregations

OOfflineNodeException (com.orientechnologies.common.concur.OOfflineNodeException)10 OException (com.orientechnologies.common.exception.OException)9 OIOException (com.orientechnologies.common.io.OIOException)9 ODistributedRedirectException (com.orientechnologies.orient.enterprise.channel.binary.ODistributedRedirectException)9 HazelcastException (com.hazelcast.core.HazelcastException)8 HazelcastInstanceNotActiveException (com.hazelcast.core.HazelcastInstanceNotActiveException)8 ONeedRetryException (com.orientechnologies.common.concur.ONeedRetryException)7 OCallable (com.orientechnologies.common.util.OCallable)6 Callable (java.util.concurrent.Callable)5 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)3 OInterruptedException (com.orientechnologies.common.concur.lock.OInterruptedException)2 OModificationOperationProhibitedException (com.orientechnologies.common.concur.lock.OModificationOperationProhibitedException)2 OChannelBinaryAsynchClient (com.orientechnologies.orient.client.binary.OChannelBinaryAsynchClient)2 ORecordId (com.orientechnologies.orient.core.id.ORecordId)2 OTokenException (com.orientechnologies.orient.core.metadata.security.OTokenException)2 OTokenSecurityException (com.orientechnologies.orient.enterprise.channel.binary.OTokenSecurityException)2 IOException (java.io.IOException)2 NamingException (javax.naming.NamingException)2 OCommandScript (com.orientechnologies.orient.core.command.script.OCommandScript)1 OPlaceholder (com.orientechnologies.orient.core.db.record.OPlaceholder)1