Ejemplo n.º 1
0
        public object OnRequest(IRequest request)
        {
            IDBOperation  dbOperation   = null;
            IDBResponse   response      = null;
            RequestParser requestParser = null;

            try
            {
                requestParser = request as RequestParser;
                try
                {
                    dbOperation = requestParser.ParseRequest();
                }
                catch (Exception ex)
                {
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Error("Error: ClientMgr.OnRequest() On Parse Request", ex.ToString());
                    }
                    throw;
                }

                if (dbOperation == null)
                {
                    throw new NullReferenceException("Database Operation");
                }

                if (_shardName != null && _statsCollector == null)
                {
                    _statsCollector = StatsManager.Instance.GetStatsCollector(new StatsIdentity(_shardName, dbOperation.Database));
                }

                //Dispose Reader check is a temporary fix for Single Get Operation.
                if (dbOperation.OperationType != DatabaseOperationType.DisposeReader && _statsCollector != null)
                {
                    _statsCollector.IncrementStatsValue(StatisticsType.RequestsPerSec);
                }

                //TODO: when SessionId will be embedded into command from router, this code needs to be removed
                //if (dbOperation.SessionId == null)
                //    dbOperation.SessionId = new RouterSessionId();
                //dbOperation.SessionId = SessionId;

                //if (_dbEngine == null)
                //    throw new NullReferenceException("DBEngine (Client Manager)");

                //LoggerManager.Instance.SetThreadContext(new LoggerContext { ShardName = ((DataBaseEngine)DbEngine).NodeContext.LocalShardName, DatabaseName = dbOperation.Database });
                switch (dbOperation.OperationType)
                {
                case DatabaseOperationType.Init:
                    response = _dbEngine.InitializeDatabase((InitDatabaseOperation)dbOperation);
                    if (response.IsSuccessfull)
                    {
                        _database = dbOperation.Database;
                    }
                    break;

                case DatabaseOperationType.Insert:

                    response = _dbEngine.InsertDocuments((InsertDocumentsOperation)dbOperation);
                    break;

                case DatabaseOperationType.Delete:

                    response = _dbEngine.DeleteDocuments((DeleteDocumentsOperation)dbOperation);
                    break;

                case DatabaseOperationType.Get:

                    response = _dbEngine.GetDocuments((GetDocumentsOperation)dbOperation);
                    if (response != null && response.IsSuccessfull)
                    {
                        var getResponse = (GetDocumentsResponse)response;
                        if (!getResponse.DataChunk.IsLastChunk)
                        {
                            var readerInfo = new ReaderInfo
                            {
                                DatabaseName   = dbOperation.Database,
                                CollectionName = dbOperation.Collection,
                                ReaderId       = getResponse.DataChunk.ReaderUID
                            };
                            lock (_readersList)
                            {
                                _readersList.Add(readerInfo);
                            }
                        }
                    }
                    break;

                case DatabaseOperationType.Update:

                    response = _dbEngine.UpdateDocuments((UpdateOperation)dbOperation);
                    break;

                case DatabaseOperationType.Replace:
                    response = _dbEngine.ReplaceDocuments((IDocumentsWriteOperation)dbOperation);
                    break;

                case DatabaseOperationType.ReadQuery:

                    response = _dbEngine.ExecuteReader((ReadQueryOperation)dbOperation);
                    if (response != null && response.IsSuccessfull)
                    {
                        var readQueryResponse = (ReadQueryResponse)response;
                        if (!readQueryResponse.DataChunk.IsLastChunk)
                        {
                            var readerInfo = new ReaderInfo
                            {
                                DatabaseName   = dbOperation.Database,
                                CollectionName = dbOperation.Collection,
                                ReaderId       = readQueryResponse.DataChunk.ReaderUID
                            };
                            lock (_readersList)
                            {
                                _readersList.Add(readerInfo);
                            }
                        }
                    }
                    break;

                case DatabaseOperationType.WriteQuery:

                    response = _dbEngine.ExecuteNonQuery((WriteQueryOperation)dbOperation);
                    break;

                case DatabaseOperationType.CreateSession:
                    break;

                case DatabaseOperationType.GetChunk:

                    response = _dbEngine.GetDataChunk((GetChunkOperation)dbOperation);
                    break;

                case DatabaseOperationType.DisposeReader:

                    var disposeReaderOperation = (DisposeReaderOperation)dbOperation;
                    response = _dbEngine.DiposeReader(disposeReaderOperation);
                    if (response != null && response.IsSuccessfull)
                    {
                        lock (_readersList)
                        {
                            _readersList.RemoveAll(
                                x =>
                                x.CollectionName == disposeReaderOperation.Collection &&
                                x.DatabaseName == disposeReaderOperation.Database &&
                                x.ReaderId == disposeReaderOperation.ReaderUID);
                        }
                    }
                    break;

                case DatabaseOperationType.Authenticate:

                    var authenticationOperation = (AuthenticationOperation)dbOperation;
                    _noSConnectionString = new ConnectionStringBuilder(authenticationOperation.ConnectionString);
                    _dbEngine            = _databaseEngineFactory.GetDatabaseEngine(_noSConnectionString);

                    authenticationOperation.Address = ServerChannel.PeerAddress;
                    response = _dbEngine.Authenticate(authenticationOperation);
                    AuthenticationResponse authResponse = response as AuthenticationResponse;
                    if (
                        !(authResponse.ServerToken.Status == Common.Security.SSPI.SecurityStatus.SecurityDisabled ||
                          authResponse.ServerToken.Status == Common.Security.SSPI.SecurityStatus.ContinueNeeded ||
                          authResponse.ServerToken.Status == Common.Security.SSPI.SecurityStatus.OK))
                    {
                        this.ChannelDisconnected(_serverChannel, "unauthenticated");
                    }
                    else
                    {
                        CsSessionId      = dbOperation.SessionId;
                        _clientProcessID = authenticationOperation.ClientProcessID;
                    }
                    break;

                default:
                    throw new Exception("Invalid Operation");
                }
            }
            catch (SerializationException se)
            {
                try
                {
                    if (requestParser == null)
                    {
                        requestParser = request.Message as RequestParser;
                    }

                    response = OperationMapper.GetResponse(requestParser.OperationType);
                    response.IsSuccessfull = false;
                    response.RequestId     = requestParser.RequestId;
                    response.ErrorCode     = se.ErrorCode != 0 ? se.ErrorCode : ErrorCodes.Cluster.UNKNOWN_ISSUE;
                    response.ErrorParams   = se.Parameters;
                }
                catch (Exception)
                {
                    //Create response if exception occurs.
                    if (dbOperation != null)
                    {
                        response = dbOperation.CreateResponse();
                    }
                    response.ErrorCode = ErrorCodes.Cluster.UNKNOWN_ISSUE;
                }
                if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled)
                {
                    LoggerManager.Instance.ShardLogger.Error("Error: ClientMgr.OnRequest()", se.ToString());
                }
            }
            catch (DatabaseException de)
            {
                if (dbOperation != null)
                {
                    response = dbOperation.CreateResponse();
                }
                if (response != null)
                {
                    response.IsSuccessfull = false;
                    response.ErrorCode     = de.ErrorCode != 0 ? de.ErrorCode : ErrorCodes.Cluster.UNKNOWN_ISSUE;
                    response.ErrorParams   = de.Parameters;
                }
            }
            catch (ManagementException me)
            {
                if (dbOperation != null)
                {
                    response = dbOperation.CreateResponse();
                }
                if (response != null)
                {
                    response.IsSuccessfull = false;
                    if (me.IsErrorCodeSpecified)
                    {
                        response.ErrorCode   = me.ErrorCode;
                        response.ErrorParams = me.Parameters;
                    }
                }
            }
            catch (Exception e)
            {
                if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled)
                {
                    LoggerManager.Instance.ShardLogger.Error("Error: ClientMgr.OnRequest()",
                                                             e.Message + " StackTrace:" + e.StackTrace);
                }

                if (dbOperation != null)
                {
                    response = dbOperation.CreateResponse();
                }
                if (response != null)
                {
                    response.IsSuccessfull = false;
                    response.ErrorCode     = ErrorCodes.Cluster.UNKNOWN_ISSUE;
                }
            }

            finally
            {
                try
                {
                    if (request.Channel.Connected)
                    {
                        request.Channel.SendMessage(response);
                    }
                }
                catch (ChannelException e)
                {
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Error("Error: ClientMgr.OnRequest()", e.ToString());
                    }
                }
                catch (Exception ex)
                {
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Error("Error: Exception on ClientMgr.OnRequest()", ex.ToString());
                    }
                }
            }

            return(null);
        }