All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aerospike.client.cluster.PeerParser Maven / Gradle / Ivy

/*
 * Copyright 2012-2018 Aerospike, Inc.
 *
 * Portions may be licensed to Aerospike, Inc. under one or more contributor
 * license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.aerospike.client.cluster;

import java.util.ArrayList;
import java.util.List;

import com.aerospike.client.AerospikeException;
import com.aerospike.client.Host;
import com.aerospike.client.Info;

/**
 * Parse node's peers.
 */
public final class PeerParser {
	private final Cluster cluster;
	private final Info parser;
	private String tlsName;
	private final int portDefault;
	public final int generation;
	
	public PeerParser(Cluster cluster, Connection conn, List peers) {
		this.cluster = cluster;
		
		String command = (cluster.tlsPolicy != null)? 
				cluster.useServicesAlternate ? "peers-tls-alt" : "peers-tls-std" :
				cluster.useServicesAlternate ? "peers-clear-alt" : "peers-clear-std";
			
		parser = new Info(conn, command);

		if (parser.length == 0) {
			throw new AerospikeException.Parse(command + " response is empty");
		}
		
		parser.skipToValue();
		generation = parser.parseInt();
		parser.expect(',');		
		portDefault = parser.parseInt();
		parser.expect(',');
		parser.expect('[');
		
		// Reset peers
		peers.clear();
		
		if (parser.buffer[parser.offset] == ']') {
			return; 
		}
		
		while (true) {			
			Peer peer = parsePeer();
			peers.add(peer);
			
			if (parser.offset < parser.length && parser.buffer[parser.offset] == ',') {
				parser.offset++;			
			}
			else {
				break;
			}
		}
	}
	
	private Peer parsePeer() {
		Peer peer = new Peer();
		parser.expect('[');
		peer.nodeName = parser.parseString(',');
		parser.offset++;
		peer.tlsName = tlsName = parser.parseString(',');
		parser.offset++;
		peer.hosts = parseHosts();
		parser.expect(']');
		return peer;
	}
	
	private List parseHosts() {
		ArrayList hosts = new ArrayList(4);
		parser.expect('[');
		
		if (parser.buffer[parser.offset] == ']') {
			return hosts;
		}
		
		while (true) {
			Host host = parseHost();
			hosts.add(host);
			
			if (parser.buffer[parser.offset] == ']') {
				parser.offset++;	
				return hosts;
			}			
			parser.offset++;	
		}
	}

	private Host parseHost() {
		String host;
		
		if (parser.buffer[parser.offset] == '[') {
			// IPV6 addresses can start with bracket.
			parser.offset++;
			host = parser.parseString(']');
			parser.offset++;
		}
		else {
			host = parser.parseString(':', ',', ']');
		}
		
		if (cluster.ipMap != null) {
			String alternativeHost = cluster.ipMap.get(host);
			
			if (alternativeHost != null) {
				host = alternativeHost;
			}				
		}

		if (parser.offset < parser.length) {
			byte b = parser.buffer[parser.offset];			

			if (b == ':') {
				parser.offset++;
				int port = parser.parseInt();
				return new Host(host, tlsName, port);
			}
			
			if (b == ',' || b == ']') {
				return new Host(host, tlsName, portDefault);
			}
		}

    	String response = parser.getTruncatedResponse();
		throw new AerospikeException.Parse("Unterminated host in response: " + response);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy