• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

igniterealtime / Smack / #2927

26 Nov 2023 12:58PM UTC coverage: 39.143% (+0.002%) from 39.141%
#2927

push

github

Flowdalic
[sinttest] drop empty line

16385 of 41859 relevant lines covered (39.14%)

0.39 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

27.23
/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/XmppConnectionManager.java
1
/**
2
 *
3
 * Copyright 2018-2023 Florian Schmaus
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
package org.igniterealtime.smack.inttest;
18

19
import java.io.IOException;
20
import java.lang.reflect.InvocationTargetException;
21
import java.security.KeyManagementException;
22
import java.security.NoSuchAlgorithmException;
23
import java.util.ArrayList;
24
import java.util.Collection;
25
import java.util.Collections;
26
import java.util.HashMap;
27
import java.util.List;
28
import java.util.Map;
29
import java.util.Set;
30
import java.util.concurrent.ConcurrentHashMap;
31
import java.util.logging.Level;
32
import java.util.logging.Logger;
33

34
import org.jivesoftware.smack.AbstractXMPPConnection;
35
import org.jivesoftware.smack.ConnectionConfiguration;
36
import org.jivesoftware.smack.SmackException;
37
import org.jivesoftware.smack.SmackException.NoResponseException;
38
import org.jivesoftware.smack.SmackException.NotConnectedException;
39
import org.jivesoftware.smack.XMPPException;
40
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
41
import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection;
42
import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnectionConfiguration;
43
import org.jivesoftware.smack.compression.CompressionModuleDescriptor;
44
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
45
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
46
import org.jivesoftware.smack.util.MultiMap;
47
import org.jivesoftware.smack.util.StringUtils;
48
import org.jivesoftware.smack.websocket.java11.Java11WebSocketFactory;
49
import org.jivesoftware.smack.websocket.okhttp.OkHttpWebSocketFactory;
50
import org.jivesoftware.smackx.admin.ServiceAdministrationManager;
51
import org.jivesoftware.smackx.iqregister.AccountManager;
52

53
import org.igniterealtime.smack.inttest.Configuration.AccountRegistration;
54
import org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.AccountNum;
55
import org.jxmpp.jid.EntityBareJid;
56
import org.jxmpp.jid.impl.JidCreate;
57
import org.jxmpp.jid.parts.Localpart;
58
import org.jxmpp.stringprep.XmppStringprepException;
59

60
public class XmppConnectionManager {
1✔
61

62
    private static final Logger LOGGER = Logger.getLogger(XmppConnectionManager.class.getName());
1✔
63

64
    private static final XmppConnectionDescriptor<? extends AbstractXMPPConnection, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>> DEFAULT_CONNECTION_DESCRIPTOR;
65

66
    private static final Map<String, XmppConnectionDescriptor<? extends AbstractXMPPConnection, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>>> NICKNAME_CONNECTION_DESCRIPTORS = new HashMap<>();
1✔
67

68
    private static final MultiMap<
69
        Class<? extends AbstractXMPPConnection>,
70
        XmppConnectionDescriptor<? extends AbstractXMPPConnection, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>>
71
    > CONNECTION_DESCRIPTORS = new MultiMap<>();
1✔
72

73
    static {
74
        try {
75
            DEFAULT_CONNECTION_DESCRIPTOR = XmppConnectionDescriptor.buildWith(XMPPTCPConnection.class, XMPPTCPConnectionConfiguration.class)
1✔
76
                            .withNickname("tcp")
1✔
77
                            .build();
1✔
78
            addConnectionDescriptor(DEFAULT_CONNECTION_DESCRIPTOR);
1✔
79

80
            addConnectionDescriptor(
1✔
81
                            XmppConnectionDescriptor.buildWith(ModularXmppClientToServerConnection.class, ModularXmppClientToServerConnectionConfiguration.class)
1✔
82
                            .withNickname("modular")
1✔
83
                            .build()
1✔
84
            );
85
            addConnectionDescriptor(
1✔
86
                            XmppConnectionDescriptor.buildWith(ModularXmppClientToServerConnection.class, ModularXmppClientToServerConnectionConfiguration.class, ModularXmppClientToServerConnectionConfiguration.Builder.class)
1✔
87
                            .withNickname("modular-nocompress")
1✔
88
                            .applyExtraConfguration(cb -> cb.removeModule(CompressionModuleDescriptor.class))
1✔
89
                            .build()
1✔
90
            );
91
            addConnectionDescriptor(
1✔
92
                            XmppConnectionDescriptor.buildWebsocketDescriptor("modular-websocket-okhttp", OkHttpWebSocketFactory.class)
1✔
93
            );
94
            addConnectionDescriptor(
1✔
95
                            XmppConnectionDescriptor.buildWebsocketDescriptor("modular-websocket-java11", Java11WebSocketFactory.class)
1✔
96
            );
97
        } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException
×
98
                        | IllegalArgumentException | InvocationTargetException e) {
99
            throw new AssertionError(e);
×
100
        }
1✔
101
    }
1✔
102

103
    public static boolean addConnectionDescriptor(
104
                    XmppConnectionDescriptor<? extends AbstractXMPPConnection, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>> connectionDescriptor) {
105
        String nickname = connectionDescriptor.getNickname();
1✔
106
        Class<? extends AbstractXMPPConnection> connectionClass = connectionDescriptor.getConnectionClass();
1✔
107

108
        boolean alreadyExisted;
109
        synchronized (CONNECTION_DESCRIPTORS) {
1✔
110
            alreadyExisted = removeConnectionDescriptor(nickname);
1✔
111

112
            CONNECTION_DESCRIPTORS.put(connectionClass, connectionDescriptor);
1✔
113
            NICKNAME_CONNECTION_DESCRIPTORS.put(connectionDescriptor.getNickname(), connectionDescriptor);
1✔
114
        }
1✔
115
        return alreadyExisted;
1✔
116
    }
117

118
    public static boolean removeConnectionDescriptor(String nickname) {
119
        synchronized (CONNECTION_DESCRIPTORS) {
1✔
120
            XmppConnectionDescriptor<? extends AbstractXMPPConnection, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>> connectionDescriptor = NICKNAME_CONNECTION_DESCRIPTORS.remove(nickname);
1✔
121
            if (connectionDescriptor == null) {
1✔
122
                return false;
1✔
123
            }
124

125
            boolean removed = CONNECTION_DESCRIPTORS.removeOne(connectionDescriptor.getConnectionClass(), connectionDescriptor);
×
126
            assert removed;
×
127
        }
×
128

129
        return true;
×
130
    }
131

132
    private final XmppConnectionDescriptor<? extends AbstractXMPPConnection, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>> defaultConnectionDescriptor;
133

134
    private final Map<String, XmppConnectionDescriptor<? extends AbstractXMPPConnection, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>>> nicknameConnectionDescriptors;
135

136
    private final MultiMap<
137
        Class<? extends AbstractXMPPConnection>,
138
        XmppConnectionDescriptor<? extends AbstractXMPPConnection, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>>
139
    > connectionDescriptors;
140

141
    private final SmackIntegrationTestFramework sinttestFramework;
142
    private final Configuration sinttestConfiguration;
143
    private final String testRunId;
144

145
    private final AbstractXMPPConnection accountRegistrationConnection;
146
    private final ServiceAdministrationManager adminManager;
147
    private final AccountManager accountManager;
148

149
    /**
150
     * One of the three main connections. The type of the main connections is the default connection type.
151
     */
