public NodeDetails Get(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                throw new ArgumentNullException("Invalid Node");
            }

            Guid validatedId;

            if (!Guid.TryParse(id, out validatedId))
            {
                throw new ArgumentOutOfRangeException("Invalid Node");
            }

            NodeDetails node = configurationRepository.Get <NodeDetails>(validatedId);

            if (node == null)
            {
                throw new ReferencedObjectDoesNotExistException("Node could not be found");
            }

            ActiveDirectoryMetadata idp = adIdpLogic.GetAll()
                                          .Where(item => item.Id == node.CredentialId)
                                          .FirstOrDefault();

            node.CredentialDisplayName = idp.Name;

            return(node);
        }
        public static List <NodeDetails> LoadSeedNodesFromCsv(string path, string ip, int port)
        {
            List <NodeDetails> nodeDetails = new List <NodeDetails>();

            if (!File.Exists(path))
            {
                throw new Exception("File path holding node details does not exist");
            }

            StreamReader reader = new StreamReader(path);

            reader.ReadLine();
            while (!reader.EndOfStream)
            {
                string[]    nodeDetailsSplit = reader.ReadLine().Split(',');
                NodeDetails details          = new NodeDetails()
                {
                    IP   = nodeDetailsSplit[0],
                    Port = int.Parse(nodeDetailsSplit[1])
                };

                if (details.IP != ip || details.Port != port)
                {
                    nodeDetails.Add(details);
                }
            }

            return(nodeDetails);
        }
Example #3
0
 public void OnDependencyWalkStart(long walkIndex, string sourceProperty, string nodeId)
 {
     graphSnapshot = dependencyEngine.GetGraphSnapshot();
     nodesInPath.Clear();
     nodesInPath[nodeId] = new NodeDetails(ReevaluationResult.Changed, 1);
     nodeIndex           = 2;
 }
 public void OnDependencyWalkStart(long walkIndex, string sourceProperty, string nodeId)
 {
     graphSnapshot = dependencyEngine.GetGraphSnapshot();
     nodesInPath.Clear();
     nodesInPath[nodeId] = new NodeDetails(ReevaluationResult.Changed, 1);
     nodeIndex = 2;
 }
        public static Command ReceiveCommand(UdpClient udpServer, NodeDetails node, int sourcePort)
        {
            IPAddress address  = IPAddress.Parse(node.IP);
            var       remoteEp = new IPEndPoint(address, node.Port);

            return(ReceivePacket(udpServer, remoteEp));
        }
        public static State PerformSyncing(State state, UdpClient udpServer, int sourcePort, List <NodeDetails> seedNodes)
        {
            state.OutputLog.Add($"{DateTime.Now} - Syncing..");
            int         highestTransaction     = 1;
            NodeDetails highestTransactionNode = null;

            string[] messageParams = new string[] { };
            byte[]   message       = MessageProcessor.ProcessMessage(BlockchainCommands.HIGHEST_TRN, messageParams);
            foreach (var node in seedNodes)
            {
                NodeBroadcasting.BroadcastToSeedNode(message, node);
                var command = SyncingOperations.ReceiveMessage(state, udpServer, node, BlockchainCommands.HIGHEST_TRN_RES, sourcePort);
                if (command.CommandType != BlockchainCommands.NO_RESPONSE)
                {
                    var highestTransactionResultCommand = (HighestTransactionResultCommand)command;
                    if (highestTransaction < highestTransactionResultCommand.TransactionNumber)
                    {
                        state.OutputLog.Add($"{DateTime.Now} - Highest Transaction Updated.");
                        highestTransaction     = highestTransactionResultCommand.TransactionNumber;
                        highestTransactionNode = node;
                    }
                }
            }

            int currentTxNumber = state.Transactions.Count == 0 ? 1 : state.Transactions.Max(p => p.Number);

            if (currentTxNumber < highestTransaction)
            {
                UpdateState(udpServer, state, highestTransactionNode, sourcePort, highestTransaction, currentTxNumber);
                state.Transactions.OrderBy(p => p.Number);
            }

            state.OutputLog.Add($"{DateTime.Now} - Syncing Finished.");
            return(state);
        }
Example #7
0
    private void AddNodeToUpdate(Int2 _nodeGridPos, bool?_hasDirtyLighting, bool?_hasDirtyIncandescence)
    {
        Node _node = GameGrid.GetInstance().TryGetNode(_nodeGridPos);

        if (_node == null)
        {
            return;
        }

        if (_node.IsWall)
        {
            if (!wallNodesToUpdate.Contains(_nodeGridPos))
            {
                wallNodesToUpdate.Add(_nodeGridPos);
            }
        }
        else
        {
            NodeDetails _details;
            if (nodesToUpdate.TryGetValue(_nodeGridPos, out _details))
            {
                _details.SetValues(_hasDirtyLighting, _hasDirtyIncandescence);
                nodesToUpdate[_nodeGridPos] = _details;
            }
            else
            {
                _details = new NodeDetails(_hasDirtyLighting, _hasDirtyIncandescence);
                nodesToUpdate.Add(_nodeGridPos, _details);
            }
        }
    }
        public static void BroadcastToSeedNode(byte[] message, NodeDetails node)
        {
            var        client = new UdpClient();
            IPEndPoint ep     = new IPEndPoint(IPAddress.Parse(node.IP), node.Port);

            client.Connect(ep);
            client.Send(message, message.Length);
            client.Close();
        }
Example #9
0
    public bool isLiving(int id)
    {
        NodeDetails det = GetNodeDetailsById(id, true);

        if (det.category == Category.Living)
        {
            return(true);
        }
        return(false);
    }
 public static Command ReceiveMessage(State state, UdpClient udpServer, NodeDetails node, BlockchainCommands commandType, int sourcePort)
 {
     while (true)
     {
         var command = ReceiveCommand(udpServer, node, sourcePort);
         state.OutputLog.Add($"{DateTime.Now} - Received {command.CommandType} command.");
         if (command.CommandType.Equals(commandType) || command.CommandType.Equals(BlockchainCommands.NO_RESPONSE))
         {
             return(command);
         }
         else
         {
             RequestsProcessor.ProcessReceiveRequest(state, command, node);
         }
     }
 }
