コード例 #1
0
ファイル: LeaderStateBehavior.cs プロジェクト: ppekrol/Rachis
        private void SendEntriesToPeer(NodeConnectionInfo peer)
        {
            LogEntry prevLogEntry;

            LogEntry[] entries;

            var nextIndex = _nextIndexes.GetOrAdd(peer.Name, -1);             //new peer's index starts at, we use -1 as a sentital value

            if (Engine.StateMachine.SupportSnapshots && nextIndex != -1)
            {
                var snapshotIndex = Engine.PersistentState.GetLastSnapshotIndex();

                if (snapshotIndex != null && nextIndex < snapshotIndex)
                {
                    if (_snapshotsPendingInstallation.ContainsKey(peer.Name))
                    {
                        return;
                    }

                    using (var snapshotWriter = Engine.StateMachine.GetSnapshotWriter())
                    {
                        Engine.Transport.Send(peer, new CanInstallSnapshotRequest
                        {
                            From = Engine.Name,
                            ClusterTopologyId = Engine.CurrentTopology.TopologyId,
                            Index             = snapshotWriter.Index,
                            Term = snapshotWriter.Term,
                        });
                    }
                    return;
                }
            }

            if (nextIndex == -1)
            {
                nextIndex = 0;
            }

            try
            {
                entries = Engine.PersistentState.LogEntriesAfter(nextIndex)
                          .Take(Engine.Options.MaxEntriesPerRequest)
                          .ToArray();

                prevLogEntry = entries.Length == 0
                                        ? Engine.PersistentState.LastLogEntry()
                                        : Engine.PersistentState.GetLogEntry(entries[0].Index - 1);
            }
            catch (Exception e)
            {
                _log.Error("Error while fetching entries from persistent state.", e);
                throw;
            }

            if (_log.IsDebugEnabled)
            {
                _log.Debug("Sending {0:#,#;;0} entries to {1} (PrevLogEntry: Term = {2} Index = {3}).", entries.Length, peer, prevLogEntry.Term, prevLogEntry.Index);
            }

            var aer = new AppendEntriesRequest
            {
                Entries           = entries,
                LeaderCommit      = Engine.CommitIndex,
                PrevLogIndex      = prevLogEntry.Index,
                PrevLogTerm       = prevLogEntry.Term,
                Term              = Engine.PersistentState.CurrentTerm,
                From              = Engine.Name,
                ClusterTopologyId = Engine.CurrentTopology.TopologyId,
            };

            Engine.Transport.Send(peer, aer);

            Engine.OnEntriesAppended(entries);
        }
コード例 #2
0
 private bool KnownNode(NodeConnectionInfo nodeConnectionInfo)
 {
     return(_senderInfo.Equals(nodeConnectionInfo) ||
            _activeView.ContainsKey(nodeConnectionInfo) ||
            _passiveView.Contains(nodeConnectionInfo));
 }
コード例 #3
0
 protected bool Equals(NodeConnectionInfo other)
 {
     return(string.Equals(Host, other.Host) && Port == other.Port);
 }
コード例 #4
0
        private void AssertUnauthorizedCredentialSupportWindowsAuth(HttpResponseMessage response, NodeConnectionInfo nodeConnectionInfo)
        {
            if (nodeConnectionInfo.Username == null)
            {
                return;
            }

            var authHeaders = response.Headers.WwwAuthenticate.FirstOrDefault();

            if (authHeaders == null || (authHeaders.ToString().Contains("NTLM") == false && authHeaders.ToString().Contains("Negotiate") == false))
            {
                // we are trying to do windows auth, but we didn't get the windows auth headers
                throw new SecurityException(
                          "Attempted to connect to a RavenDB Server that requires authentication using Windows credentials," + Environment.NewLine
                          + " but either wrong credentials where entered or the specified server does not support Windows authentication." +
                          Environment.NewLine +
                          "If you are running inside IIS, make sure to enable Windows authentication.");
            }
        }
