comparison src/main/java/org/monetdb/mcl/net/MapiSocket.java @ 834:5aa19bbed0d6 monetdbs

Comments and formatting
author Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
date Wed, 13 Dec 2023 15:39:47 +0100 (17 months ago)
parents ede3a59ff4f2
children 071be9a628e8
comparison
equal deleted inserted replaced
813:a71afa48f269 834:5aa19bbed0d6
20 import java.net.*; 20 import java.net.*;
21 import java.nio.charset.StandardCharsets; 21 import java.nio.charset.StandardCharsets;
22 import java.security.MessageDigest; 22 import java.security.MessageDigest;
23 import java.security.NoSuchAlgorithmException; 23 import java.security.NoSuchAlgorithmException;
24 import java.util.*; 24 import java.util.*;
25 import java.util.stream.Collectors;
26 25
27 import org.monetdb.mcl.MCLException; 26 import org.monetdb.mcl.MCLException;
28 import org.monetdb.mcl.io.BufferedMCLReader; 27 import org.monetdb.mcl.io.BufferedMCLReader;
29 import org.monetdb.mcl.io.BufferedMCLWriter; 28 import org.monetdb.mcl.io.BufferedMCLWriter;
30 import org.monetdb.mcl.io.LineType; 29 import org.monetdb.mcl.io.LineType;
79 * @version 4.3 78 * @version 4.3
80 * @see org.monetdb.mcl.io.BufferedMCLReader 79 * @see org.monetdb.mcl.io.BufferedMCLReader
81 * @see org.monetdb.mcl.io.BufferedMCLWriter 80 * @see org.monetdb.mcl.io.BufferedMCLWriter
82 */ 81 */
83 public final class MapiSocket { 82 public final class MapiSocket {
84 public static final byte[] NUL_BYTES = new byte[]{ 0, 0, 0, 0, 0, 0, 0, 0, }; 83 /* an even number of NUL bytes used during the handshake */
84 private static final byte[] NUL_BYTES = new byte[]{ 0, 0, 0, 0, 0, 0, 0, 0, };
85
86 /* A mapping between hash algorithm names as used in the MAPI
87 * protocol, and the names by which the Java runtime knows them.
88 */
85 private static final String[][] KNOWN_ALGORITHMS = new String[][] { 89 private static final String[][] KNOWN_ALGORITHMS = new String[][] {
86 {"SHA512", "SHA-512"}, 90 {"SHA512", "SHA-512"},
87 {"SHA384", "SHA-384"}, 91 {"SHA384", "SHA-384"},
88 {"SHA256", "SHA-256"}, 92 {"SHA256", "SHA-256"},
89 // should we deprecate this by now? 93 // should we deprecate this by now?
260 264
261 public List<String> connect(String url, Properties props) throws URISyntaxException, ValidationError, MCLException, MCLParseException, IOException { 265 public List<String> connect(String url, Properties props) throws URISyntaxException, ValidationError, MCLException, MCLParseException, IOException {
262 return connect(new Target(url, props), null); 266 return connect(new Target(url, props), null);
263 } 267 }
264 268
269 /**
270 * Connect according to the settings in the 'target' parameter.
271 * If followRedirect is false, a RedirectionException is
272 * thrown when a redirect is encountered.
273 *
274 * Some settings, such as the initial reply size, can already be configured
275 * during the handshake, saving a command round-trip later on.
276 * To do so, create and pass a subclass of {@link MapiSocket.OptionsCallback}.
277 *
278 * @param target the connection settings
279 * @param callback will be called if the server allows options to be set during the
280 * initial handshake
281 * @return A List with informational (warning) messages. If this
282 * list is empty; then there are no warnings.
283 * @throws IOException if an I/O error occurs when creating the socket
284 * @throws SocketException - if there is an error in the underlying protocol, such as a TCP error.
285 * @throws UnknownHostException if the IP address of the host could not be determined
286 * @throws MCLParseException if bogus data is received
287 * @throws MCLException if an MCL related error occurs
288 */
265 public List<String> connect(Target target, OptionsCallback callback) throws MCLException, MCLParseException, IOException { 289 public List<String> connect(Target target, OptionsCallback callback) throws MCLException, MCLParseException, IOException {
266 // get rid of any earlier connection state, including the existing target 290 // get rid of any earlier connection state, including the existing target
267 close(); 291 close();
268 this.target = target; 292 this.target = target;
269 293
519 appendPrefixHere.append(mapiName); 543 appendPrefixHere.append(mapiName);
520 appendPrefixHere.append('}'); 544 appendPrefixHere.append('}');
521 } 545 }
522 return digest; 546 return digest;
523 } 547 }
524 String algoNames = algos.stream().collect(Collectors.joining()); 548 String algoNames = String.join(",", algos);
525 throw new MCLException("No supported hash algorithm: " + algoNames); 549 throw new MCLException("No supported hash algorithm: " + algoNames);
526 } 550 }
527 551
528 private void hexhash(StringBuilder buffer, MessageDigest digest, String text) { 552 private void hexhash(StringBuilder buffer, MessageDigest digest, String text) {
529 byte[] bytes = text.getBytes(StandardCharsets.UTF_8); 553 byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
1446 else 1470 else
1447 return off - origOff; 1471 return off - origOff;
1448 } 1472 }
1449 } 1473 }
1450 1474
1475 /**
1476 * Callback used during the initial MAPI handshake.
1477 *
1478 * Newer MonetDB versions allow setting some options during the handshake.
1479 * The options are language-specific and each has a 'level'. The server
1480 * advertises up to which level options are supported for a given language
1481 * and for each language/option combination, {@link addOptions} will be invoked.
1482 * It should call {@link contribute} for each option it wants to set.
1483 *
1484 * At the time of writing, only the 'sql' language supports options,
1485 * they are listed in enum mapi_handshake_options_levels in mapi.h.
1486 */
1451 public static abstract class OptionsCallback { 1487 public static abstract class OptionsCallback {
1452 private StringBuilder buffer; 1488 private StringBuilder buffer;
1453 1489
1490 /**
1491 * Callback called for each language/level combination supported by the
1492 * server. May call {@link contribute} for options with a level STRICTLY
1493 * LOWER than the level passed as a parameter.
1494 * @param lang language advertised by the server
1495 * @param level one higher than the maximum supported option
1496 */
1497 public abstract void addOptions(String lang, int level);
1498
1499 /**
1500 * Pass option=value during the handshake
1501 * @param field
1502 * @param value
1503 */
1454 protected void contribute(String field, int value) { 1504 protected void contribute(String field, int value) {
1455 if (buffer.length() > 0) 1505 if (buffer.length() > 0)
1456 buffer.append(','); 1506 buffer.append(',');
1457 buffer.append(field); 1507 buffer.append(field);
1458 buffer.append('='); 1508 buffer.append('=');
1459 buffer.append(value); 1509 buffer.append(value);
1460 } 1510 }
1461 1511
1462 public abstract void addOptions(String lang, int level);
1463 1512
1464 void setBuffer(StringBuilder buf) { 1513 void setBuffer(StringBuilder buf) {
1465 buffer = buf; 1514 buffer = buf;
1466 } 1515 }
1467 } 1516 }