@@ -31,26 +31,70 @@ public async static Task Main(string[] args)
3131 LogLevel . Information ,
3232 string . Format ( PowerShellWorkerStrings . PowerShellWorkerVersion , typeof ( Worker ) . Assembly . GetName ( ) . Version ) ) ;
3333
34- WorkerArguments arguments = null ;
35- Parser . Default . ParseArguments < WorkerArguments > ( args )
36- . WithParsed ( ops => arguments = ops )
37- . WithNotParsed ( err => Environment . Exit ( 1 ) ) ;
34+ var workerOptions = new WorkerOptions ( ) ;
35+
36+ var parser = new Parser ( settings =>
37+ {
38+ settings . EnableDashDash = true ;
39+ settings . IgnoreUnknownArguments = true ;
40+ } ) ;
41+ parser . ParseArguments < WorkerArguments > ( args )
42+ . WithParsed ( workerArgs =>
43+ {
44+ // TODO: Remove parsing old command-line arguments that are not prefixed with functions-<argumentname>
45+ // for more information, see https://github.com/Azure/azure-functions-powershell-worker/issues/995
46+ workerOptions . WorkerId = workerArgs . FunctionsWorkerId ?? workerArgs . WorkerId ;
47+ workerOptions . RequestId = workerArgs . FunctionsRequestId ?? workerArgs . RequestId ;
48+
49+ if ( ! string . IsNullOrWhiteSpace ( workerArgs . FunctionsUri ) )
50+ {
51+ try
52+ {
53+ // TODO: Update WorkerOptions to have a URI property instead of host name and port number
54+ // for more information, see https://github.com/Azure/azure-functions-powershell-worker/issues/994
55+ var uri = new Uri ( workerArgs . FunctionsUri ) ;
56+ workerOptions . Host = uri . Host ;
57+ workerOptions . Port = uri . Port ;
58+ }
59+ catch ( UriFormatException formatEx )
60+ {
61+ var message = $ "Invalid URI format: { workerArgs . FunctionsUri } . Error message: { formatEx . Message } ";
62+ throw new ArgumentException ( message , nameof ( workerArgs . FunctionsUri ) ) ;
63+ }
64+ }
65+ else
66+ {
67+ workerOptions . Host = workerArgs . Host ;
68+ workerOptions . Port = workerArgs . Port ;
69+ }
70+
71+ // Validate workerOptions
72+ ValidateProperty ( "WorkerId" , workerOptions . WorkerId ) ;
73+ ValidateProperty ( "RequestId" , workerOptions . RequestId ) ;
74+ ValidateProperty ( "Host" , workerOptions . Host ) ;
75+
76+ if ( workerOptions . Port <= 0 )
77+ {
78+ throw new ArgumentException ( "Port number has not been initialized" , nameof ( workerOptions . Port ) ) ;
79+ }
80+ } ) ;
3881
3982 // Create the very first Runspace so the debugger has the target to attach to.
4083 // This PowerShell instance is shared by the first PowerShellManager instance created in the pool,
4184 // and the dependency manager (used to download dependent modules if needed).
4285 var firstPowerShellInstance = Utils . NewPwshInstance ( ) ;
43- LogPowerShellVersion ( firstPowerShellInstance ) ;
86+ var pwshVersion = Utils . GetPowerShellVersion ( firstPowerShellInstance ) ;
87+ LogPowerShellVersion ( pwshVersion ) ;
4488 WarmUpPowerShell ( firstPowerShellInstance ) ;
4589
46- var msgStream = new MessagingStream ( arguments . Host , arguments . Port ) ;
47- var requestProcessor = new RequestProcessor ( msgStream , firstPowerShellInstance ) ;
90+ var msgStream = new MessagingStream ( workerOptions . Host , workerOptions . Port ) ;
91+ var requestProcessor = new RequestProcessor ( msgStream , firstPowerShellInstance , pwshVersion ) ;
4892
4993 // Send StartStream message
5094 var startedMessage = new StreamingMessage ( )
5195 {
52- RequestId = arguments . RequestId ,
53- StartStream = new StartStream ( ) { WorkerId = arguments . WorkerId }
96+ RequestId = workerOptions . RequestId ,
97+ StartStream = new StartStream ( ) { WorkerId = workerOptions . WorkerId }
5498 } ;
5599
56100 msgStream . Write ( startedMessage ) ;
@@ -75,28 +119,53 @@ private static void WarmUpPowerShell(System.Management.Automation.PowerShell fir
75119 . InvokeAndClearCommands ( ) ;
76120 }
77121
78- private static void LogPowerShellVersion ( System . Management . Automation . PowerShell pwsh )
122+ private static void LogPowerShellVersion ( string pwshVersion )
79123 {
80- var message = string . Format ( PowerShellWorkerStrings . PowerShellVersion , Utils . GetPowerShellVersion ( pwsh ) ) ;
124+ var message = string . Format ( PowerShellWorkerStrings . PowerShellVersion , pwshVersion ) ;
81125 RpcLogger . WriteSystemLog ( LogLevel . Information , message ) ;
82126 }
127+
128+ private static void ValidateProperty ( string name , string value )
129+ {
130+ if ( string . IsNullOrWhiteSpace ( value ) )
131+ {
132+ throw new ArgumentException ( $ "{ name } is null or empty", name ) ;
133+ }
134+ }
83135 }
84136
85137 internal class WorkerArguments
86138 {
87- [ Option ( "host" , Required = true , HelpText = "IP Address used to connect to the Host via gRPC." ) ]
139+ [ Option ( "host" , Required = false , HelpText = "IP Address used to connect to the Host via gRPC." ) ]
88140 public string Host { get ; set ; }
89141
90- [ Option ( "port" , Required = true , HelpText = "Port used to connect to the Host via gRPC." ) ]
142+ [ Option ( "port" , Required = false , HelpText = "Port used to connect to the Host via gRPC." ) ]
91143 public int Port { get ; set ; }
92144
93- [ Option ( "workerId" , Required = true , HelpText = "Worker ID assigned to this language worker." ) ]
145+ [ Option ( "workerId" , Required = false , HelpText = "Worker ID assigned to this language worker." ) ]
94146 public string WorkerId { get ; set ; }
95147
96- [ Option ( "requestId" , Required = true , HelpText = "Request ID used for gRPC communication with the Host." ) ]
148+ [ Option ( "requestId" , Required = false , HelpText = "Request ID used for gRPC communication with the Host." ) ]
97149 public string RequestId { get ; set ; }
98150
99- [ Option ( "grpcMaxMessageLength" , Required = false , HelpText = "[Deprecated and ignored] gRPC Maximum message size." ) ]
100- public int MaxMessageLength { get ; set ; }
151+ [ Option ( "functions-uri" , Required = false , HelpText = "URI with IP Address and Port used to connect to the Host via gRPC." ) ]
152+ public string FunctionsUri { get ; set ; }
153+
154+ [ Option ( "functions-workerid" , Required = false , HelpText = "Worker ID assigned to this language worker." ) ]
155+ public string FunctionsWorkerId { get ; set ; }
156+
157+ [ Option ( "functions-requestid" , Required = false , HelpText = "Request ID used for gRPC communication with the Host." ) ]
158+ public string FunctionsRequestId { get ; set ; }
159+ }
160+
161+ internal class WorkerOptions
162+ {
163+ public string Host { get ; set ; }
164+
165+ public int Port { get ; set ; }
166+
167+ public string WorkerId { get ; set ; }
168+
169+ public string RequestId { get ; set ; }
101170 }
102171}
0 commit comments