152
    AbstractXMPPConnection conOne, conTwo, conThree;
153

154
    /**
155
     * A pool of authenticated and free to use connections.
156
     */
157
    private final MultiMap<XmppConnectionDescriptor<?, ?, ?>, AbstractXMPPConnection> connectionPool = new MultiMap<>();
1✔
158

159
    /**
160
     * A list of all ever created connections.
161
     */
162
    private final Map<AbstractXMPPConnection, XmppConnectionDescriptor<?, ?, ?>> connections = new ConcurrentHashMap<>();
1✔
163

164
    XmppConnectionManager(SmackIntegrationTestFramework sinttestFramework)
165
            throws SmackException, IOException, XMPPException, InterruptedException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
1✔
166
        synchronized (CONNECTION_DESCRIPTORS) {
1✔
167
            connectionDescriptors = CONNECTION_DESCRIPTORS.clone();
1✔
168
            nicknameConnectionDescriptors = new HashMap<>(NICKNAME_CONNECTION_DESCRIPTORS);
1✔
169
        }
1✔
170

171
        this.sinttestFramework = sinttestFramework;
1✔
172
        this.sinttestConfiguration = sinttestFramework.config;
1✔
173
        this.testRunId = sinttestFramework.testRunResult.testRunId;
1✔
174