コード例 #5
0
ファイル: ClusterController.cs プロジェクト: rstonkus/ravendb
 private Task <ConnectivityStatus> FetchNodeStatus(NodeConnectionInfo nci)
 {
     return(ClusterManager.Client.CheckConnectivity(nci));
 }
コード例 #6
0
 internal SecuredAuthenticator GetAuthenticator(NodeConnectionInfo info)
 {
     return(_securedAuthenticatorCache.GetOrAdd(info.GetAbsoluteUri(), _ => new SecuredAuthenticator(autoRefreshToken: false)));
 }
コード例 #7
0
        internal Task <Action <HttpClient> > HandleUnauthorizedResponseAsync(HttpResponseMessage unauthorizedResponse, NodeConnectionInfo nodeConnectionInfo)
        {
            var oauthSource = unauthorizedResponse.Headers.GetFirstValue("OAuth-Source");

            if (nodeConnectionInfo.ApiKey == null)
            {
                AssertUnauthorizedCredentialSupportWindowsAuth(unauthorizedResponse, nodeConnectionInfo);
                return(null);
            }

            if (string.IsNullOrEmpty(oauthSource))
            {
                oauthSource = nodeConnectionInfo.GetAbsoluteUri() + "/OAuth/API-Key";
            }

            return(GetAuthenticator(nodeConnectionInfo).DoOAuthRequestAsync(nodeConnectionInfo.GetAbsoluteUri(), oauthSource, nodeConnectionInfo.ApiKey));
        }
コード例 #8
0
 private Task SendDatabaseUpdateInternalAsync(NodeConnectionInfo leaderNode, string databaseName, DatabaseDocument document)
 {
     return(PutAsync(leaderNode, "admin/cluster/commands/database/" + Uri.EscapeDataString(databaseName), document));
 }
コード例 #9
0
        public async Task SendLeaveClusterInternalAsync(NodeConnectionInfo leaderNode, NodeConnectionInfo leavingNode)
        {
            var url = leaderNode.GetAbsoluteUri() + "admin/cluster/leave?name=" + leavingNode.Name;

            using (var request = CreateRequest(leaderNode, url, HttpMethods.Get))
            {
                var response = await request.ExecuteAsync().ConfigureAwait(false);

                if (response.IsSuccessStatusCode)
                {
                    return;
                }

                throw await CreateErrorResponseExceptionAsync(response).ConfigureAwait(false);
            }
        }
コード例 #10
0
        public async Task <CanJoinResult> SendJoinServerInternalAsync(NodeConnectionInfo leaderNode, NodeConnectionInfo newNode)
        {
            var url = leaderNode.GetAbsoluteUri() + "admin/cluster/join";

            using (var request = CreateRequest(leaderNode, url, HttpMethods.Post))
            {
                var response = await request.WriteAsync(() => new JsonContent(RavenJToken.FromObject(newNode))).ConfigureAwait(false);

                if (response.IsSuccessStatusCode)
                {
                    return(CanJoinResult.CanJoin);
                }

                switch (response.StatusCode)
                {
                case HttpStatusCode.Conflict:
                    return(CanJoinResult.IsNonEmpty);

                case HttpStatusCode.NotModified:
                    return(CanJoinResult.AlreadyJoined);

                case HttpStatusCode.NotAcceptable:
                    return(CanJoinResult.InAnotherCluster);

                default:
                    throw await CreateErrorResponseExceptionAsync(response).ConfigureAwait(false);
                }
            }
        }
コード例 #11
0
 private Task SendClusterConfigurationInternalAsync(NodeConnectionInfo leaderNode, ClusterConfiguration configuration)
 {
     return(PutAsync(leaderNode, "admin/cluster/commands/configuration", configuration));
 }
コード例 #12
0
        private void AssertForbiddenCredentialSupportWindowsAuth(HttpResponseMessage response, NodeConnectionInfo nodeConnection)
        {
            if (nodeConnection.ToOperationCredentials().Credentials == null)
            {
                return;
            }

            var requiredAuth = response.Headers.GetFirstValue("Raven-Required-Auth");

            if (requiredAuth == "Windows")
            {
                // we are trying to do windows auth, but we didn't get the windows auth headers
                throw new SecurityException(
                          "Attempted to connect to a RavenDB Server that requires authentication using Windows credentials, but the specified server does not support Windows authentication." +
                          Environment.NewLine +
                          "If you are running inside IIS, make sure to enable Windows authentication.");
            }
        }