Example #11
0
    void DayNightFunctions()
    {
        if (DNCycle != null)
        {
            if (/*DNCycle.transition > .01f && */ !DNCycle.dayTime)
            {
                //Once per night (for now), determine if there are any high-tier activities happening in the city

                if (!highTierActSet)
                {
                    mapLocNum = Random.Range(0, mapNodes.Count);
                }

                mapLoc = mapNodes[mapLocNum];
                NodeDetails nodeDeets = mapLoc.GetComponent <NodeDetails>();

                if (!highTierActSet && !nodeDeets.isEventHappeningHere)
                {
                    NodeDetails.myHighTierActivity = nodeDeets.highTierActivities[Random.Range(0, nodeDeets.highTierActivities.Length)];
                }

                if (NodeDetails.myHighTierActivity != null && NodeDetails.myHighTierActivity != "" && NodeDetails.myHighTierActivity != "Blank")
                {
                    mapLoc.GetComponent <MeshRenderer>().material.color = Color.yellow;

                    policeAlertBG.color   = bgOnColor;
                    policeAlertText.color = Color.yellow;
                    policeAlertText.text  = (StatsPlayer.myName + "! We need your assistance! There is a " +
                                             NodeDetails.myHighTierActivity + " happening at the " + nodeDeets.myLandmark);

                    //Debug.Log("High-Tier Activity happening at " + mapLoc.name + ": " + nodeDeets.myHighTierActivity);
                }
                else
                {
                    if (policeAlertBG.color != bgOffColor)
                    {
                        policeAlertBG.color  = bgOffColor;
                        policeAlertText.text = "";
                        Debug.Log("No high-tier activity happening tonight.");
                    }
                }

                highTierActSet = true;
                nightOver      = false;
            }
        }
    }
 public static State ProcessReceiveRequest(State state, Command command, NodeDetails node)
 {
     state.OutputLog.Add($"{DateTime.Now} - Received {command.CommandType} command.");
     if (state.NodeState != NodeState.SYNCING && command.CommandType.Equals(BlockchainCommands.NEW_TRANS))
     {
         state = ProcessNewTransactionReceived(state, command, node);
     }
     else if (command.CommandType.Equals(BlockchainCommands.GET_TRANS))
     {
         ProcessGetTransactionRequest(state, command, node);
     }
     else if (command.CommandType.Equals(BlockchainCommands.HIGHEST_TRN))
     {
         ProcessHighestTransactionRequest(state, command, node);
     }
     state.OutputLog.Add($"{DateTime.Now} - Command processed.");
     return(state);
 }
 private static Command ReceiveNewTransaction(UdpClient udpServer, NodeDetails node, int expectedTxNumber, int sourcePort)
 {
     while (true)
     {
         var command = ReceiveCommand(udpServer, node, sourcePort);
         if (command.CommandType.Equals(BlockchainCommands.NO_RESPONSE))
         {
             return(command);
         }
         else if (command.CommandType.Equals(BlockchainCommands.NEW_TRANS))
         {
             var newTransactionCommand = (NewTransactionCommand)command;
             if (newTransactionCommand.TransactionNumber == expectedTxNumber)
             {
                 return(command);
             }
         }
     }
 }
        private static State UpdateState(UdpClient udpServer, State state, NodeDetails node, int sourcePort, int highestTransaction, int currentTransaction)
        {
            for (int i = currentTransaction; i <= highestTransaction; i++)
            {
                state.OutputLog.Add($"{DateTime.Now} - Getting Transaction {i}..");
                byte[] message = MessageProcessor.ProcessMessage(BlockchainCommands.GET_TRANS, new string[] { i.ToString() });
                int    retry   = 0;
                var    command = new NewTransactionCommand();
                while (retry < 5)
                {
                    NodeBroadcasting.BroadcastToSeedNode(message, node);
                    var newCommand = ReceiveNewTransaction(udpServer, node, i, sourcePort);
                    if (newCommand.CommandType.Equals(BlockchainCommands.NEW_TRANS))
                    {
                        command = (NewTransactionCommand)newCommand;
                        break;
                    }
                    retry++;
                }

                if (retry >= 5)
                {
                    state.OutputLog.Add($"{DateTime.Now} - Failed to get transaction {i}");
                    return(state);
                }
                state.Transactions.Add(new Transaction(command.TransactionNumber, command.FromUser, command.ToUser, command.Timestamp));
                if (!state.Balances.ContainsKey(command.ToUser))
                {
                    state.Balances.Add(command.ToUser, 0);
                }
                state.Balances[command.ToUser] += 1;

                if (state.Balances.ContainsKey(command.FromUser))
                {
                    state.Balances[command.FromUser] -= 1;
                }
            }

            return(state);
        }
        public static State ProcessReceiveRequest(State state, byte[] messageBytes, NodeDetails node)
        {
            var command = CommandsParser.ParseCommand(messageBytes);

            return(ProcessReceiveRequest(state, command, node));
        }
        public static void ProcessGetTransactionRequest(State state, Command command, NodeDetails node)
        {
            var getTransactionCommand = (GetTransactionCommand)command;
            var transaction           = state.Transactions.FirstOrDefault(p => p.Number == getTransactionCommand.TransactionNumber);

            if (transaction == null)
            {
                NodeBroadcasting.SendNotOkMessage(node);
            }
            else
            {
                byte[] message = MessageProcessor.ProcessMessage(BlockchainCommands.NEW_TRANS, new string[]
                {
                    transaction.Number.ToString(), transaction.From, transaction.To, transaction.Timestamp.ToString()
                });

                NodeBroadcasting.BroadcastToSeedNode(message, node);
            }
        }
 public static void SendNotOkMessage(NodeDetails node)
 {
     byte[] notOkMessage = MessageProcessor.ProcessMessage(Protocol.Commands.BlockchainCommands.NOK_MSG, new string[] { });
     BroadcastToSeedNode(notOkMessage, node);
 }
        public static State ProcessNewTransactionReceived(State state, Command command, NodeDetails node)
        {
            var newTransactionCommand = (NewTransactionCommand)command;
            var existingTransaction   = state.Transactions.FirstOrDefault(p => p.Number == newTransactionCommand.TransactionNumber);

            if (existingTransaction == null)
            {
                state.Transactions.Add(new Transaction(newTransactionCommand.TransactionNumber, newTransactionCommand.FromUser,
                                                       newTransactionCommand.ToUser, newTransactionCommand.Timestamp));
            }
            else
            {
                int index = state.Transactions.FindIndex(p => p.Number == newTransactionCommand.TransactionNumber);
                if (existingTransaction.Timestamp > newTransactionCommand.Timestamp)
                {
                    //Replace transaction
                    state.Balances[state.Transactions[index].To] -= 1;
                    state.Transactions[index] = new Transaction(newTransactionCommand.TransactionNumber, newTransactionCommand.FromUser,
                                                                newTransactionCommand.ToUser, newTransactionCommand.Timestamp);
                    if (!state.Balances.ContainsKey(newTransactionCommand.ToUser))
                    {
                        state.Balances.Add(newTransactionCommand.ToUser, 0);
                    }
                    state.Balances[newTransactionCommand.ToUser] += 1;
                }
            }

            NodeBroadcasting.SendOkMessage(node);
            return(state);
        }