175
        String configuredDefaultConnectionNickname = sinttestConfiguration.defaultConnectionNickname;
1✔
176
        if (configuredDefaultConnectionNickname != null) {
1✔
177
            defaultConnectionDescriptor = nicknameConnectionDescriptors.get(configuredDefaultConnectionNickname);
1✔
178
            if (defaultConnectionDescriptor == null) {
1✔
179
                throw new IllegalArgumentException("Could not find a connection descriptor for connection nickname '" + configuredDefaultConnectionNickname + "'");
×
180
            }
181
        } else {
182
            defaultConnectionDescriptor = DEFAULT_CONNECTION_DESCRIPTOR;
×
183
        }
184

185
        switch (sinttestConfiguration.accountRegistration) {
1✔
186
        case serviceAdministration:
187
        case inBandRegistration:
188
            accountRegistrationConnection = defaultConnectionDescriptor.construct(sinttestConfiguration);
×
189
            accountRegistrationConnection.connect();
×
190

191
            if (sinttestConfiguration.accountRegistration == AccountRegistration.inBandRegistration) {
×
192
                adminManager = null;
×
193
                accountManager = AccountManager.getInstance(accountRegistrationConnection);
×
194
            } else {
195
                accountRegistrationConnection.login(sinttestConfiguration.adminAccountUsername,
×
196
                                sinttestConfiguration.adminAccountPassword);
197
                adminManager = ServiceAdministrationManager.getInstanceFor(accountRegistrationConnection);
×
198
                accountManager = null;
×
199
            }
200
            break;
×
201
        case disabled:
202
            accountRegistrationConnection = null;
1✔
203
            adminManager = null;
1✔
204
            accountManager = null;
1✔
205
            break;
1✔
206
        default:
207
            throw new AssertionError();
×
208
        }
209
    }
1✔
210

211
    SmackIntegrationTestEnvironment prepareEnvironment() throws KeyManagementException, NoSuchAlgorithmException,
212
            InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
213
            SmackException, IOException, XMPPException, InterruptedException {
214
        prepareMainConnections();
×
215
        return new SmackIntegrationTestEnvironment(conOne, conTwo, conThree,
×
216
                sinttestFramework.testRunResult.testRunId, sinttestConfiguration, this);
217
    }
218

219
    private void prepareMainConnections() throws KeyManagementException, NoSuchAlgorithmException, InstantiationException,
220
            IllegalAccessException, IllegalArgumentException, InvocationTargetException, SmackException, IOException,
221
            XMPPException, InterruptedException {
222
        final int mainAccountCount = AccountNum.values().length;
×
223
        List<AbstractXMPPConnection> connections = new ArrayList<>(mainAccountCount);
×
224
        for (AccountNum mainAccountNum : AccountNum.values()) {
×
225
            AbstractXMPPConnection mainConnection = getConnectedMainConnectionFor(mainAccountNum);
×
226
            connections.add(mainConnection);
×
227
        }
228
        conOne = connections.get(0);
×
229
        conTwo = connections.get(1);
×
230
        conThree = connections.get(2);
×
231
    }
×
232

233
    public XmppConnectionDescriptor<? extends AbstractXMPPConnection, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>> getDefaultConnectionDescriptor() {
234
        return defaultConnectionDescriptor;
×
235
    }
236

237
    public Collection<XmppConnectionDescriptor<? extends AbstractXMPPConnection, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>>> getConnectionDescriptors() {
238
        return Collections.unmodifiableCollection(nicknameConnectionDescriptors.values());
×
239
    }
240

