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

bernardladenthin / BitcoinAddressFinder / #358

25 Jul 2025 10:40PM UTC coverage: 72.611% (+0.2%) from 72.394%
#358

push

bernardladenthin
Extract AbstractKeyProducerQueueBuffered

101 of 108 new or added lines in 8 files covered. (93.52%)

2 existing lines in 1 file now uncovered.

1649 of 2271 relevant lines covered (72.61%)

0.73 hits per line

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

96.61
/src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaSocket.java
1
// @formatter:off
2
/**
3
 * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com
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
 */
18
// @formatter:on
19
package net.ladenthin.bitcoinaddressfinder.keyproducer;
20

21
import net.ladenthin.bitcoinaddressfinder.configuration.CKeyProducerJavaSocket;
22
import java.io.DataInputStream;
23
import java.io.IOException;
24
import java.net.InetSocketAddress;
25
import java.net.ServerSocket;
26
import java.net.Socket;
27
import java.util.concurrent.ExecutorService;
28
import net.ladenthin.bitcoinaddressfinder.BitHelper;
29
import net.ladenthin.bitcoinaddressfinder.KeyUtility;
30
import net.ladenthin.bitcoinaddressfinder.PublicKeyBytes;
31
import org.slf4j.Logger;
32
import java.util.concurrent.*;
33

34
public class KeyProducerJavaSocket extends AbstractKeyProducerQueueBuffered<CKeyProducerJavaSocket> {
35

36
    private ServerSocket serverSocket;
37
    private Socket socket;
38
    private DataInputStream inputStream;
39
    private Future<?> readerFuture;
40

41
    private final ExecutorService readerExecutor = Executors.newSingleThreadExecutor();
1✔
42

43
    public KeyProducerJavaSocket(CKeyProducerJavaSocket config, KeyUtility keyUtility, BitHelper bitHelper, Logger logger) {
44
        super(config, keyUtility, logger);
1✔
45
        setupSocket();
1✔
46
    }
1✔
47

48
    private void setupSocket() {
49
        readerFuture = readerExecutor.submit(() -> {
1✔
50
            int attempts = 0;
1✔
51
            Exception lastException = null;
1✔
52

53
            while (!shouldStop && attempts < cKeyProducerJava.connectionRetryCount) {
1✔
54
                try {
55
                    if (cKeyProducerJava.mode == CKeyProducerJavaSocket.Mode.SERVER) {
1✔
56
                        if (serverSocket == null) {
1✔
57
                            serverSocket = new ServerSocket(cKeyProducerJava.getPort());
1✔
58
                            serverSocket.setSoTimeout(cKeyProducerJava.timeout);
1✔
59
                        }
60
                        socket = serverSocket.accept();
1✔
61
                        logger.info("Accepted client connection at port {}", cKeyProducerJava.getPort());
1✔
62
                    } else {
63
                        socket = new Socket();
1✔
64
                        socket.connect(new InetSocketAddress(cKeyProducerJava.getHost(), cKeyProducerJava.getPort()), cKeyProducerJava.timeout);
1✔
65
                        logger.info("Connected to server at {}:{}", cKeyProducerJava.getHost(), cKeyProducerJava.getPort());
1✔
66
                    }
67

68
                    socket.setSoTimeout(cKeyProducerJava.timeout);
1✔
69
                    inputStream = new DataInputStream(socket.getInputStream());
1✔
70

71
                    byte[] buffer = new byte[PublicKeyBytes.PRIVATE_KEY_MAX_NUM_BYTES];
1✔
72
                    while (!shouldStop) {
1✔
73
                        int read = 0;
1✔
74
                        while (read < buffer.length) {
1✔
75
                            int r = inputStream.read(buffer, read, buffer.length - read);
1✔
76
                            if (r == -1) throw new IOException("End of stream");
1✔
77
                            read += r;
1✔
78
                        }
1✔
79
                        addSecret(buffer.clone());
1✔
80
                    }
1✔
81

82
                } catch (IOException e) {
1✔
83
                    lastException = e;
1✔
84
                    logger.warn("Connection attempt {} failed: {}", attempts + 1, e.getMessage());
1✔
85
                    attempts++;
1✔
86
                    closeConnections();
1✔
87
                    sleep(cKeyProducerJava.retryDelayMillisConnect);
1✔
88
                }
1✔
89
            }
90

91
            if (!shouldStop && socket == null) {
1✔
NEW
92
                throw new RuntimeException("Unable to establish socket connection", lastException);
×
93
            }
94
        });
1✔
95
    }
1✔
96

97
    private void closeConnections() {
98
        try { if (inputStream != null) inputStream.close(); } catch (IOException ignored) {}
1✔
99
        try { if (socket != null) socket.close(); } catch (IOException ignored) {}
1✔
100
        try { if (serverSocket != null) serverSocket.close(); } catch (IOException ignored) {}
1✔
101
        inputStream = null;
1✔
102
        socket = null;
1✔
103
        serverSocket = null;
1✔
104
    }
1✔
105

106
    @Override
107
    protected int getReadTimeout() {
108
        return cKeyProducerJava.timeout;
1✔
109
    }
110

111
    @Override
112
    public void interrupt() {
113
        shouldStop = true;
1✔
114
        if (readerFuture != null) {
1✔
115
            readerFuture.cancel(true);
1✔
116
        }
117
        readerExecutor.shutdownNow();
1✔
118
        closeConnections();
1✔
119
        try {
120
            readerExecutor.awaitTermination(500, TimeUnit.MILLISECONDS);
1✔
NEW
121
        } catch (InterruptedException ex) {
×
122
        }
1✔
123
    }
1✔
124

125
    public void close() {
126
        interrupt();
1✔
127
    }
1✔
128
}
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