Example #19
0
        public async Task <IActionResult> GetAsync(string name, CancellationToken token)
        {
            name = name.ToLowerInvariant();
            var registrationKey = this.utilities.GetRegistrationKey(name);

            var nodes  = this.utilities.GetNodesTable();
            var result = await nodes.ExecuteAsync(TableOperation.Retrieve <JsonTableEntity>(this.utilities.NodesPartitionKey, registrationKey), null, null, token);

            if (!result.IsSuccessfulStatusCode())
            {
                return(new StatusCodeResult(result.HttpStatusCode));
            }

            ComputeClusterRegistrationInformation registerInfo = (result.Result as JsonTableEntity)?.GetObject <ComputeClusterRegistrationInformation>();

            var heartbeatKey = this.utilities.GetHeartbeatKey(name);

            result = await nodes.ExecuteAsync(TableOperation.Retrieve <JsonTableEntity>(this.utilities.NodesPartitionKey, heartbeatKey), null, null, token);

            if (!result.IsSuccessfulStatusCode())
            {
                return(new StatusCodeResult(result.HttpStatusCode));
            }

            var entity = result.Result as JsonTableEntity;
            ComputeClusterNodeInformation nodeInfo = entity?.GetObject <ComputeClusterNodeInformation>();

            var node = new Node()
            {
                NodeRegistrationInfo = registerInfo, Name = name,
            };

            if (entity?.Timestamp.AddSeconds(this.utilities.Option.MaxMissedHeartbeats * this.utilities.Option.HeartbeatIntervalSeconds) > DateTimeOffset.UtcNow)
            {
                node.Health          = NodeHealth.OK;
                node.RunningJobCount = nodeInfo.Jobs.Count;
                node.EventCount      = 5;
            }
            else
            {
                node.Health = NodeHealth.Error;
            }

            node.State = NodeState.Online;

            var nodeDetails = new NodeDetails()
            {
                NodeInfo = node, Jobs = nodeInfo?.Jobs,
            };

            var metricsKey = this.utilities.GetMinuteHistoryKey();

            result = await nodes.ExecuteAsync(TableOperation.Retrieve <JsonTableEntity>(this.utilities.GetNodePartitionKey(name), metricsKey), null, null, token);

            if (!result.IsSuccessfulStatusCode())
            {
                return(new StatusCodeResult(result.HttpStatusCode));
            }

            var historyEntity = result.Result as JsonTableEntity;

            nodeDetails.History = historyEntity.GetObject <MetricHistory>();

            return(new OkObjectResult(nodeDetails));
        }
Example #20
0
 public void OnNodeEvaluated(long walkIndex, string updatedNode, string nodeId, ReevaluationResult result)
 {
     nodesInPath[nodeId] = new NodeDetails(result, nodeIndex++);
 }