241
    @SuppressWarnings("unchecked")
242
    public <C extends AbstractXMPPConnection> XmppConnectionDescriptor<C, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>> getConnectionDescriptorFor(
243
                    Class<C> connectionClass) {
244
        return (XmppConnectionDescriptor<C, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>>) connectionDescriptors.getFirst(
×
245
                        connectionClass);
246
    }
247

248
    void disconnectAndCleanup() throws InterruptedException {
249
        int successfullyDeletedAccountsCount = 0;
1✔
250
        for (AbstractXMPPConnection connection : connections.keySet()) {
1✔
251
            if (sinttestConfiguration.accountRegistration == AccountRegistration.inBandRegistration) {
×
252
                // Note that we use the account manager from the to-be-deleted connection.
253
                AccountManager accountManager = AccountManager.getInstance(connection);
×
254
                try {
255
                    accountManager.deleteAccount();
×
256
                    successfullyDeletedAccountsCount++;
×
257
                } catch (NoResponseException | XMPPErrorException | NotConnectedException e) {
×
258
                    LOGGER.log(Level.WARNING, "Could not delete dynamically registered account", e);
×
259
                }
×
260
            }
261

262
            connection.disconnect();
×
263

264
            if (sinttestConfiguration.accountRegistration == AccountRegistration.serviceAdministration) {
×
265
                String username = connection.getConfiguration().getUsername().toString();
×
266
                Localpart usernameAsLocalpart;
267
                try {
268
                    usernameAsLocalpart = Localpart.from(username);
×
269
                } catch (XmppStringprepException e) {
×
270
                    throw new AssertionError(e);
×
271
                }
×
272

273
                EntityBareJid connectionAddress = JidCreate.entityBareFrom(usernameAsLocalpart, sinttestConfiguration.service);
×
274

275
                try {
276
                    adminManager.deleteUser(connectionAddress);
×
277
                    successfullyDeletedAccountsCount++;
×
278
                } catch (NoResponseException | XMPPErrorException | NotConnectedException e) {
×
279
                    LOGGER.log(Level.WARNING, "Could not delete dynamically registered account", e);
×
280
                }
×
281
            }
282
        }
×
283

284
        if (sinttestConfiguration.isAccountRegistrationPossible()) {
1✔
285
            int unsuccessfullyDeletedAccountsCount = connections.size() - successfullyDeletedAccountsCount;
×
286
            if (unsuccessfullyDeletedAccountsCount == 0) {
×
287
                LOGGER.info("Successfully deleted all created accounts ✔");
×
288
            } else {
289
                LOGGER.warning("Could not delete all created accounts, " + unsuccessfullyDeletedAccountsCount + " remaining");
×
290
            }
291
        }
292

293
        connections.clear();
1✔
294

295
        if (accountRegistrationConnection != null) {
1✔
296
            accountRegistrationConnection.disconnect();
×
297
        }
298
    }
1✔
299

300

301
    private static final String USERNAME_PREFIX = "smack-inttest";
302

303
    private AbstractXMPPConnection getConnectedMainConnectionFor(AccountNum accountNum) throws SmackException, IOException, XMPPException,
304
            InterruptedException, KeyManagementException, NoSuchAlgorithmException, InstantiationException,
