58
58
import java .net .URL ;
59
59
import java .nio .charset .Charset ;
60
60
import java .nio .file .Files ;
61
- import java .nio .file .Path ;
62
61
import java .nio .file .Paths ;
63
62
import java .time .Duration ;
64
63
import java .time .Instant ;
@@ -89,26 +88,8 @@ public class DockerSessionFactory implements SessionFactory {
89
88
private final URI dockerUri ;
90
89
private final Image browserImage ;
91
90
private final Capabilities stereotype ;
92
- private boolean isVideoRecordingAvailable ;
93
- private Image videoImage ;
94
- private DockerSessionAssetsPath assetsPath ;
95
-
96
- public DockerSessionFactory (
97
- Tracer tracer ,
98
- HttpClient .Factory clientFactory ,
99
- Docker docker ,
100
- URI dockerUri ,
101
- Image browserImage ,
102
- Capabilities stereotype ) {
103
- this .tracer = Require .nonNull ("Tracer" , tracer );
104
- this .clientFactory = Require .nonNull ("HTTP client" , clientFactory );
105
- this .docker = Require .nonNull ("Docker command" , docker );
106
- this .dockerUri = Require .nonNull ("Docker URI" , dockerUri );
107
- this .browserImage = Require .nonNull ("Docker browser image" , browserImage );
108
- this .stereotype = ImmutableCapabilities .copyOf (
109
- Require .nonNull ("Stereotype" , stereotype ));
110
- this .isVideoRecordingAvailable = false ;
111
- }
91
+ private final Image videoImage ;
92
+ private final DockerAssetsPath assetsPath ;
112
93
113
94
public DockerSessionFactory (
114
95
Tracer tracer ,
@@ -118,9 +99,14 @@ public DockerSessionFactory(
118
99
Image browserImage ,
119
100
Capabilities stereotype ,
120
101
Image videoImage ,
121
- DockerSessionAssetsPath assetsPath ) {
122
- this (tracer , clientFactory , docker , dockerUri , browserImage , stereotype );
123
- this .isVideoRecordingAvailable = true ;
102
+ DockerAssetsPath assetsPath ) {
103
+ this .tracer = Require .nonNull ("Tracer" , tracer );
104
+ this .clientFactory = Require .nonNull ("HTTP client" , clientFactory );
105
+ this .docker = Require .nonNull ("Docker command" , docker );
106
+ this .dockerUri = Require .nonNull ("Docker URI" , dockerUri );
107
+ this .browserImage = Require .nonNull ("Docker browser image" , browserImage );
108
+ this .stereotype = ImmutableCapabilities .copyOf (
109
+ Require .nonNull ("Stereotype" , stereotype ));
124
110
this .videoImage = videoImage ;
125
111
this .assetsPath = assetsPath ;
126
112
}
@@ -145,15 +131,7 @@ public Optional<ActiveSession> apply(CreateSessionRequest sessionRequest) {
145
131
attributeMap .put (AttributeKey .LOGGER_CLASS .getKey (),
146
132
EventAttribute .setValue (this .getClass ().getName ()));
147
133
LOG .info ("Creating container, mapping container port 4444 to " + port );
148
- Map <String , String > browserContainerEnvVars =
149
- getBrowserContainerEnvVars (sessionRequest .getCapabilities ());
150
- Map <String , String > devShmMount =
151
- Collections .singletonMap ("/dev/shm" , "/dev/shm" );
152
- Container container = docker .create (
153
- image (browserImage )
154
- .env (browserContainerEnvVars )
155
- .bind (devShmMount )
156
- .map (Port .tcp (4444 ), Port .tcp (port )));
134
+ Container container = createBrowserContainer (port , sessionRequest .getCapabilities ());
157
135
container .start ();
158
136
ContainerInfo containerInfo = container .inspect ();
159
137
@@ -211,22 +189,16 @@ public Optional<ActiveSession> apply(CreateSessionRequest sessionRequest) {
211
189
212
190
SessionId id = new SessionId (response .getSessionId ());
213
191
Capabilities capabilities = new ImmutableCapabilities ((Map <?, ?>) response .getValue ());
192
+ Capabilities mergedCapabilities = capabilities .merge (sessionRequest .getCapabilities ());
193
+
214
194
Container videoContainer = null ;
215
- if (isVideoRecordingAvailable ) {
216
- Capabilities mergedCapabilities = capabilities .merge (sessionRequest .getCapabilities ());
217
- Optional <Path > containerAssetsPath = assetsPath .createContainerSessionAssetsPath (id );
218
- containerAssetsPath .ifPresent (path -> saveSessionCapabilities (mergedCapabilities , path ));
219
- if (containerAssetsPath .isPresent () && recordVideoForSession (mergedCapabilities )) {
220
- Map <String , String > envVars = getVideoContainerEnvVars (
221
- mergedCapabilities ,
222
- containerInfo .getIp ());
223
- String hostAssetsPath = assetsPath .getHostSessionAssetsPath (id );
224
- Map <String , String > volumeBinds =
225
- Collections .singletonMap (hostAssetsPath , "/videos" );
226
- videoContainer = docker .create (image (videoImage ).env (envVars ).bind (volumeBinds ));
227
- videoContainer .start ();
228
- LOG .info (String .format ("Video container started (id: %s)" , videoContainer .getId ()));
229
- }
195
+ Optional <DockerAssetsPath > path = ofNullable (this .assetsPath );
196
+ if (path .isPresent ()) {
197
+ // Seems we can store session assets
198
+ String containerPath = path .get ().getContainerPath (id );
199
+ saveSessionCapabilities (mergedCapabilities , containerPath );
200
+ String hostPath = path .get ().getHostPath (id );
201
+ videoContainer = startVideoContainer (mergedCapabilities , containerInfo .getIp (), hostPath );
230
202
}
231
203
232
204
Dialect downstream = sessionRequest .getDownstreamDialects ().contains (result .getDialect ()) ?
@@ -249,13 +221,25 @@ public Optional<ActiveSession> apply(CreateSessionRequest sessionRequest) {
249
221
id ,
250
222
remoteAddress ,
251
223
stereotype ,
252
- capabilities ,
224
+ mergedCapabilities ,
253
225
downstream ,
254
226
result .getDialect (),
255
227
Instant .now ()));
256
228
}
257
229
}
258
230
231
+ private Container createBrowserContainer (int port , Capabilities sessionCapabilities ) {
232
+ Map <String , String > browserContainerEnvVars =
233
+ getBrowserContainerEnvVars (sessionCapabilities );
234
+ Map <String , String > devShmMount =
235
+ Collections .singletonMap ("/dev/shm" , "/dev/shm" );
236
+ return docker .create (
237
+ image (browserImage )
238
+ .env (browserContainerEnvVars )
239
+ .bind (devShmMount )
240
+ .map (Port .tcp (4444 ), Port .tcp (port )));
241
+ }
242
+
259
243
private Map <String , String > getBrowserContainerEnvVars (Capabilities sessionRequestCapabilities ) {
260
244
Optional <Dimension > screenResolution =
261
245
ofNullable (getScreenResolution (sessionRequestCapabilities ));
@@ -269,6 +253,21 @@ private Map<String, String> getBrowserContainerEnvVars(Capabilities sessionReque
269
253
return envVars ;
270
254
}
271
255
256
+ private Container startVideoContainer (Capabilities sessionCapabilities ,
257
+ String browserContainerIp , String hostPath ) {
258
+ if (!recordVideoForSession (sessionCapabilities )) {
259
+ return null ;
260
+ }
261
+ Map <String , String > envVars = getVideoContainerEnvVars (
262
+ sessionCapabilities ,
263
+ browserContainerIp );
264
+ Map <String , String > volumeBinds = Collections .singletonMap (hostPath , "/videos" );
265
+ Container videoContainer = docker .create (image (videoImage ).env (envVars ).bind (volumeBinds ));
266
+ videoContainer .start ();
267
+ LOG .info (String .format ("Video container started (id: %s)" , videoContainer .getId ()));
268
+ return videoContainer ;
269
+ }
270
+
272
271
private Map <String , String > getVideoContainerEnvVars (Capabilities sessionRequestCapabilities ,
273
272
String containerIp ) {
274
273
Map <String , String > envVars = new HashMap <>();
@@ -332,11 +331,12 @@ private Object getCapability(Capabilities sessionRequestCapabilities, String cap
332
331
return null ;
333
332
}
334
333
335
- private void saveSessionCapabilities (Capabilities sessionRequestCapabilities , Path assetsPath ) {
334
+ private void saveSessionCapabilities (Capabilities sessionRequestCapabilities , String path ) {
336
335
String capsToJson = new Json ().toJson (sessionRequestCapabilities );
337
336
try {
337
+ Files .createDirectories (Paths .get (path ));
338
338
Files .write (
339
- Paths .get (assetsPath . toString () , "sessionCapabilities.json" ),
339
+ Paths .get (path , "sessionCapabilities.json" ),
340
340
capsToJson .getBytes (Charset .defaultCharset ()));
341
341
} catch (IOException e ) {
342
342
LOG .log (Level .WARNING ,
0 commit comments