Example #21
0
        private void ProcessChild(SyntaxNode syntaxNode, NodeDetails previousNodeDetails)
        {
            switch (syntaxNode.Kind())
            {
            case SyntaxKind.ClassDeclaration:
            {
                ClassDeclarationSyntax classDeclarationSyntax = (ClassDeclarationSyntax)syntaxNode;

                if (classDeclarationSyntax.AttributeLists.Count > 0)
                {
                    var classDetails = classDeclarationSyntax.GetClassDetails();
                    var classHashes  = Generator.Get(classDetails.Attribute, classDetails.AttributeArgument).Select(generator =>
                        {
                            var key   = generator.GetEnumeratedType();
                            var value = generator.AddClass(classDetails, previousNodeDetails.ParentHashes == null ? string.Empty : previousNodeDetails.ParentHashes[key]);
                            return(new KeyValuePair <XChains, string>(key, value));
                        }).ToDictionary(x => x.Key, x => x.Value);

                    if (classDetails.IsModel)
                    {
                        Models.Add(classDetails.Name, new List <ModelProperty>());
                    }

                    classDetails.ParentHashes = classHashes;

                    var singleLineComments = classDeclarationSyntax.DescendantTrivia().Where(descendent => descendent.IsKind(SyntaxKind.SingleLineCommentTrivia));
                    foreach (var singleLineComment in singleLineComments)
                    {
                        var comment = singleLineComment.ToFullString().Split("//").Last().Trim();
                        if (Regex.IsMatch(syntaxNode.ToString(), Constants.XOnRegex) && classHashes.ContainsKey(XChains.Ethereum))
                        {
                            var expressionDetails = singleLineComment.GetExpressionDetails();
                            Generator.Get(Constants.XOn, Constants.XOnEthereumChain).ForEach(generator =>
                                {
                                    generator.AddExpression(expressionDetails, classHashes.Where(classHash => classHash.Key == XChains.Ethereum).FirstOrDefault().Value);
                                });
                        }
                    }

                    foreach (var member in classDeclarationSyntax.Members)
                    {
                        ProcessChild(member, classDetails);
                    }
                }
            }

            break;

            case SyntaxKind.FieldDeclaration:
            {
                FieldDeclarationSyntax fieldDeclarationSyntax = (FieldDeclarationSyntax)syntaxNode;

                if (previousNodeDetails != null && previousNodeDetails.GetType() == typeof(ClassDetails))
                {
                    var fieldDetails = fieldDeclarationSyntax.GetFieldDetails();
                    if (fieldDetails.Attribute.Equals(string.Empty))
                    {
                        fieldDetails.Attribute         = previousNodeDetails.Attribute;
                        fieldDetails.AttributeArgument = previousNodeDetails.AttributeArgument;
                    }

                    var fieldHashes = Generator.Get(fieldDetails.Attribute, fieldDetails.AttributeArgument).Select(generator =>
                        {
                            var key   = generator.GetEnumeratedType();
                            var value = generator.AddField(fieldDetails, previousNodeDetails.ParentHashes == null ? string.Empty : previousNodeDetails.ParentHashes[key]);
                            return(new KeyValuePair <XChains, string>(key, value));
                        }).ToDictionary(x => x.Key, x => x.Value);

                    var parsedPreviousNodeDetails = (ClassDetails)previousNodeDetails;
                    if (parsedPreviousNodeDetails.IsModel)
                    {
                        foreach (var fieldHash in fieldHashes)
                        {
                            Models[parsedPreviousNodeDetails.Name].Add(new ModelProperty
                                {
                                    Location    = fieldHash.Key,
                                    Hash        = fieldHash.Value,
                                    IsParameter = fieldDetails.IsParameter
                                });
                        }
                    }
                }
                else
                {
                    throw new InvalidExpressionException("Field declared in incorrect place...");
                }
            }

            break;

            case SyntaxKind.ConstructorDeclaration:
            {
                ConstructorDeclarationSyntax constructorDeclarationSyntax = (ConstructorDeclarationSyntax)syntaxNode;

                if (previousNodeDetails != null && previousNodeDetails.GetType() == typeof(ClassDetails))
                {
                    var constructorDetails = constructorDeclarationSyntax.GetConstructorDetails();
                    if (constructorDetails.Attribute.Equals(string.Empty))
                    {
                        constructorDetails.Attribute         = previousNodeDetails.Attribute;
                        constructorDetails.AttributeArgument = previousNodeDetails.AttributeArgument;
                    }

                    var constructorHashes = Generator.Get(constructorDetails.Attribute, constructorDetails.AttributeArgument).Select(generator =>
                        {
                            var key   = generator.GetEnumeratedType();
                            var value = generator.AddConstructor(constructorDetails, previousNodeDetails.ParentHashes == null ? string.Empty : previousNodeDetails.ParentHashes[key]);
                            return(new KeyValuePair <XChains, string>(key, value));
                        }).ToDictionary(x => x.Key, x => x.Value);

                    var    statementQueue     = new Queue <SyntaxNode>(constructorDeclarationSyntax.Body.Statements);
                    string lastKnownBlockHash = string.Empty;

                    while (statementQueue.Count > 0)
                    {
                        var member = statementQueue.Dequeue();
                        if (Regex.IsMatch(member.ToString(), Constants.XOnRegex) && statementQueue.Peek().Kind() == SyntaxKind.Block)
                        {
                            var onChainArguments = member.ToString().Split('(', ')')[1].Split(',').ToList();
                            var blockAttribute   = onChainArguments.First().Contains("\"") ? onChainArguments.First().Replace("\"", "") : onChainArguments.First();
                            var argumentList     = onChainArguments.Skip(1).ToList().Select(argument => argument.Trim()).ToList();

                            constructorDetails.Arguments = argumentList;

                            constructorDetails.ParentHashes      = constructorHashes.Where(methodHash => methodHash.Key.ToString() == blockAttribute).ToDictionary(methodHash => methodHash.Key, methodHash => methodHash.Value);
                            constructorDetails.Attribute         = Constants.XOn;
                            constructorDetails.AttributeArgument = blockAttribute;

                            Generator.Get(Constants.XOn, blockAttribute).ForEach(generator => generator.AddMethodParameters(constructorDetails, constructorHashes.Where(methodHash => methodHash.Key.ToString() == blockAttribute).First().Value, GetModelParameters, Models.Select(model => model.Key).ToList()));

                            ProcessChild(statementQueue.Dequeue(), constructorDetails);

                            lastKnownBlockHash = blockAttribute.Equals(Constants.XOnDesktop) ? constructorHashes.First().Value : string.Empty;
                        }
                        else
                        {
                            constructorDetails.ParentHashes      = constructorHashes;
                            constructorDetails.Attribute         = constructorDetails.Attribute;
                            constructorDetails.AttributeArgument = constructorDetails.AttributeArgument;
                            ProcessChild(member, constructorDetails);
                        }
                    }
                }
                else
                {
                    throw new InvalidExpressionException("Constructor declared in incorrect place...");
                }
            }

            break;

            case SyntaxKind.MethodDeclaration:
            {
                MethodDeclarationSyntax methodDeclarationSyntax = (MethodDeclarationSyntax)syntaxNode;

                if (previousNodeDetails != null && previousNodeDetails.GetType() == typeof(ClassDetails))
                {
                    var methodDetails = methodDeclarationSyntax.GetMethodDetails();
                    if (methodDetails.Attribute.Equals(string.Empty))
                    {
                        methodDetails.Attribute         = previousNodeDetails.Attribute;
                        methodDetails.AttributeArgument = previousNodeDetails.AttributeArgument;
                    }

                    var methodHashes = Generator.Get(string.IsNullOrEmpty(methodDetails.Attribute) ? previousNodeDetails.Attribute : methodDetails.Attribute, string.IsNullOrEmpty(methodDetails.Attribute) ? previousNodeDetails.AttributeArgument : methodDetails.AttributeArgument).Select(generator =>
                        {
                            var key   = generator.GetEnumeratedType();
                            var value = generator.AddMethod(methodDetails, previousNodeDetails.ParentHashes == null ? string.Empty : previousNodeDetails.ParentHashes[key]);
                            return(new KeyValuePair <XChains, string>(key, value));
                        }).ToDictionary(x => x.Key, x => x.Value);

                    var    statementQueue     = new Queue <SyntaxNode>(methodDeclarationSyntax.Body.Statements);
                    string lastKnownBlockHash = string.Empty;

                    while (statementQueue.Count > 0)
                    {
                        var member = statementQueue.Dequeue();
                        if (Regex.IsMatch(member.ToString(), Constants.XOnRegex) && statementQueue.Peek().Kind() == SyntaxKind.Block)
                        {
                            var onChainArguments = member.ToString().Split('(', ')')[1].Split(',').ToList();
                            var blockAttribute   = onChainArguments.First().Contains("\"") ? onChainArguments.First().Replace("\"", "") : onChainArguments.First();
                            var argumentList     = onChainArguments.Skip(1).ToList().Select(argument => argument.Trim()).ToList();
                            var isSynchronous    = member.ToString().StartsWith(Constants.SynchronousEscapeCharacter);

                            methodDetails.Arguments = argumentList;

                            methodDetails.IsSynchronous     = isSynchronous;
                            methodDetails.ParentHashes      = methodHashes.Where(methodHash => methodHash.Key.ToString() == blockAttribute).ToDictionary(methodHash => methodHash.Key, methodHash => methodHash.Value);
                            methodDetails.Attribute         = Constants.XOn;
                            methodDetails.AttributeArgument = blockAttribute;

                            Generator.Get(Constants.XOn, blockAttribute).ForEach(generator =>
                                {
                                    var xCallArguments = generator.AddMethodParameters(methodDetails, methodHashes.Where(methodHash => methodHash.Key.ToString() == blockAttribute).First().Value, GetModelParameters, Models.Select(model => model.Key).ToList());
                                    generator.AddMethodReturnTypes(methodDetails, methodHashes.Where(methodHash => methodHash.Key.ToString() == blockAttribute).First().Value, GetModelReturnsTypes, Models.Select(model => model.Key).ToList());

                                    if (!blockAttribute.Equals(Constants.XOnDesktop))
                                    {
                                        Generator.Get(Constants.XOn, Constants.XOnDesktop).ForEach(generator =>
                                        {
                                            var isReturnStatement = member.ToString().StartsWith("return");
                                            generator.AddExpression(new ExpressionDetails()
                                            {
                                                Statement = (isReturnStatement ? "return " : string.Empty) + (methodDetails.IsSynchronous ? "await " : string.Empty) + string.Format(Constants.XCallExpression, Constants.XOnEthereumChain, methodDetails.Identifier, xCallArguments)
                                            }, lastKnownBlockHash);
                                        });
                                    }
                                });


                            ProcessChild(statementQueue.Dequeue(), methodDetails);

                            lastKnownBlockHash = blockAttribute.Equals(Constants.XOnDesktop) ? methodHashes.First().Value : string.Empty;
                        }
                        else
                        {
                            methodDetails.ParentHashes      = methodHashes;
                            methodDetails.Attribute         = methodDetails.Attribute;
                            methodDetails.AttributeArgument = methodDetails.AttributeArgument;
                            ProcessChild(member, methodDetails);
                        }
                    }
                }
                else
                {
                    throw new InvalidExpressionException("Method declared in incorrect place...");
                }
            }

            break;

            case SyntaxKind.SingleLineCommentTrivia:
            case SyntaxKind.IfStatement:
            case SyntaxKind.ReturnStatement:
            case SyntaxKind.ExpressionStatement:
            case SyntaxKind.LocalDeclarationStatement:
            {
                if (previousNodeDetails != null)
                {
                    var expressionDetails = syntaxNode.GetExpressionDetails();
                    var statementHashes   = Generator.Get(previousNodeDetails.Attribute, previousNodeDetails.AttributeArgument).Select(generator =>
                        {
                            var key   = generator.GetEnumeratedType();
                            var value = generator.AddExpression(expressionDetails, previousNodeDetails.ParentHashes == null ? string.Empty : previousNodeDetails.ParentHashes[key], Models.Select(model => model.Key).ToList());
                            return(new KeyValuePair <XChains, string>(key, value));
                        }).ToDictionary(x => x.Key, x => x.Value);
                }
                else
                {
                    throw new InvalidExpressionException("Expression declared in incorrect place...");
                }
            }

            break;

            case SyntaxKind.Block:
            {
                BlockSyntax blockSyntax = (BlockSyntax)syntaxNode;

                if (previousNodeDetails != null)
                {
                    foreach (var child in blockSyntax.ChildNodes())
                    {
                        ProcessChild(child, previousNodeDetails);
                    }
                }
                else
                {
                    throw new InvalidExpressionException("Block declared in incorrect place...");
                }

                break;
            }

            default:
            {
                foreach (var member in syntaxNode.ChildNodes())
                {
                    ProcessChild(member, new NodeDetails());
                }

                break;
            }
            }
        }