305
            IllegalAccessException, IllegalArgumentException, InvocationTargetException {
306
        String middlefix;
307
        String accountUsername;
308
        String accountPassword;
309
        switch (accountNum) {
×
310
        case One:
311
            accountUsername = sinttestConfiguration.accountOneUsername;
×
312
            accountPassword = sinttestConfiguration.accountOnePassword;
×
313
            middlefix = "one";
×
314
            break;
×
315
        case Two:
316
            accountUsername = sinttestConfiguration.accountTwoUsername;
×
317
            accountPassword = sinttestConfiguration.accountTwoPassword;
×
318
            middlefix = "two";
×
319
            break;
×
320
        case Three:
321
            accountUsername = sinttestConfiguration.accountThreeUsername;
×
322
            accountPassword = sinttestConfiguration.accountThreePassword;
×
323
            middlefix = "three";
×
324
            break;
×
325
        default:
326
            throw new IllegalStateException();
×
327
        }
328

329
        // Note that it is perfectly fine for account(Username|Password) to be 'null' at this point.
330
        final String finalAccountUsername = StringUtils.isNullOrEmpty(accountUsername) ? USERNAME_PREFIX + '-' + middlefix + '-' + testRunId : accountUsername;
×
331
        final String finalAccountPassword = StringUtils.isNullOrEmpty(accountPassword) ? StringUtils.insecureRandomString(16) : accountPassword;
×
332

333
        if (sinttestConfiguration.isAccountRegistrationPossible()) {
×
334
            registerAccount(finalAccountUsername, finalAccountPassword);
×
335
        }
336

337
        AbstractXMPPConnection mainConnection = defaultConnectionDescriptor.construct(sinttestConfiguration, builder -> {
×
338
            try {
339
                builder.setUsernameAndPassword(finalAccountUsername, finalAccountPassword)
×
340
                    .setResource(middlefix + '-' + testRunId);
×
341
            } catch (XmppStringprepException e) {
×
342
                throw new IllegalArgumentException(e);
×
343
            }
×
344
        });
×
345

346
        connections.put(mainConnection, defaultConnectionDescriptor);
×
347

348
        mainConnection.connect();
×
349
        mainConnection.login();
×
350

351
        return mainConnection;
×
352
    }
353

354
    private void registerAccount(String username, String password) throws NoResponseException, XMPPErrorException,
355
                    NotConnectedException, InterruptedException, XmppStringprepException {
356
        if (accountRegistrationConnection == null) {
×
357
            throw new IllegalStateException("Account registration not configured");
×
358
        }
359

360
        switch (sinttestConfiguration.accountRegistration) {
×
361
        case serviceAdministration:
362
            EntityBareJid userJid = JidCreate.entityBareFrom(Localpart.from(username),
×
363
                            accountRegistrationConnection.getXMPPServiceDomain());
×
364
            adminManager.addUser(userJid, password);
×
365
            break;
×
366
        case inBandRegistration:
367
            if (!accountManager.supportsAccountCreation()) {
×
368
                throw new UnsupportedOperationException("Account creation/registration is not supported");
×
369
            }
370
            Set<String> requiredAttributes = accountManager.getAccountAttributes();
×
371
            if (requiredAttributes.size() > 4) {
×
372
                throw new IllegalStateException("Unknown required attributes");
×
373
            }
374
            Map<String, String> additionalAttributes = new HashMap<>();
×
375
            additionalAttributes.put("name", "Smack Integration Test");
×
376
            additionalAttributes.put("email", "flow@igniterealtime.org");
×
377
            Localpart usernameLocalpart = Localpart.from(username);
×
378
            accountManager.createAccount(usernameLocalpart, password, additionalAttributes);
×
379
            break;
×
380
        case disabled:
381
            throw new IllegalStateException("Account creation no possible");
×
382
        }
383
    }
×
384

385
    <C extends AbstractXMPPConnection> List<C> constructConnectedConnections(XmppConnectionDescriptor<C, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>>  connectionDescriptor, int count)
386
                    throws InterruptedException, SmackException, IOException, XMPPException {
387
        List<C> connections = new ArrayList<>(count);
×
388

389
        synchronized (connectionPool) {
×
390
            @SuppressWarnings("unchecked")
391
            List<C> pooledConnections = (List<C>) connectionPool.getAll(connectionDescriptor);
×
392
            while (count > 0 && !pooledConnections.isEmpty()) {
×
393
                C connection = pooledConnections.remove(pooledConnections.size() - 1);
×
394
                connections.add(connection);
×
395
                count--;
×
396
            }
×
397
        }
×
398

399
        for (int i = 0; i < count; i++) {
×
400
            C connection = constructConnectedConnection(connectionDescriptor);
×
401
            connections.add(connection);
×
402
        }
403

404
        return connections;
×
405
    }
406

407
    private <C extends AbstractXMPPConnection> C constructConnectedConnection(
408
                    XmppConnectionDescriptor<C, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>> connectionDescriptor)
