18
18
19
19
namespace AWS . Deploy . CLI . Commands ;
20
20
21
+ /// <summary>
22
+ /// Represents a Server mode command that allows communication between this CLI and the AWS Toolkit for Visual Studio.
23
+ /// </summary>
21
24
public class ServerModeCommand (
22
25
IToolInteractiveService toolInteractiveService ) : CancellableAsyncCommand < ServerModeCommandSettings >
23
26
{
27
+ /// <summary>
28
+ /// Runs tool in server mode
29
+ /// </summary>
30
+ /// <param name="context">Command context</param>
31
+ /// <param name="settings">Command settings</param>
32
+ /// <param name="cancellationTokenSource">Cancellation token source</param>
33
+ /// <returns>The command exit code</returns>
34
+ public override async Task < int > ExecuteAsync ( CommandContext context , ServerModeCommandSettings settings , CancellationTokenSource cancellationTokenSource )
35
+ {
36
+ toolInteractiveService . Diagnostics = settings . Diagnostics ;
37
+
38
+ toolInteractiveService . WriteLine ( "Server mode allows communication between this CLI and the AWS Toolkit for Visual Studio." ) ;
39
+
40
+ IEncryptionProvider encryptionProvider = CreateEncryptionProvider ( settings . UnsecureMode ) ;
41
+
42
+ if ( IsPortInUse ( settings . Port ) )
43
+ throw new TcpPortInUseException ( DeployToolErrorCode . TcpPortInUse , "The port you have selected is currently in use by another process." ) ;
44
+
45
+ var url = $ "http://localhost:{ settings . Port } ";
46
+
47
+ var builder = new WebHostBuilder ( )
48
+ . UseKestrel ( )
49
+ . UseUrls ( url )
50
+ . ConfigureServices ( services =>
51
+ {
52
+ services . AddSingleton < IEncryptionProvider > ( encryptionProvider ) ;
53
+ } )
54
+ . UseStartup < Startup > ( ) ;
55
+
56
+ var host = builder . Build ( ) ;
57
+
58
+ if ( settings . ParentPid . GetValueOrDefault ( ) == 0 )
59
+ {
60
+ await host . RunAsync ( cancellationTokenSource . Token ) ;
61
+ }
62
+ else
63
+ {
64
+ try
65
+ {
66
+ var process = Process . GetProcessById ( settings . ParentPid . GetValueOrDefault ( ) ) ;
67
+ process . EnableRaisingEvents = true ;
68
+ process . Exited += async ( sender , args ) => { await ShutDownHost ( host , cancellationTokenSource . Token ) ; } ;
69
+ }
70
+ catch ( Exception exception )
71
+ {
72
+ toolInteractiveService . WriteDebugLine ( exception . PrettyPrint ( ) ) ;
73
+ return CommandReturnCodes . SUCCESS ;
74
+ }
75
+
76
+ await host . RunAsync ( cancellationTokenSource . Token ) ;
77
+ }
78
+
79
+ return CommandReturnCodes . SUCCESS ;
80
+ }
81
+
82
+ /// <summary>
83
+ /// Shuts down the web host
84
+ /// </summary>
85
+ /// <param name="host">Web host</param>
86
+ /// <param name="cancellationToken">Cancellation token</param>
24
87
private async Task ShutDownHost ( IWebHost host , CancellationToken cancellationToken )
25
88
{
26
89
toolInteractiveService . WriteLine ( string . Empty ) ;
@@ -29,6 +92,11 @@ private async Task ShutDownHost(IWebHost host, CancellationToken cancellationTok
29
92
await host . StopAsync ( cancellationToken ) ;
30
93
}
31
94
95
+ /// <summary>
96
+ /// Creates encryption provider
97
+ /// </summary>
98
+ /// <param name="noEncryptionKeyInfo">Indicates that no encryption key info will be provided</param>
99
+ /// <returns>Encryption provider</returns>
32
100
private IEncryptionProvider CreateEncryptionProvider ( bool noEncryptionKeyInfo )
33
101
{
34
102
IEncryptionProvider encryptionProvider ;
@@ -66,59 +134,16 @@ private IEncryptionProvider CreateEncryptionProvider(bool noEncryptionKeyInfo)
66
134
return encryptionProvider ;
67
135
}
68
136
137
+ /// <summary>
138
+ /// Checks if a port is in use
139
+ /// </summary>
140
+ /// <param name="port">Tcp port</param>
141
+ /// <returns>true, if port is in use. false if not.</returns>
69
142
private bool IsPortInUse ( int port )
70
143
{
71
144
var ipGlobalProperties = IPGlobalProperties . GetIPGlobalProperties ( ) ;
72
145
var listeners = ipGlobalProperties . GetActiveTcpListeners ( ) ;
73
146
74
147
return listeners . Any ( x => x . Port == port ) ;
75
148
}
76
-
77
- public override async Task < int > ExecuteAsync ( CommandContext context , ServerModeCommandSettings settings , CancellationTokenSource cancellationTokenSource )
78
- {
79
- toolInteractiveService . Diagnostics = settings . Diagnostics ;
80
-
81
- toolInteractiveService . WriteLine ( "Server mode allows communication between this CLI and the AWS Toolkit for Visual Studio." ) ;
82
-
83
- IEncryptionProvider encryptionProvider = CreateEncryptionProvider ( settings . UnsecureMode ) ;
84
-
85
- if ( IsPortInUse ( settings . Port ) )
86
- throw new TcpPortInUseException ( DeployToolErrorCode . TcpPortInUse , "The port you have selected is currently in use by another process." ) ;
87
-
88
- var url = $ "http://localhost:{ settings . Port } ";
89
-
90
- var builder = new WebHostBuilder ( )
91
- . UseKestrel ( )
92
- . UseUrls ( url )
93
- . ConfigureServices ( services =>
94
- {
95
- services . AddSingleton < IEncryptionProvider > ( encryptionProvider ) ;
96
- } )
97
- . UseStartup < Startup > ( ) ;
98
-
99
- var host = builder . Build ( ) ;
100
-
101
- if ( settings . ParentPid . GetValueOrDefault ( ) == 0 )
102
- {
103
- await host . RunAsync ( cancellationTokenSource . Token ) ;
104
- }
105
- else
106
- {
107
- try
108
- {
109
- var process = Process . GetProcessById ( settings . ParentPid . GetValueOrDefault ( ) ) ;
110
- process . EnableRaisingEvents = true ;
111
- process . Exited += async ( sender , args ) => { await ShutDownHost ( host , cancellationTokenSource . Token ) ; } ;
112
- }
113
- catch ( Exception exception )
114
- {
115
- toolInteractiveService . WriteDebugLine ( exception . PrettyPrint ( ) ) ;
116
- return CommandReturnCodes . SUCCESS ;
117
- }
118
-
119
- await host . RunAsync ( cancellationTokenSource . Token ) ;
120
- }
121
-
122
- return CommandReturnCodes . SUCCESS ;
123
- }
124
149
}
0 commit comments