Example #22
0
        /// <summary>
        ///
        /// </summary>
        private TreeData.TreeDataTableDataTable LoadFromDatabase()
        {
            DataTable table       = ds.Tables[0];
            const int key         = 0;
            const int parentkey   = 1;
            const int description = 2;
            const int note        = 3;
            const int scripting   = 4;
            const int ntype       = 5;

            TreeData.TreeDataTableDataTable dt = new TreeData.TreeDataTableDataTable();
            foreach (DataRow dr in table.Rows)
            {
                if (dr[key].ToString() != "")
                {
                    NodeDetails nodeDetails = new NodeDetails(1);
                    nodeDetails.nodeID       = dr[key].ToString();
                    nodeDetails.parentNodeID = dr[parentkey].ToString();


                    if (dr[description] != null)
                    {
                        nodeDetails.nodeDescription = dr[description].ToString();
                    }
                    if (dr[note] != null)
                    {
                        nodeDetails.nodeNote = dr[note].ToString();
                    }
                    if (dr[scripting] != null)
                    {
                        nodeDetails.scripting = dr[scripting].ToString();
                    }
                    if (dr[ntype] != null)
                    {
                        nodeDetails.nodetype = dr[ntype].ToString();
                    }

                    try
                    {
                        dt.AddTreeDataTableRow(nodeDetails.nodeID, nodeDetails.parentNodeID, nodeDetails.nodeDescription,
                                               nodeDetails.nodeNote, nodeDetails.nodeCategory, nodeDetails.nodeSOD, nodeDetails.scripting, nodeDetails.nodetype);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Data may be lost, error with unique key.");
                    }
                    //
                    // -1 is a control row
                    // scripting column contains a stylesheet to load
                    //
                    if (dr[key].ToString() == "-1" && dr[scripting] != null)
                    {
                        string filename = dr[scripting].ToString();
                        if (File.Exists(filename))
                        {
                            LoadStyle(filename);
                        }
                    }
                }
            }
            return(dt);
        }
Example #23
0
        private TreeNode parseDynamic(dynamic dyn, String name)
        {
            TreeNode    node;
            NodeDetails details = new NodeDetails();

            if (dyn is String)
            {
                details.id    = "STRING";
                details.type  = "String";
                details.value = dyn;
                node          = new TreeNode(name != null ? name : "String");
            }
            else if (dyn is int)
            {
                details.id    = "INTEGER";
                details.type  = "Integer";
                details.value = dyn.ToString();
                node          = new TreeNode(name != null ? name : "Integer");
            }
            else if (dyn is float)
            {
                details.id    = "FLOAT";
                details.type  = "Float";
                details.value = dyn.ToString("0.000");
                node          = new TreeNode(name != null ? name : "Float");
            }
            else if (dyn is bool)
            {
                details.id    = "BOOLEAN";
                details.type  = "Boolean";
                details.value = dyn.ToString();
                node          = new TreeNode(name != null ? name : "Boolean");
            }
            else if (dyn is IEnumerable <dynamic> )
            {
                details.id   = "ARRAY_LIST";
                details.type = "Array";

                List <dynamic>  list  = new List <dynamic>(dyn);
                List <TreeNode> nodes = new List <TreeNode>();
                foreach (var i in list)
                {
                    nodes.Add(parseDynamic(i, null));
                }

                if (list.Count == 0)
                {
                    details.value = "Empty List";
                }
                else
                {
                    details.value = list.Count == 1 ? "Contains " + list.Count + " Entry" : "Contains " + list.Count + " Entries";
                }
                node = new TreeNode(name != null ? name : "Array", nodes.ToArray());
            }
            else if (dyn is IDictionary <String, dynamic> )
            {
                details.id   = "DICTIONARY";
                details.type = "Dictionary";

                Dictionary <String, dynamic> dic = new Dictionary <String, dynamic>(dyn);
                List <TreeNode> nodes            = new List <TreeNode>();
                foreach (var i in dic)
                {
                    nodes.Add(parseDynamic(i.Value, i.Key));
                }

                if (dic.Count == 0)
                {
                    details.value = "Empty Dictionary";
                }
                else
                {
                    details.value = dic.Count == 1 ? "Contains " + dic.Count + " Entry" : "Contains " + dic.Count + " Entries";
                }
                node = new TreeNode(name != null ? name : "Dictionary", nodes.ToArray());
            }
            else
            {
                details.id    = "ERROR";
                details.type  = "Error";
                details.value = "ERRORED";
                node          = new TreeNode(name != null ? name : "Error!");
            }

            node.Tag = details;
            return(node);
        }
Example #24
0
    void GangWarOnNode()
    {
        DNCycle.daylightEvent -= GangWarOnNode;

        //TODO Set this as part of the listener for the "DaylightCome" event method when it is triggered on the DayNightCycle script (Not yet implemented)
        //Here, the gangs of the city fight for control of the map's nodes
        foreach (GameObject node in nodeList)
        {
            NodeDetails nodeDeets = node.GetComponent <NodeDetails>();
            if (!nodeDeets.battlingForControl)
            {
                GameObject  neighborToFight = nodeDeets.neighborObjects[Random.Range(0, nodeDeets.neighborObjects.Count)];
                NodeDetails neighborDeets   = neighborToFight.GetComponent <NodeDetails>();

                if (!neighborDeets.battlingForControl && nodeDeets.gangName != neighborDeets.gangName)
                {
                    Debug.Log(node.name + " fighting with " + neighborToFight.name);
                    nodeDeets.battlingForControl     = true;
                    neighborDeets.battlingForControl = true;
                    int isKeepingControl = Random.Range(0, 2);
                    if (isKeepingControl == 0)
                    {
                        Debug.Log(node.name + ": I kept control of my territory!");
                    }
                    else
                    {
                        if (!nodeDeets.isGangHQ)
                        {
                            nodeGangs[nodeDeets.nodeNum] = neighborDeets.gangName;
                            nodeDeets.SetMyGangInfluence();
                            Debug.Log(node.name + ": I lost control of my territory!");
                        }
                        else
                        {
                            Debug.Log("This is my gang's home base! I can't lose!");
                            int isTakingControl = Random.Range(0, 2);
                            if (isTakingControl == 0)
                            {
                                Debug.Log(node.name + ": I was unable to take control!");
                            }
                            else
                            {
                                nodeGangs[neighborDeets.nodeNum] = nodeDeets.gangName;
                                neighborDeets.SetMyGangInfluence();
                                Debug.Log(node.name + ": I was able to take control of " + neighborToFight.name);
                            }
                        }
                    }
                }
                else
                {
                    //Debug.Log(node.name + ": My neighbor, " + neighborToFight.name + " is busy/friendly. No gang war here tonight");
                    //No battling with the chosen neighbor
                    //Choose another?
                }
            }
        }

        //Reset everything for next time
        foreach (GameObject node in nodeList)
        {
            node.GetComponent <NodeDetails>().battlingForControl = false;
        }
    }
        public static void ProcessHighestTransactionRequest(State state, Command command, NodeDetails node)
        {
            int transactionNumber = state.Transactions.Count == 0 ? 0 : state.Transactions.Max(p => p.Number);

            byte[] message = MessageProcessor.ProcessMessage(BlockchainCommands.HIGHEST_TRN_RES,
                                                             new string[] { transactionNumber.ToString() });
            NodeBroadcasting.BroadcastToSeedNode(message, node);
        }