409
                    throws InterruptedException, SmackException, IOException, XMPPException {
410
        C connection = constructConnection(connectionDescriptor, null);
×
411

412
        connection.connect();
×
413
        connection.login();
×
414

415
        return connection;
×
416
    }
417

418
    AbstractXMPPConnection constructConnection()
419
                    throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
420
        return constructConnection(defaultConnectionDescriptor);
×
421
    }
422

423
    AbstractXMPPConnection constructConnectedConnection()
424
                    throws InterruptedException, SmackException, IOException, XMPPException {
425
        return constructConnectedConnection(defaultConnectionDescriptor);
×
426
    }
427

428
    <C extends AbstractXMPPConnection> C constructConnection(
429
                    XmppConnectionDescriptor<C, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>> connectionDescriptor)
430
                    throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
431
        return constructConnection(connectionDescriptor, null);
×
432
    }
433

434
    private <C extends AbstractXMPPConnection> C constructConnection(
435
            XmppConnectionDescriptor<C, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>> connectionDescriptor,
436
            Collection<ConnectionConfigurationBuilderApplier> customConnectionConfigurationAppliers)
437
            throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
438
        String username = "sinttest-" + testRunId + '-' + (connections.size() + 1);
×
439
        String password = StringUtils.randomString(24);
×
440

441
        return constructConnection(username, password, connectionDescriptor, customConnectionConfigurationAppliers);
×
442
    }
443

444
    private <C extends AbstractXMPPConnection> C constructConnection(final String username, final String password,
445
                    XmppConnectionDescriptor<C, ? extends ConnectionConfiguration, ? extends ConnectionConfiguration.Builder<?, ?>> connectionDescriptor,
446
                    Collection<ConnectionConfigurationBuilderApplier> customConnectionConfigurationAppliers)
447
                    throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
448
        try {
449
            registerAccount(username, password);
×
450
        } catch (XmppStringprepException e) {
×
451
            throw new IllegalArgumentException(e);
×
452
        }
×
453

454
        ConnectionConfigurationBuilderApplier usernameAndPasswordApplier = configurationBuilder -> {
×
455
            configurationBuilder.setUsernameAndPassword(username, password);
×
456
        };
×
457

458
        if (customConnectionConfigurationAppliers == null) {
×
459
            customConnectionConfigurationAppliers = Collections.singleton(usernameAndPasswordApplier);
×
460
        } else {
461
            customConnectionConfigurationAppliers.add(usernameAndPasswordApplier);
×
462
        }
463

464
        C connection;
465
        try {
466
            connection = connectionDescriptor.construct(sinttestConfiguration, customConnectionConfigurationAppliers);
×
467
        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
×
468
                        | InvocationTargetException e) {
469
            throw new IllegalStateException(e);
×
470
        }
×
471

472
        connections.put(connection, connectionDescriptor);
×
473

474
        return connection;
×
475
    }
476

477
    void recycle(Collection<? extends AbstractXMPPConnection> connections) {
478
        for (AbstractXMPPConnection connection : connections) {
×
479
            recycle(connection);
×
480
        }
×
481
    }
×
482

483
    void recycle(AbstractXMPPConnection connection) {
484
        Class<? extends AbstractXMPPConnection> connectionClass = connection.getClass();
×
485
        if (!connectionDescriptors.containsKey(connectionClass)) {
×
486
            throw new IllegalStateException("Attempt to recycle unknown connection of class '" + connectionClass + "'");
×
487
        }
488

489
        if (connection.isAuthenticated()) {
×
490
            XmppConnectionDescriptor<?, ?, ?> connectionDescriptor = connections.get(connection);
×
491
            if (connectionDescriptor == null) {
×
492
                throw new IllegalStateException("Attempt to recycle unknown connection: " + connection);
×
493
            }
494

495
            synchronized (connectionPool) {
×
496
                connectionPool.put(connectionDescriptor, connection);
×
497
            }
×
498
        } else {
×
499
            connection.disconnect();
×
500
        }
501
        // Note that we do not delete the account of the unauthenticated connection here, as it is done at the end of
502
        // the test run together with all other dynamically created accounts.
503
    }
×
504

505
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc