protected override void ProcessRecord() { // iterate attempting to connect, send and receive to Chef node server. for (int tryIndex = 0; tryIndex < Constants.MAX_CLIENT_RETRIES; ++tryIndex) { ITransport transport = new JsonTransport(); PipeClient pipeClient = new PipeClient(Constants.CHEF_NODE_PIPE_NAME, transport); try { pipeClient.Connect(Constants.CHEF_NODE_CONNECT_TIMEOUT_MSECS); SetNodeValueRequestBase request = CreateRequest(); IDictionary responseHash = (IDictionary)transport.NormalizeDeserializedObject(pipeClient.SendReceive <object>(request)); if (null == responseHash) { if (tryIndex + 1 < Constants.MAX_CLIENT_RETRIES) { // delay retry a few ticks to yield time in case server is busy. Thread.Sleep(Constants.SLEEP_BETWEEN_CLIENT_RETRIES_MSECS); continue; } else { string message = String.Format("Failed to get expected response after {0} retries.", Constants.MAX_CLIENT_RETRIES); throw CreateException(message); } } if (ChefNodeCmdletExceptionBase.HasError(responseHash)) { throw CreateException(responseHash); } // done. break; } catch (TimeoutException e) { ThrowTerminatingError(new ErrorRecord(e, "Connection timed out", ErrorCategory.OperationTimeout, pipeClient)); } catch (ChefNodeCmdletExceptionBase e) { ThrowTerminatingError(new ErrorRecord(e, "ChefNodeCmdlet exception", ErrorCategory.InvalidResult, pipeClient)); } catch (Exception e) { ThrowTerminatingError(new ErrorRecord(e, "Unexpected exception", ErrorCategory.NotSpecified, pipeClient)); } finally { pipeClient.Close(); pipeClient = null; } } }
static void Main(string[] args) { // resolve persistent node path. string nodeFilePath = null; if (2 == args.Length && args[0] == "-nf") { nodeFilePath = args[1]; } else { Console.WriteLine("Usage: TestChefNodeCmdlet -nf <nodefile>"); Console.WriteLine(); Console.WriteLine("The nodefile is a JSON text file containing initial values and which receives any modified node values."); return; } // load initial node values, if any. string nodeFileText = ReadTextFile(nodeFilePath); // use JSON transport to unmarshal initial nodes. ITransport transport = new JsonTransport(); IDictionary nodeHash = new Hashtable(); if (nodeFileText.Length > 0) { nodeHash = (IDictionary)transport.NormalizeDeserializedObject(transport.ConvertStringToObject <object>(nodeFileText)); } // current and new resource hashes. IDictionary currentResourceHash = new Hashtable(); currentResourceHash.Add("name", "test name"); IDictionary newResourceHash = new Hashtable(currentResourceHash); // create pipe server using JSON as transport. PipeServer pipeServer = new PipeServer(Constants.CHEF_NODE_PIPE_NAME, transport); Console.WriteLine("Hit Ctrl+C to stop the server."); for (; ;) { try { Console.WriteLine("Waiting for client to connect..."); pipeServer.WaitForConnection(); for (; ;) { // use duck typing to determine type of request. IDictionary requestHash = (IDictionary)transport.NormalizeDeserializedObject(pipeServer.Receive <object>()); if (null == requestHash) { break; } bool validRequest = false; if (requestHash.Contains(Constants.JSON_COMMAND_KEY)) { if (requestHash.Contains(Constants.JSON_PATH_KEY) && requestHash.Contains(Constants.JSON_NODE_VALUE_KEY)) { if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "SetChefNodeRequest") { SetChefNodeRequest request = new SetChefNodeRequest((ICollection)requestHash[Constants.JSON_PATH_KEY], requestHash[Constants.JSON_NODE_VALUE_KEY]); Console.WriteLine(String.Format("Received: {0}", request.ToString())); InsertNodeHash(nodeHash, request.Path, transport.NormalizeDeserializedObject(request.NodeValue)); SetChefNodeResponse response = new SetChefNodeResponse(request.Path); Console.WriteLine(String.Format("Responding: {0}", response.ToString())); pipeServer.Send(response); // save change to node file. WriteTextFile(nodeFilePath, transport.ConvertObjectToString(nodeHash, true)); validRequest = true; } else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "SetCurrentResourceRequest") { SetCurrentResourceRequest request = new SetCurrentResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY], requestHash[Constants.JSON_NODE_VALUE_KEY]); Console.WriteLine(String.Format("Received: {0}", request.ToString())); InsertNodeHash(currentResourceHash, request.Path, transport.NormalizeDeserializedObject(request.NodeValue)); SetCurrentResourceResponse response = new SetCurrentResourceResponse(); Console.WriteLine(String.Format("Responding: {0}", response.ToString())); pipeServer.Send(response); validRequest = true; } else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "SetNewResourceRequest") { SetNewResourceRequest request = new SetNewResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY], requestHash[Constants.JSON_NODE_VALUE_KEY]); Console.WriteLine(String.Format("Received: {0}", request.ToString())); InsertNodeHash(newResourceHash, request.Path, transport.NormalizeDeserializedObject(request.NodeValue)); SetNewResourceResponse response = new SetNewResourceResponse(); Console.WriteLine(String.Format("Responding: {0}", response.ToString())); pipeServer.Send(response); validRequest = true; } } else if (requestHash.Contains(Constants.JSON_PATH_KEY)) { if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "GetChefNodeRequest") { GetChefNodeRequest request = new GetChefNodeRequest((ICollection)requestHash[Constants.JSON_PATH_KEY]); Console.WriteLine(String.Format("Received: {0}", request.ToString())); object nodeValue = QueryNodeHash(nodeHash, request.Path); GetChefNodeResponse response = new GetChefNodeResponse(request.Path, nodeValue); Console.WriteLine(String.Format("Responding: {0}", response.ToString())); pipeServer.Send(response); validRequest = true; } else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "GetCurrentResourceRequest") { GetCurrentResourceRequest request = new GetCurrentResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY]); Console.WriteLine(String.Format("Received: {0}", request.ToString())); object nodeValue = QueryNodeHash(currentResourceHash, request.Path); GetCurrentResourceResponse response = new GetCurrentResourceResponse(request.Path, nodeValue); Console.WriteLine(String.Format("Responding: {0}", response.ToString())); pipeServer.Send(response); validRequest = true; } else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "GetNewResourceRequest") { GetNewResourceRequest request = new GetNewResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY]); Console.WriteLine(String.Format("Received: {0}", request.ToString())); object nodeValue = QueryNodeHash(newResourceHash, request.Path); GetNewResourceResponse response = new GetNewResourceResponse(request.Path, nodeValue); Console.WriteLine(String.Format("Responding: {0}", response.ToString())); pipeServer.Send(response); validRequest = true; } } } if (false == validRequest) { // unknown request type; hang up and try again. break; } } } catch (Exception e) { Console.WriteLine(e.Message); } finally { pipeServer.Close(); } } }
static void Main(string[] args) { // resolve persistent node path. string nodeFilePath = null; if (2 == args.Length && args[0] == "-nf") { nodeFilePath = args[1]; } else { Console.WriteLine("Usage: TestChefNodeCmdlet -nf <nodefile>"); Console.WriteLine(); Console.WriteLine("The nodefile is a JSON text file containing initial values and which receives any modified node values."); return; } // load initial node values, if any. string nodeFileText = ReadTextFile(nodeFilePath); // use JSON transport to unmarshal initial nodes. ITransport transport = new JsonTransport(); IDictionary nodeHash = new Hashtable(); if (nodeFileText.Length > 0) { nodeHash = (IDictionary)transport.NormalizeDeserializedObject(transport.ConvertStringToObject<object>(nodeFileText)); } // current and new resource hashes. IDictionary currentResourceHash = new Hashtable(); currentResourceHash.Add("name", "test name"); IDictionary newResourceHash = new Hashtable(currentResourceHash); // create pipe server using JSON as transport. PipeServer pipeServer = new PipeServer(Constants.CHEF_NODE_PIPE_NAME, transport); Console.WriteLine("Hit Ctrl+C to stop the server."); for (; ; ) { try { Console.WriteLine("Waiting for client to connect..."); pipeServer.WaitForConnection(); for (; ; ) { // use duck typing to determine type of request. IDictionary requestHash = (IDictionary)transport.NormalizeDeserializedObject(pipeServer.Receive<object>()); if (null == requestHash) { break; } bool validRequest = false; if (requestHash.Contains(Constants.JSON_COMMAND_KEY)) { if (requestHash.Contains(Constants.JSON_PATH_KEY) && requestHash.Contains(Constants.JSON_NODE_VALUE_KEY)) { if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "SetChefNodeRequest") { SetChefNodeRequest request = new SetChefNodeRequest((ICollection)requestHash[Constants.JSON_PATH_KEY], requestHash[Constants.JSON_NODE_VALUE_KEY]); Console.WriteLine(String.Format("Received: {0}", request.ToString())); InsertNodeHash(nodeHash, request.Path, transport.NormalizeDeserializedObject(request.NodeValue)); SetChefNodeResponse response = new SetChefNodeResponse(request.Path); Console.WriteLine(String.Format("Responding: {0}", response.ToString())); pipeServer.Send(response); // save change to node file. WriteTextFile(nodeFilePath, transport.ConvertObjectToString(nodeHash, true)); validRequest = true; } else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "SetCurrentResourceRequest") { SetCurrentResourceRequest request = new SetCurrentResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY], requestHash[Constants.JSON_NODE_VALUE_KEY]); Console.WriteLine(String.Format("Received: {0}", request.ToString())); InsertNodeHash(currentResourceHash, request.Path, transport.NormalizeDeserializedObject(request.NodeValue)); SetCurrentResourceResponse response = new SetCurrentResourceResponse(); Console.WriteLine(String.Format("Responding: {0}", response.ToString())); pipeServer.Send(response); validRequest = true; } else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "SetNewResourceRequest") { SetNewResourceRequest request = new SetNewResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY], requestHash[Constants.JSON_NODE_VALUE_KEY]); Console.WriteLine(String.Format("Received: {0}", request.ToString())); InsertNodeHash(newResourceHash, request.Path, transport.NormalizeDeserializedObject(request.NodeValue)); SetNewResourceResponse response = new SetNewResourceResponse(); Console.WriteLine(String.Format("Responding: {0}", response.ToString())); pipeServer.Send(response); validRequest = true; } } else if (requestHash.Contains(Constants.JSON_PATH_KEY)) { if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "GetChefNodeRequest") { GetChefNodeRequest request = new GetChefNodeRequest((ICollection)requestHash[Constants.JSON_PATH_KEY]); Console.WriteLine(String.Format("Received: {0}", request.ToString())); object nodeValue = QueryNodeHash(nodeHash, request.Path); GetChefNodeResponse response = new GetChefNodeResponse(request.Path, nodeValue); Console.WriteLine(String.Format("Responding: {0}", response.ToString())); pipeServer.Send(response); validRequest = true; } else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "GetCurrentResourceRequest") { GetCurrentResourceRequest request = new GetCurrentResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY]); Console.WriteLine(String.Format("Received: {0}", request.ToString())); object nodeValue = QueryNodeHash(currentResourceHash, request.Path); GetCurrentResourceResponse response = new GetCurrentResourceResponse(request.Path, nodeValue); Console.WriteLine(String.Format("Responding: {0}", response.ToString())); pipeServer.Send(response); validRequest = true; } else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "GetNewResourceRequest") { GetNewResourceRequest request = new GetNewResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY]); Console.WriteLine(String.Format("Received: {0}", request.ToString())); object nodeValue = QueryNodeHash(newResourceHash, request.Path); GetNewResourceResponse response = new GetNewResourceResponse(request.Path, nodeValue); Console.WriteLine(String.Format("Responding: {0}", response.ToString())); pipeServer.Send(response); validRequest = true; } } } if (false == validRequest) { // unknown request type; hang up and try again. break; } } } catch (Exception e) { Console.WriteLine(e.Message); } finally { pipeServer.Close(); } } }
// Summary: // implements required cmdlet processing method. protected override void ProcessRecord() { // iterate attempting to connect, send and receive to Chef node server. for (int tryIndex = 0; tryIndex < Constants.MAX_CLIENT_RETRIES; ++tryIndex) { ITransport transport = new JsonTransport(); PipeClient pipeClient = new PipeClient(Constants.CHEF_NODE_PIPE_NAME, transport); try { GetNodeValueRequestBase request = CreateRequest(); pipeClient.Connect(Constants.CHEF_NODE_CONNECT_TIMEOUT_MSECS); IDictionary responseHash = (IDictionary)transport.NormalizeDeserializedObject(pipeClient.SendReceive<object>(request)); if (null == responseHash) { if (tryIndex + 1 < Constants.MAX_CLIENT_RETRIES) { // delay retry a few ticks to yield time in case server is busy. Thread.Sleep(Constants.SLEEP_BETWEEN_CLIENT_RETRIES_MSECS); continue; } else { string message = String.Format("Failed to get expected response after {0} retries.", Constants.MAX_CLIENT_RETRIES); throw CreateException(message); } } if (ChefNodeCmdletExceptionBase.HasError(responseHash)) { throw CreateException(responseHash); } // can't write a null object to pipeline, so write nothing in the null case. object nodeValue = responseHash.Contains(Constants.JSON_NODE_VALUE_KEY) ? responseHash[Constants.JSON_NODE_VALUE_KEY] : null; if (null != nodeValue) { WriteObject(nodeValue, nodeValue is ICollection); } // done. break; } catch (TimeoutException e) { ThrowTerminatingError(new ErrorRecord(e, "Connection timed out", ErrorCategory.OperationTimeout, pipeClient)); } catch (ChefNodeCmdletExceptionBase e) { ThrowTerminatingError(new ErrorRecord(e, "ChefNodeCmdlet exception", ErrorCategory.InvalidResult, pipeClient)); } catch (Exception e) { ThrowTerminatingError(new ErrorRecord(e, "Unexpected exception", ErrorCategory.NotSpecified, pipeClient)); } finally { pipeClient.Close(); pipeClient = null; } } }
static void Main(string[] args) { // resolve persistent node path. string pipeName = null; string nextActionPath = null; if (4 == args.Length && args[0] == "-pn" && args[2] == "-na") { pipeName = args[1]; nextActionPath = args[3]; } else { Console.WriteLine("Usage: -pn <pipe name> -na <next action file path>"); Console.WriteLine(); Console.WriteLine("The <pipe name> is any legal file name which uniquely distinguishes the pipe server."); Console.WriteLine("The <next action file path> is a text file containing a list of actions to execute in PowerShell."); return; } FileStream fileStream = null; StreamReader streamReader = null; try { // read next action file linewise. fileStream = new FileStream(nextActionPath, FileMode.OpenOrCreate, FileAccess.Read); streamReader = new StreamReader(fileStream); // use JSON transport to unmarshal initial nodes. ITransport transport = new JsonTransport(); // create pipe server using JSON as transport. PipeServer pipeServer = new PipeServer(pipeName, transport); Console.WriteLine("Hit Ctrl+C to stop the server."); bool moreCommands = true; while (moreCommands) { try { Console.WriteLine("Waiting for client to connect..."); pipeServer.WaitForConnection(); GetNextActionRequest request = pipeServer.Receive<GetNextActionRequest>(); if (null == request) { break; } Console.WriteLine(String.Format("Received: {0}", request.ToString())); for (;;) { string nextLine = streamReader.ReadLine(); if (null == nextLine) { moreCommands = false; nextLine = "exit"; } if (nextLine.Trim().Length > 0) { GetNextActionResponse response = new GetNextActionResponse(nextLine); Console.WriteLine(String.Format("Responding: {0}", response.ToString())); pipeServer.Send(response); break; } } } catch (Exception e) { Console.WriteLine(e.Message); } finally { pipeServer.Close(); } } } catch (IOException e) { Console.WriteLine(e.Message); } finally { if (null != streamReader) { streamReader.Close(); streamReader = null; } if (null != fileStream) { fileStream.Close(); fileStream = null; } } }
protected override void ProcessRecord() { // iterate attempting to connect, send and receive to Chef node server. for (int tryIndex = 0; tryIndex < Constants.MAX_CLIENT_RETRIES; ++tryIndex) { ITransport transport = new JsonTransport(); PipeClient pipeClient = new PipeClient(PipeName, transport); try { GetNextActionRequest request = new GetNextActionRequest(LastActionExitCode, LastActionErrorMessage); pipeClient.Connect(Constants.NEXT_ACTION_CONNECT_TIMEOUT_MSECS); IDictionary responseHash = (IDictionary)transport.NormalizeDeserializedObject(pipeClient.SendReceive <object>(request)); if (null == responseHash) { if (tryIndex + 1 < Constants.MAX_CLIENT_RETRIES) { // delay retry a few ticks to yield time in case server is busy. Thread.Sleep(Constants.SLEEP_BETWEEN_CLIENT_RETRIES_MSECS); continue; } else { string message = String.Format("Failed to get expected response after {0} retries.", Constants.MAX_CLIENT_RETRIES); throw new GetNextActionException(message); } } if (ChefNodeCmdletExceptionBase.HasError(responseHash)) { throw new GetNextActionException(responseHash); } // next action cannot be null. string nextAction = responseHash.Contains(Constants.JSON_NEXT_ACTION_KEY) ? responseHash[Constants.JSON_NEXT_ACTION_KEY].ToString() : null; if (null == nextAction) { throw new GetNextActionException("Received null for next action; expecting an exit command when finished."); } // enhance next action with try-catch logic to set the $global:RS_LastErrorRecord variable // in case of an exception thrown by a script. the try-catch block loses details of script // execution if caught by an outer block instead of the inner block which threw it. nextAction = NEXT_ACTION_PREFIX + nextAction + NEXT_ACTION_POSTFIX; // automagically convert next action into an invocable script block. // // example of use: // // while ($TRUE) // { // $Error.clear() // $nextAction = $NULL // $nextAction = get-NextAction $pipeName // if ($Error.Count -eq 0) // { // write-output $nextAction // Invoke-Command -scriptblock $nextAction // sleep 1 // } // else // { // break // } // } ScriptBlock scriptBlock = ScriptBlock.Create(nextAction); WriteObject(scriptBlock); // done. break; } catch (TimeoutException e) { ThrowTerminatingError(new ErrorRecord(e, "Connection timed out", ErrorCategory.OperationTimeout, pipeClient)); } catch (GetNextActionException e) { ThrowTerminatingError(new ErrorRecord(e, "get-NextAction exception", ErrorCategory.InvalidResult, pipeClient)); } catch (Exception e) { ThrowTerminatingError(new ErrorRecord(e, "Unexpected exception", ErrorCategory.NotSpecified, pipeClient)); } finally { pipeClient.Close(); pipeClient = null; } } }
protected override void ProcessRecord() { // iterate attempting to connect, send and receive to Chef node server. for (int tryIndex = 0; tryIndex < Constants.MAX_CLIENT_RETRIES; ++tryIndex) { ITransport transport = new JsonTransport(); PipeClient pipeClient = new PipeClient(PipeName, transport); try { // FIX: query the current value of $LastExitCode from powershell host. int lastExitCode = 0; GetNextActionRequest request = new GetNextActionRequest(lastExitCode); pipeClient.Connect(Constants.NEXT_ACTION_CONNECT_TIMEOUT_MSECS); IDictionary responseHash = (IDictionary)transport.NormalizeDeserializedObject(pipeClient.SendReceive<object>(request)); if (null == responseHash) { if (tryIndex + 1 < Constants.MAX_CLIENT_RETRIES) { // delay retry a few ticks to yield time in case server is busy. Thread.Sleep(Constants.SLEEP_BETWEEN_CLIENT_RETRIES_MSECS); continue; } else { string message = String.Format("Failed to get expected response after {0} retries.", Constants.MAX_CLIENT_RETRIES); throw new GetNextActionException(message); } } if (ChefNodeCmdletExceptionBase.HasError(responseHash)) { throw new GetNextActionException(responseHash); } // can't write a null object to pipeline, so write nothing in the null case. string nextAction = responseHash.Contains(Constants.JSON_NEXT_ACTION_KEY) ? responseHash[Constants.JSON_NEXT_ACTION_KEY].ToString() : null; if (null == nextAction) { throw new GetNextActionException("Received null for next action; expecting an exit command when finished."); } // automagically convert next action into an invocable script block. // // example of use: // // while ($TRUE) // { // $Error.clear() // $nextAction = $NULL // $nextAction = get-NextAction // if ($Error.Count -eq 0) // { // write-output $nextAction // Invoke-Command -scriptblock $nextAction // sleep 1 // } // else // { // break // } // } ScriptBlock scriptBlock = ScriptBlock.Create(nextAction); WriteObject(scriptBlock); // done. break; } catch (TimeoutException e) { ThrowTerminatingError(new ErrorRecord(e, "Connection timed out", ErrorCategory.OperationTimeout, pipeClient)); } catch (GetNextActionException e) { ThrowTerminatingError(new ErrorRecord(e, "get-NextAction exception", ErrorCategory.InvalidResult, pipeClient)); } catch (Exception e) { ThrowTerminatingError(new ErrorRecord(e, "Unexpected exception", ErrorCategory.NotSpecified, pipeClient)); } finally { pipeClient.Close(); pipeClient = null; } } }
static void Main(string[] args) { // resolve persistent node path. string pipeName = null; string nextActionPath = null; if (4 == args.Length && args[0] == "-pn" && args[2] == "-na") { pipeName = args[1]; nextActionPath = args[3]; } else { Console.WriteLine("Usage: -pn <pipe name> -na <next action file path>"); Console.WriteLine(); Console.WriteLine("The <pipe name> is any legal file name which uniquely distinguishes the pipe server."); Console.WriteLine("The <next action file path> is a text file containing a list of actions to execute in PowerShell."); return; } FileStream fileStream = null; StreamReader streamReader = null; try { // read next action file linewise. fileStream = new FileStream(nextActionPath, FileMode.OpenOrCreate, FileAccess.Read); streamReader = new StreamReader(fileStream); // use JSON transport to unmarshal initial nodes. ITransport transport = new JsonTransport(); // create pipe server using JSON as transport. PipeServer pipeServer = new PipeServer(pipeName, transport); Console.WriteLine("Hit Ctrl+C to stop the server."); bool moreCommands = true; while (moreCommands) { try { Console.WriteLine("Waiting for client to connect..."); pipeServer.WaitForConnection(); GetNextActionRequest request = pipeServer.Receive <GetNextActionRequest>(); if (null == request) { break; } Console.WriteLine(String.Format("Received: {0}", request.ToString())); for (;;) { string nextLine = streamReader.ReadLine(); if (null == nextLine) { moreCommands = false; nextLine = "exit"; } if (nextLine.Trim().Length > 0) { GetNextActionResponse response = new GetNextActionResponse(nextLine); Console.WriteLine(String.Format("Responding: {0}", response.ToString())); pipeServer.Send(response); break; } } } catch (Exception e) { Console.WriteLine(e.Message); } finally { pipeServer.Close(); } } } catch (IOException e) { Console.WriteLine(e.Message); } finally { if (null != streamReader) { streamReader.Close(); streamReader = null; } if (null != fileStream) { fileStream.Close(); fileStream = null; } } }