Example #26
0
        public JsonResult GetNode(Guid id)
        {
            NodeDetails node = nodeLogic.Get(id.ToString());

            return(http.RespondSuccess(node));
        }
 public void OnNodeEvaluated(long walkIndex, string updatedNode, string nodeId, ReevaluationResult result)
 {
     nodesInPath[nodeId] = new NodeDetails(result, nodeIndex++);
 }
Example #28
0
        public async Task AddNode()
        {
            var nodeUrl       = GetQueryStringValueAndAssertIfSingleAndNotEmpty("url");
            var tag           = GetStringQueryString("tag", false);
            var watcher       = GetBoolValueQueryString("watcher", false);
            var raftRequestId = GetRaftRequestIdFromQuery();
            var assignedCores = GetIntValueQueryString("assignedCores", false);

            if (assignedCores <= 0)
            {
                throw new ArgumentException("Assigned cores must be greater than 0!");
            }

            nodeUrl = nodeUrl.Trim();
            if (Uri.IsWellFormedUriString(nodeUrl, UriKind.Absolute) == false)
            {
                throw new InvalidOperationException($"Given node URL '{nodeUrl}' is not in a correct format.");
            }

            nodeUrl = UrlHelper.TryGetLeftPart(nodeUrl);
            var remoteIsHttps = nodeUrl.StartsWith("https:", StringComparison.OrdinalIgnoreCase);

            if (HttpContext.Request.IsHttps != remoteIsHttps)
            {
                throw new InvalidOperationException($"Cannot add node '{nodeUrl}' to cluster because it will create invalid mix of HTTPS & HTTP endpoints. A cluster must be only HTTPS or only HTTP.");
            }

            if (tag != null)
            {
                tag = tag.Trim();
            }

            NodeInfo nodeInfo;

            using (ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext ctx))
                using (var requestExecutor = ClusterRequestExecutor.CreateForSingleNode(nodeUrl, Server.Certificate.Certificate))
                {
                    requestExecutor.DefaultTimeout = ServerStore.Engine.OperationTimeout;

                    // test connection to remote.
                    var result = await ServerStore.TestConnectionToRemote(nodeUrl, database : null);

                    if (result.Success == false)
                    {
                        throw new InvalidOperationException(result.Error);
                    }

                    // test connection from remote to destination
                    result = await ServerStore.TestConnectionFromRemote(requestExecutor, ctx, nodeUrl);

                    if (result.Success == false)
                    {
                        throw new InvalidOperationException(result.Error);
                    }

                    var infoCmd = new GetNodeInfoCommand();
                    try
                    {
                        await requestExecutor.ExecuteAsync(infoCmd, ctx);
                    }
                    catch (AllTopologyNodesDownException e)
                    {
                        throw new InvalidOperationException($"Couldn't contact node at {nodeUrl}", e);
                    }

                    nodeInfo = infoCmd.Result;

                    if (SchemaUpgrader.CurrentVersion.ServerVersion != nodeInfo.ServerSchemaVersion)
                    {
                        var nodesVersion = nodeInfo.ServerSchemaVersion == 0 ? "Pre 4.2 version" : nodeInfo.ServerSchemaVersion.ToString();
                        throw new InvalidOperationException($"Can't add node with mismatched storage schema version.{Environment.NewLine}" +
                                                            $"My version is {SchemaUpgrader.CurrentVersion.ServerVersion}, while node's version is {nodesVersion}");
                    }

                    if (ServerStore.IsPassive() && nodeInfo.TopologyId != null)
                    {
                        throw new TopologyMismatchException("You can't add new node to an already existing cluster");
                    }
                }

            if (assignedCores != null && assignedCores > nodeInfo.NumberOfCores)
            {
                throw new ArgumentException("Cannot add node because the assigned cores is larger " +
                                            $"than the available cores on that machine: {nodeInfo.NumberOfCores}");
            }

            if (ServerStore.ValidateFixedPort && nodeInfo.HasFixedPort == false)
            {
                throw new InvalidOperationException($"Failed to add node '{nodeUrl}' to cluster. " +
                                                    $"Node '{nodeUrl}' has port '0' in 'Configuration.Core.ServerUrls' setting. " +
                                                    "Adding a node with non fixed port is forbidden. Define a fixed port for the node to enable cluster creation.");
            }

            ServerStore.EnsureNotPassive();

            if (assignedCores == null)
            {
                assignedCores = ServerStore.LicenseManager.GetCoresToAssign(nodeInfo.NumberOfCores);
            }

            Debug.Assert(assignedCores <= nodeInfo.NumberOfCores);

            ServerStore.LicenseManager.AssertCanAddNode(nodeUrl, assignedCores.Value);

            if (ServerStore.IsLeader())
            {
                using (ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext ctx))
                {
                    var clusterTopology = ServerStore.GetClusterTopology();

                    var possibleNode = clusterTopology.TryGetNodeTagByUrl(nodeUrl);
                    if (possibleNode.HasUrl)
                    {
                        throw new InvalidOperationException($"Can't add a new node on {nodeUrl} to cluster because this url is already used by node {possibleNode.NodeTag}");
                    }

                    if (nodeInfo.ServerId == ServerStore.GetServerId())
                    {
                        throw new InvalidOperationException($"Can't add a new node on {nodeUrl} to cluster because it's a synonym of the current node URL:{ServerStore.GetNodeHttpServerUrl()}");
                    }

                    if (nodeInfo.TopologyId != null)
                    {
                        AssertCanAddNodeWithTopologyId(clusterTopology, nodeInfo, nodeUrl);
                    }

                    var nodeTag = nodeInfo.NodeTag == RachisConsensus.InitialTag ? tag : nodeInfo.NodeTag;
                    CertificateDefinition oldServerCert = null;
                    X509Certificate2      certificate   = null;

                    if (remoteIsHttps)
                    {
                        if (nodeInfo.Certificate == null)
                        {
                            throw new InvalidOperationException($"Cannot add node {nodeTag} with url {nodeUrl} to cluster because it has no certificate while trying to use HTTPS");
                        }

                        certificate = new X509Certificate2(Convert.FromBase64String(nodeInfo.Certificate), (string)null, X509KeyStorageFlags.MachineKeySet);

                        var now = DateTime.UtcNow;
                        if (certificate.NotBefore.ToUniversalTime() > now)
                        {
                            // Because of time zone and time drift issues, we can't assume that the certificate generation will be
                            // proper. Because of that, we allow tolerance of the NotBefore to be a bit earlier / later than the
                            // current time. Clients may still fail to work with our certificate because of timing issues,
                            // but the admin needs to setup time sync properly and there isn't much we can do at that point
                            if ((certificate.NotBefore.ToUniversalTime() - now).TotalDays > 1)
                            {
                                throw new InvalidOperationException(
                                          $"Cannot add node {nodeTag} with url {nodeUrl} to cluster because its certificate '{certificate.FriendlyName}' is not yet valid. It starts on {certificate.NotBefore}");
                            }
                        }

                        if (certificate.NotAfter.ToUniversalTime() < now)
                        {
                            throw new InvalidOperationException($"Cannot add node {nodeTag} with url {nodeUrl} to cluster because its certificate '{certificate.FriendlyName}' expired on {certificate.NotAfter}");
                        }

                        var expected = GetStringQueryString("expectedThumbprint", required: false);
                        if (expected != null)
                        {
                            if (certificate.Thumbprint != expected)
                            {
                                throw new InvalidOperationException($"Cannot add node {nodeTag} with url {nodeUrl} to cluster because its certificate thumbprint '{certificate.Thumbprint}' doesn't match the expected thumbprint '{expected}'.");
                            }
                        }

                        // if it's the same server certificate as our own, we don't want to add it to the cluster
                        if (certificate.Thumbprint != Server.Certificate.Certificate.Thumbprint)
                        {
                            using (ctx.OpenReadTransaction())
                            {
                                var readCert = ServerStore.Cluster.GetCertificateByThumbprint(ctx, certificate.Thumbprint);
                                if (readCert != null)
                                {
                                    oldServerCert = JsonDeserializationServer.CertificateDefinition(readCert);
                                }
                            }

                            if (oldServerCert == null)
                            {
                                var certificateDefinition = new CertificateDefinition
                                {
                                    Certificate          = nodeInfo.Certificate,
                                    Thumbprint           = certificate.Thumbprint,
                                    PublicKeyPinningHash = certificate.GetPublicKeyPinningHash(),
                                    NotAfter             = certificate.NotAfter,
                                    Name = "Server Certificate for " + nodeUrl,
                                    SecurityClearance = SecurityClearance.ClusterNode
                                };

                                var res = await ServerStore.PutValueInClusterAsync(new PutCertificateCommand(certificate.Thumbprint, certificateDefinition,
                                                                                                             $"{raftRequestId}/put-new-certificate"));

                                await ServerStore.Cluster.WaitForIndexNotification(res.Index);
                            }
                        }
                    }

                    await ServerStore.AddNodeToClusterAsync(nodeUrl, nodeTag, validateNotInTopology : true, asWatcher : watcher ?? false);

                    using (ctx.OpenReadTransaction())
                    {
                        clusterTopology = ServerStore.GetClusterTopology(ctx);
                        possibleNode    = clusterTopology.TryGetNodeTagByUrl(nodeUrl);
                        nodeTag         = possibleNode.HasUrl ? possibleNode.NodeTag : null;

                        if (certificate != null && certificate.Thumbprint != Server.Certificate.Certificate.Thumbprint)
                        {
                            var modifiedServerCert = JsonDeserializationServer.CertificateDefinition(ServerStore.Cluster.GetCertificateByThumbprint(ctx, certificate.Thumbprint));

                            if (modifiedServerCert == null)
                            {
                                throw new ConcurrencyException("After adding the certificate, it was removed, shouldn't happen unless another admin removed it midway through.");
                            }

                            if (oldServerCert == null)
                            {
                                modifiedServerCert.Name = "Server certificate for Node " + nodeTag;
                            }
                            else
                            {
                                var value = "Node " + nodeTag;
                                if (modifiedServerCert.Name.Contains(value) == false)
                                {
                                    modifiedServerCert.Name += ", " + value;
                                }
                            }

                            var res = await ServerStore.PutValueInClusterAsync(new PutCertificateCommand(certificate.Thumbprint, modifiedServerCert, $"{raftRequestId}/put-modified-certificate"));

                            await ServerStore.Cluster.WaitForIndexNotification(res.Index);
                        }

                        var nodeDetails = new NodeDetails
                        {
                            NodeTag             = nodeTag,
                            AssignedCores       = assignedCores.Value,
                            NumberOfCores       = nodeInfo.NumberOfCores,
                            InstalledMemoryInGb = nodeInfo.InstalledMemoryInGb,
                            UsableMemoryInGb    = nodeInfo.UsableMemoryInGb,
                            BuildInfo           = nodeInfo.BuildInfo,
                            OsInfo = nodeInfo.OsInfo
                        };
                        await ServerStore.LicenseManager.CalculateLicenseLimits(nodeDetails, forceFetchingNodeInfo : true);
                    }

                    NoContentStatus();
                    return;
                }
            }
            RedirectToLeader();
        }