コード例 #13
0
        internal Task <Action <HttpClient> > HandleForbiddenResponseAsync(HttpResponseMessage forbiddenResponse, NodeConnectionInfo nodeConnection)
        {
            if (nodeConnection.ApiKey == null)
            {
                AssertForbiddenCredentialSupportWindowsAuth(forbiddenResponse, nodeConnection);
                return(null);
            }

            return(null);
        }
コード例 #14
0
        public bool Execute(CommandProcessorContext context, string[] args)
        {
            if (args.Length != 0 && false == (args.Length == 7 || args.Length == 8))
            {
                return(false);
            }

            var                maxConcurrentRequests = 20;
            var                connections           = 10;
            var                streams                = 100;
            var                eventsPerStream        = 400;
            var                streamDeleteStep       = 7;
            var                scenarioName           = "";
            var                executionPeriodMinutes = 2;
            string             dbParentPath           = null;
            NodeConnectionInfo customNode             = null;

            {
                if (args.Length == 9)
                {
                    throw new ArgumentException(
                              "Not compatible arguments, only one of <dbPath> or <custom node> can be specified.");
                }

                if (args.Length == 8)
                {
                    IPAddress ip;
                    int       tcpPort;
                    int       httpPort;

                    var atoms = args[7].Split(':');
                    if (atoms.Length == 3 &&
                        IPAddress.TryParse(atoms[0], out ip) &&
                        int.TryParse(atoms[1], out tcpPort) &&
                        int.TryParse(atoms[2], out httpPort))
                    {
                        customNode = new NodeConnectionInfo(ip, tcpPort, httpPort);

                        args = CutLastArgument(args);
                    }
                }

                if (args.Length == 7 || args.Length == 8)
                {
                    try {
                        maxConcurrentRequests = int.Parse(args[0]);
                        connections           = int.Parse(args[1]);
                        streams                = int.Parse(args[2]);
                        eventsPerStream        = int.Parse(args[3]);
                        streamDeleteStep       = int.Parse(args[4]);
                        scenarioName           = args[5];
                        executionPeriodMinutes = int.Parse(args[6]);

                        if (args.Length == 8)
                        {
                            dbParentPath = args[7];
                        }
                        else
                        {
                            var envDbPath = Environment.GetEnvironmentVariable("EVENTSTORE_DATABASEPATH");
                            if (!string.IsNullOrEmpty(envDbPath))
                            {
                                dbParentPath = envDbPath;
                            }
                        }
                    } catch (Exception e) {
                        Log.Error("Invalid arguments ({e})", e.Message);
                        return(false);
                    }
                }
            }

            context.IsAsync();

            Log.Info("\n---" +
                     "\nRunning scenario {scenario} using {connections} connections with {maxConcurrentRequests} max concurrent requests," +
                     "\nfor {streams} streams {eventsPerStream} events each deleting every {streamDeleteStep}th stream. " +
                     "\nExecution period {executionPeriod} minutes. " +
                     "\nDatabase path {dbParentPath};" +
                     "\nCustom Node {customNode};" +
                     "\n---",
                     scenarioName,
                     connections,
                     maxConcurrentRequests,
                     streams,
                     eventsPerStream,
                     streamDeleteStep,
                     executionPeriodMinutes,
                     dbParentPath,
                     customNode);

            var directTcpSender = CreateDirectTcpSender(context);
            var allScenarios    = new IScenario[] {
                new LoopingScenario(directTcpSender,
                                    maxConcurrentRequests,
                                    connections,
                                    streams,
                                    eventsPerStream,
                                    streamDeleteStep,
                                    TimeSpan.FromMinutes(executionPeriodMinutes),
                                    dbParentPath,
                                    customNode),
                new ProjectionsKillScenario(directTcpSender,
                                            maxConcurrentRequests,
                                            connections,
                                            streams,
                                            eventsPerStream,
                                            streamDeleteStep,
                                            dbParentPath,
                                            customNode),
                new ProjForeachForcedCommonNameScenario(directTcpSender,
                                                        maxConcurrentRequests,
                                                        connections,
                                                        streams,
                                                        eventsPerStream,
                                                        streamDeleteStep,
                                                        TimeSpan.FromMinutes(executionPeriodMinutes),
                                                        dbParentPath,
                                                        customNode),
                new ProjForeachForcedCommonNameNoRestartScenario(directTcpSender,
                                                                 maxConcurrentRequests,
                                                                 connections,
                                                                 streams,
                                                                 eventsPerStream,
                                                                 streamDeleteStep,
                                                                 TimeSpan.FromMinutes(executionPeriodMinutes),
                                                                 dbParentPath,
                                                                 customNode),
                new LoopingProjTranWriteScenario(directTcpSender,
                                                 maxConcurrentRequests,
                                                 connections,
                                                 streams,
                                                 eventsPerStream,
                                                 streamDeleteStep,
                                                 TimeSpan.FromMinutes(executionPeriodMinutes),
                                                 dbParentPath,
                                                 customNode),
                new LoopingProjectionKillScenario(directTcpSender,
                                                  maxConcurrentRequests,
                                                  connections,
                                                  streams,
                                                  eventsPerStream,
                                                  streamDeleteStep,
                                                  TimeSpan.FromMinutes(executionPeriodMinutes),
                                                  dbParentPath,
                                                  customNode),
                new MassProjectionsScenario(directTcpSender,
                                            maxConcurrentRequests,
                                            connections,
                                            streams,
                                            eventsPerStream,
                                            streamDeleteStep,
                                            dbParentPath,
                                            customNode),
                new ProjectionWrongTagCheck(directTcpSender,
                                            maxConcurrentRequests,
                                            connections,
                                            streams,
                                            eventsPerStream,
                                            streamDeleteStep,
                                            TimeSpan.FromMinutes(executionPeriodMinutes),
                                            dbParentPath,
                                            customNode),
            };

            Log.Info("Found scenarios {scenariosCount} total :\n{scenarios}.", allScenarios.Length,
                     allScenarios.Aggregate(new StringBuilder(),
                                            (sb, s) => sb.AppendFormat("{0}, ", s.GetType().Name)));
            var scenarios = allScenarios.Where(x => scenarioName == AllScenariosFlag ||
                                               x.GetType().Name.Equals(scenarioName,
                                                                       StringComparison.InvariantCultureIgnoreCase))
                            .ToArray();

            Log.Info("Running test scenarios ({scenarios} total)...", scenarios.Length);

            foreach (var scenario in scenarios)
            {
                using (scenario) {
                    try {
                        Log.Info("Run scenario {type}", scenario.GetType().Name);
                        scenario.Run();
                        scenario.Clean();
                        Log.Info("Scenario run successfully");
                    } catch (Exception e) {
                        context.Fail(e);
                    }
                }
            }

            Log.Info("Finished running test scenarios");

            if (context.ExitCode == 0)
            {
                context.Success();
            }

            return(true);
        }
コード例 #15
0
 internal SecuredAuthenticator GetAuthenticator(NodeConnectionInfo info)
 {
     return(_securedAuthenticatorCache.GetOrAdd(info.Uri.AbsoluteUri, _ => new SecuredAuthenticator()));
 }
コード例 #16
0
ファイル: Program.cs プロジェクト: comitia-curiata/pericles
        public static void Main(string[] args)
        {
            var configFilepath = args[0];
            var password       = args[1];

            // config
            var nodeConfig      = ConfigDeserializer.Deserialize <NodeConfig>(configFilepath);
            var console         = ConsoleFactory.Build(nodeConfig.IsMiningNode);
            var ipAddress       = IpAddressProvider.GetLocalIpAddress();
            var electionEndTime = nodeConfig.IsClassDemo ? DateTime.Now.AddSeconds(120) : nodeConfig.ElectionEndTime;

            // password check
            var voterDb    = new VoterDatabaseFacade(nodeConfig.VoterDbFilepath);
            var foundMiner = voterDb.TryGetVoterEncryptedKeyPair(password, out var encryptedKeyPair);

            if (!foundMiner)
            {
                Console.WriteLine("incorrect password: you may not mine!");
                return;
            }

            // blockchain
            var blockchain = new Blockchain();

            // networking
            var registrarClientFactory     = new RegistrarClientFactory();
            var registrarClient            = registrarClientFactory.Build(ipAddress, RegistrarPort);
            var registrationRequestFactory = new RegistrationRequestFactory();
            var myConnectionInfo           = new NodeConnectionInfo(ipAddress, nodeConfig.Port);
            var knownNodeStore             = new KnownNodeStore();
            var nodeClientFactory          = new NodeClientFactory();
            var handshakeRequestFactory    = new HandshakeRequestFactory(blockchain);
            var nodeClientStore            = new NodeClientStore();
            var nodeServerFactory          = new NodeServerFactory();

            // votes
            var protoVoteFactory = new ProtoVoteFactory();
            var voteForwarder    = new VoteForwarder(nodeClientStore, protoVoteFactory);
            var voteMemoryPool   = new VoteMemoryPool(voteForwarder, console);

            // blocks
            var merkleNodeFactory = new MerkleNodeFactory();
            var merkleTreeFactory = new MerkleTreeFactory(merkleNodeFactory);
            var minerId           = encryptedKeyPair.PublicKey.GetBase64String();
            var blockFactory      = new BlockFactory(merkleTreeFactory, minerId);
            var protoBlockFactory = new ProtoBlockFactory(protoVoteFactory);
            var blockForwarder    = new BlockForwarder(nodeClientStore, protoBlockFactory);
            var voteValidator     = new VoteValidator(blockchain, voterDb, electionEndTime);
            var blockValidator    = new BlockValidator(blockFactory, voteValidator);
            var blockchainAdder   = new BlockchainAdder(blockchain, voteMemoryPool, blockForwarder, console);

            // mining
            var difficultyTarget = TargetFactory.Build(BlockHeader.DefaultBits);
            var miner            = new Miner(
                blockchain,
                voteMemoryPool,
                difficultyTarget,
                blockFactory,
                blockchainAdder,
                console);

            // interaction
            var voteSerializer           = new VoteSerializer();
            var electionAlgorithmFactory = new ElectionAlgorithmFactory(voteSerializer);
            var electionAlgorithm        = electionAlgorithmFactory.Build(nodeConfig.ElectionType);
            var electionResultProvider   = new ElectionResultProvider(
                electionAlgorithm,
                electionEndTime,
                voteMemoryPool,
                blockchain);
            var voterTerminal = new VoterTerminal.VoterTerminal(
                voterDb,
                nodeConfig.Candidates.ToArray(),
                voteSerializer,
                voteMemoryPool,
                electionResultProvider,
                blockchain);
            var votingBooth = new VoterTerminal.VoterBooth(voterTerminal, nodeConfig.ElectionType);

            // startup
            var nodeServer = nodeServerFactory.Build(
                myConnectionInfo,
                knownNodeStore,
                nodeClientFactory,
                nodeClientStore,
                voteMemoryPool,
                blockchain,
                miner,
                voteValidator,
                blockValidator,
                blockchainAdder,
                console);
            var boostrapper = new Bootstrapper(
                MinNetworkSize,
                knownNodeStore,
                nodeClientFactory,
                handshakeRequestFactory,
                nodeClientStore,
                registrarClient,
                registrationRequestFactory,
                nodeServer);

            Console.WriteLine("bootstrapping node network...");
            boostrapper.Bootstrap(myConnectionInfo);
            Console.WriteLine($"{MinNetworkSize} nodes in network! bootstrapping complete");

            if (nodeConfig.IsMiningNode)
            {
                Console.WriteLine("starting miner...");
                miner.Start();

                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine("Press any key to quit");
                Console.ReadKey();
            }
            else
            {
                votingBooth.LaunchBooth();
            }
        }