Example #29
0
        public async Task AddNode()
        {
            SetupCORSHeaders();

            var nodeUrl       = GetQueryStringValueAndAssertIfSingleAndNotEmpty("url");
            var watcher       = GetBoolValueQueryString("watcher", false);
            var assignedCores = GetIntValueQueryString("assignedCores", false);

            if (assignedCores <= 0)
            {
                throw new ArgumentException("Assigned cores must be greater than 0!");
            }

            nodeUrl = UrlHelper.TryGetLeftPart(nodeUrl);
            var remoteIsHttps = nodeUrl.StartsWith("https:", StringComparison.OrdinalIgnoreCase);

            if (HttpContext.Request.IsHttps != remoteIsHttps)
            {
                throw new InvalidOperationException($"Cannot add node '{nodeUrl}' to cluster because it will create invalid mix of HTTPS & HTTP endpoints. A cluster must be only HTTPS or only HTTP.");
            }

            NodeInfo nodeInfo;

            using (ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext ctx))
                using (var requestExecutor = ClusterRequestExecutor.CreateForSingleNode(nodeUrl, Server.Certificate.Certificate))
                {
                    requestExecutor.DefaultTimeout = ServerStore.Engine.OperationTimeout;

                    var infoCmd = new GetNodeInfoCommand();
                    try
                    {
                        await requestExecutor.ExecuteAsync(infoCmd, ctx);
                    }
                    catch (AllTopologyNodesDownException e)
                    {
                        throw new InvalidOperationException($"Couldn't contact node at {nodeUrl}", e);
                    }

                    nodeInfo = infoCmd.Result;

                    if (ServerStore.IsPassive() && nodeInfo.TopologyId != null)
                    {
                        throw new TopologyMismatchException("You can't add new node to an already existing cluster");
                    }
                }

            if (assignedCores != null && assignedCores > nodeInfo.NumberOfCores)
            {
                throw new ArgumentException("Cannot add node because the assigned cores is larger " +
                                            $"than the available cores on that machine: {nodeInfo.NumberOfCores}");
            }

            ServerStore.EnsureNotPassive();

            if (assignedCores == null)
            {
                assignedCores = ServerStore.LicenseManager.GetCoresToAssign(nodeInfo.NumberOfCores);
            }

            Debug.Assert(assignedCores <= nodeInfo.NumberOfCores);

            ServerStore.LicenseManager.AssertCanAddNode(nodeUrl, assignedCores.Value);

            if (ServerStore.IsLeader())
            {
                using (ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext ctx))
                {
                    string          topologyId;
                    ClusterTopology clusterTopology;
                    using (ctx.OpenReadTransaction())
                    {
                        clusterTopology = ServerStore.GetClusterTopology(ctx);
                        topologyId      = clusterTopology.TopologyId;
                    }

                    var possibleNode = clusterTopology.TryGetNodeTagByUrl(nodeUrl);
                    if (possibleNode.HasUrl)
                    {
                        throw new InvalidOperationException($"Can't add a new node on {nodeUrl} to cluster because this url is already used by node {possibleNode.NodeTag}");
                    }

                    if (nodeInfo.ServerId == ServerStore.GetServerId())
                    {
                        throw new InvalidOperationException($"Can't add a new node on {nodeUrl} to cluster because it's a synonym of the current node URL:{ServerStore.GetNodeHttpServerUrl()}");
                    }

                    if (nodeInfo.TopologyId != null)
                    {
                        if (topologyId != nodeInfo.TopologyId)
                        {
                            throw new TopologyMismatchException(
                                      $"Adding a new node to cluster failed. The new node is already in another cluster. " +
                                      $"Expected topology id: {topologyId}, but we get {nodeInfo.TopologyId}");
                        }

                        if (nodeInfo.CurrentState != RachisState.Passive)
                        {
                            throw new InvalidOperationException($"Can't add a new node on {nodeUrl} to cluster " +
                                                                $"because it's already in the cluster under tag :{nodeInfo.NodeTag} " +
                                                                $"and URL: {clusterTopology.GetUrlFromTag(nodeInfo.NodeTag)}");
                        }
                    }

                    var nodeTag = nodeInfo.NodeTag == RachisConsensus.InitialTag ? null : nodeInfo.NodeTag;
                    CertificateDefinition oldServerCert = null;
                    X509Certificate2      certificate   = null;

                    if (remoteIsHttps)
                    {
                        if (nodeInfo.Certificate == null)
                        {
                            throw new InvalidOperationException($"Cannot add node {nodeTag} with url {nodeUrl} to cluster because it has no certificate while trying to use HTTPS");
                        }

                        certificate = new X509Certificate2(Convert.FromBase64String(nodeInfo.Certificate), (string)null, X509KeyStorageFlags.MachineKeySet);

                        var now = DateTime.UtcNow;
                        if (certificate.NotBefore.ToUniversalTime() > now)
                        {
                            // Because of time zone and time drift issues, we can't assume that the certificate generation will be
                            // proper. Because of that, we allow tolerance of the NotBefore to be a bit earlier / later than the
                            // current time. Clients may still fail to work with our certificate because of timing issues,
                            // but the admin needs to setup time sync properly and there isn't much we can do at that point
                            if ((certificate.NotBefore.ToUniversalTime() - now).TotalDays > 1)
                            {
                                throw new InvalidOperationException(
                                          $"Cannot add node {nodeTag} with url {nodeUrl} to cluster because its certificate '{certificate.FriendlyName}' is not yet valid. It starts on {certificate.NotBefore}");
                            }
                        }

                        if (certificate.NotAfter.ToUniversalTime() < now)
                        {
                            throw new InvalidOperationException($"Cannot add node {nodeTag} with url {nodeUrl} to cluster because its certificate '{certificate.FriendlyName}' expired on {certificate.NotAfter}");
                        }

                        var expected = GetStringQueryString("expectedThumbprint", required: false);
                        if (expected != null)
                        {
                            if (certificate.Thumbprint != expected)
                            {
                                throw new InvalidOperationException($"Cannot add node {nodeTag} with url {nodeUrl} to cluster because its certificate thumbprint '{certificate.Thumbprint}' doesn't match the expected thumbprint '{expected}'.");
                            }
                        }

                        using (ctx.OpenReadTransaction())
                        {
                            var key      = Constants.Certificates.Prefix + certificate.Thumbprint;
                            var readCert = ServerStore.Cluster.Read(ctx, key);
                            if (readCert != null)
                            {
                                oldServerCert = JsonDeserializationServer.CertificateDefinition(readCert);
                            }
                        }

                        if (oldServerCert == null)
                        {
                            var certificateDefinition = new CertificateDefinition
                            {
                                Certificate       = nodeInfo.Certificate,
                                Thumbprint        = certificate.Thumbprint,
                                NotAfter          = certificate.NotAfter,
                                Name              = "Server Certificate for " + nodeUrl,
                                SecurityClearance = SecurityClearance.ClusterNode
                            };

                            var res = await ServerStore.PutValueInClusterAsync(new PutCertificateCommand(Constants.Certificates.Prefix + certificate.Thumbprint, certificateDefinition));

                            await ServerStore.Cluster.WaitForIndexNotification(res.Index);
                        }
                    }

                    await ServerStore.AddNodeToClusterAsync(nodeUrl, nodeTag, validateNotInTopology : false, asWatcher : watcher ?? false);

                    using (ctx.OpenReadTransaction())
                    {
                        clusterTopology = ServerStore.GetClusterTopology(ctx);
                        possibleNode    = clusterTopology.TryGetNodeTagByUrl(nodeUrl);
                        nodeTag         = possibleNode.HasUrl ? possibleNode.NodeTag : null;

                        if (certificate != null)
                        {
                            var key = Constants.Certificates.Prefix + certificate.Thumbprint;

                            var modifiedServerCert = JsonDeserializationServer.CertificateDefinition(ServerStore.Cluster.Read(ctx, key));

                            if (modifiedServerCert == null)
                            {
                                throw new ConcurrencyException("After adding the certificate, it was removed, shouldn't happen unless another admin removed it midway through.");
                            }

                            if (oldServerCert == null)
                            {
                                modifiedServerCert.Name = "Server certificate for Node " + nodeTag;
                            }
                            else
                            {
                                var value = "Node " + nodeTag;
                                if (modifiedServerCert.Name.Contains(value) == false)
                                {
                                    modifiedServerCert.Name += ", " + value;
                                }
                            }

                            var res = await ServerStore.PutValueInClusterAsync(new PutCertificateCommand(key, modifiedServerCert));

                            await ServerStore.Cluster.WaitForIndexNotification(res.Index);
                        }

                        var nodeDetails = new NodeDetails
                        {
                            NodeTag             = nodeTag,
                            AssignedCores       = assignedCores.Value,
                            NumberOfCores       = nodeInfo.NumberOfCores,
                            InstalledMemoryInGb = nodeInfo.InstalledMemoryInGb,
                            UsableMemoryInGb    = nodeInfo.UsableMemoryInGb,
                            BuildInfo           = nodeInfo.BuildInfo
                        };
                        await ServerStore.LicenseManager.CalculateLicenseLimits(nodeDetails, forceFetchingNodeInfo : true, waitToUpdate : true);
                    }

                    NoContentStatus();
                    return;
                }
            }
            RedirectToLeader();
        }
Example #30
0
 public NodeStructure()
 {
     Details      = new NodeDetails();
     Details.Name = "New Node";
     Details.Path = "";
 }