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

org.csource.fastdfs.TrackerClient Maven / Gradle / Ivy

The newest version!
/**
* Copyright (C) 2008 Happy Fish / YuQing
*
* FastDFS Java Client may be copied only under the terms of the GNU Lesser
* General Public License (LGPL).
* Please visit the FastDFS Home Page http://www.csource.org/ for more detail.
*/

package org.csource.fastdfs;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Arrays;

/**
* Tracker client
* @author Happy Fish / YuQing
* @version Version 1.19
*/
public class TrackerClient
{
	protected TrackerGroup tracker_group;
  protected byte errno;
  
/**
* constructor with global tracker group
*/
	public TrackerClient()
	{
		this.tracker_group = ClientGlobal.g_tracker_group;
	}
	
/**
* constructor with specified tracker group
* @param tracker_group the tracker group object
*/
	public TrackerClient(TrackerGroup tracker_group)
	{
		this.tracker_group = tracker_group;
	}
	
/**
* get the error code of last call
* @return the error code of last call
*/
	public byte getErrorCode()
	{
		return this.errno;
	}
	
	/**
	* get a connection to tracker server
	* @return tracker server Socket object, return null if fail
	*/
	public TrackerServer getConnection() throws IOException
	{
		return this.tracker_group.getConnection();
	}
	
	/**
	* query storage server to upload file
	* @param trackerServer the tracker server
	* @return storage server Socket object, return null if fail
	*/
	public StorageServer getStoreStorage(TrackerServer trackerServer) throws IOException
	{
		final String groupName = null;
		return this.getStoreStorage(trackerServer, groupName);
	}
	
	/**
	* query storage server to upload file
	* @param trackerServer the tracker server
	* @param groupName the group name to upload file to, can be empty
	* @return storage server object, return null if fail
	*/
	public StorageServer getStoreStorage(TrackerServer trackerServer, String groupName) throws IOException
	{
		byte[] header;
		String ip_addr;
		int port;
		byte cmd;
		int out_len;
		boolean bNewConnection;
		byte store_path;
		Socket trackerSocket;
		
		if (trackerServer == null)
		{
			trackerServer = getConnection();
			if (trackerServer == null)
			{
				return null;
			}
			bNewConnection = true;
		}
		else
		{
			bNewConnection = false;
		}

		trackerSocket = trackerServer.getSocket();
		OutputStream out = trackerSocket.getOutputStream();
		
		try
		{
			if (groupName == null || groupName.length() == 0)
			{
				cmd = ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITHOUT_GROUP_ONE;
				out_len = 0;
			}
			else
			{
				cmd = ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITH_GROUP_ONE;
				out_len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;
			}
			header = ProtoCommon.packHeader(cmd, out_len, (byte)0);
			out.write(header);

			if (groupName != null && groupName.length() > 0)
			{
				byte[] bGroupName;
				byte[] bs;
				int group_len;
				
				bs = groupName.getBytes(ClientGlobal.g_charset);
				bGroupName = new byte[ProtoCommon.FDFS_GROUP_NAME_MAX_LEN];
				
				if (bs.length <= ProtoCommon.FDFS_GROUP_NAME_MAX_LEN)
				{
					group_len = bs.length;
				}
				else
				{
					group_len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;
				}
				Arrays.fill(bGroupName, (byte)0);
				System.arraycopy(bs, 0, bGroupName, 0, group_len);
				out.write(bGroupName);
			}
	
			ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(trackerSocket.getInputStream(),
	                                     ProtoCommon.TRACKER_PROTO_CMD_RESP,
	                                     ProtoCommon.TRACKER_QUERY_STORAGE_STORE_BODY_LEN);
			this.errno = pkgInfo.errno;
			if (pkgInfo.errno != 0)
			{
				return null;
			}
			
			ip_addr = new String(pkgInfo.body, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN, ProtoCommon.FDFS_IPADDR_SIZE-1).trim();
	
			port = (int) ProtoCommon.buff2long(pkgInfo.body, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN
	                        + ProtoCommon.FDFS_IPADDR_SIZE-1);
			store_path = pkgInfo.body[ProtoCommon.TRACKER_QUERY_STORAGE_STORE_BODY_LEN - 1];
			
			return new StorageServer(ip_addr, port, store_path);
		}
		catch(IOException ex)
		{
			if (!bNewConnection)
			{
				try
				{
					trackerServer.close();
				}
				catch(IOException ex1)
				{
					ex1.printStackTrace();
				}
			}
			
			throw ex;
		}
		finally
		{
			if (bNewConnection)
			{
				try
				{
					trackerServer.close();
				}
				catch(IOException ex1)
				{
					ex1.printStackTrace();
				}
			}
		}
	}

	/**
	* query storage servers to upload file
	* @param trackerServer the tracker server
	* @param groupName the group name to upload file to, can be empty
	* @return storage servers, return null if fail
	*/
	public StorageServer[] getStoreStorages(TrackerServer trackerServer, String groupName) throws IOException
	{
		byte[] header;
		String ip_addr;
		int port;
		byte cmd;
		int out_len;
		boolean bNewConnection;
		Socket trackerSocket;
		
		if (trackerServer == null)
		{
			trackerServer = getConnection();
			if (trackerServer == null)
			{
				return null;
			}
			bNewConnection = true;
		}
		else
		{
			bNewConnection = false;
		}

		trackerSocket = trackerServer.getSocket();
		OutputStream out = trackerSocket.getOutputStream();
		
		try
		{
			if (groupName == null || groupName.length() == 0)
			{
				cmd = ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITHOUT_GROUP_ALL;
				out_len = 0;
			}
			else
			{
				cmd = ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITH_GROUP_ALL;
				out_len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;
			}
			header = ProtoCommon.packHeader(cmd, out_len, (byte)0);
			out.write(header);

			if (groupName != null && groupName.length() > 0)
			{
				byte[] bGroupName;
				byte[] bs;
				int group_len;
				
				bs = groupName.getBytes(ClientGlobal.g_charset);
				bGroupName = new byte[ProtoCommon.FDFS_GROUP_NAME_MAX_LEN];
				
				if (bs.length <= ProtoCommon.FDFS_GROUP_NAME_MAX_LEN)
				{
					group_len = bs.length;
				}
				else
				{
					group_len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;
				}
				Arrays.fill(bGroupName, (byte)0);
				System.arraycopy(bs, 0, bGroupName, 0, group_len);
				out.write(bGroupName);
			}
	
			ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(trackerSocket.getInputStream(),
	                                     ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
			this.errno = pkgInfo.errno;
			if (pkgInfo.errno != 0)
			{
				return null;
			}
			
			if (pkgInfo.body.length < ProtoCommon.TRACKER_QUERY_STORAGE_STORE_BODY_LEN)
			{
				this.errno = ProtoCommon.ERR_NO_EINVAL;
				return null;
			}
			
			int ipPortLen = pkgInfo.body.length - (ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + 1);
			final int recordLength = ProtoCommon.FDFS_IPADDR_SIZE - 1 + ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE;
			
			if (ipPortLen % recordLength != 0)
			{
				this.errno = ProtoCommon.ERR_NO_EINVAL;
				return null;
			}
			
			int serverCount = ipPortLen / recordLength;
			if (serverCount > 16)
			{
				this.errno = ProtoCommon.ERR_NO_ENOSPC;
				return null;
			}
			
			StorageServer[] results = new StorageServer[serverCount];
			byte store_path = pkgInfo.body[pkgInfo.body.length - 1];
			int offset = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;
			
			for (int i=0; i decoder = new ProtoStructDecoder();
			return decoder.decode(pkgInfo.body, StructGroupStat.class, StructGroupStat.getFieldsTotalSize());
		}
		catch(IOException ex)
		{
			if (!bNewConnection)
			{
				try
				{
					trackerServer.close();
				}
				catch(IOException ex1)
				{
					ex1.printStackTrace();
				}
			}
			
			throw ex;
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
			this.errno = ProtoCommon.ERR_NO_EINVAL;
			return null;
		}
		finally
		{
			if (bNewConnection)
			{
				try
				{
					trackerServer.close();
				}
				catch(IOException ex1)
				{
					ex1.printStackTrace();
				}
			}
		}
	}

	/**
	* query storage server stat info of the group
	* @param trackerServer the tracker server
	*	@param groupName the group name of storage server
	* @return storage server stat array, return null if fail
	*/
	public StructStorageStat[] listStorages(TrackerServer trackerServer, String groupName) throws IOException
	{
		final String storageIpAddr = null;
		return this.listStorages(trackerServer, groupName, storageIpAddr);
	}
	
	/**
	* query storage server stat info of the group
	* @param trackerServer the tracker server
	*	@param groupName the group name of storage server
	* @param storageIpAddr the storage server ip address, can be null or empty
	* @return storage server stat array, return null if fail
	*/
	public StructStorageStat[] listStorages(TrackerServer trackerServer,
											String groupName, String storageIpAddr) throws IOException
	{
		byte[] header;
		byte[] bGroupName;
		byte[] bs;
		int len;
		boolean bNewConnection;
		Socket trackerSocket;
		
		if (trackerServer == null)
		{
			trackerServer = getConnection();
			if (trackerServer == null)
			{
				return null;
			}
			bNewConnection = true;
		}
		else
		{
			bNewConnection = false;
		}
		trackerSocket = trackerServer.getSocket();
		OutputStream out = trackerSocket.getOutputStream();
		
		try
		{
			bs = groupName.getBytes(ClientGlobal.g_charset);
			bGroupName = new byte[ProtoCommon.FDFS_GROUP_NAME_MAX_LEN];
			
			if (bs.length <= ProtoCommon.FDFS_GROUP_NAME_MAX_LEN)
			{
				len = bs.length;
			}
			else
			{
				len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;
			}
			Arrays.fill(bGroupName, (byte)0);
			System.arraycopy(bs, 0, bGroupName, 0, len);
			
			int ipAddrLen;
			byte[] bIpAddr;
			if (storageIpAddr != null && storageIpAddr.length() > 0)
			{
				bIpAddr = storageIpAddr.getBytes(ClientGlobal.g_charset);
				if (bIpAddr.length < ProtoCommon.FDFS_IPADDR_SIZE)
				{
					ipAddrLen = bIpAddr.length;
				}
				else
				{
					ipAddrLen = ProtoCommon.FDFS_IPADDR_SIZE - 1;
				}
			}
			else
			{
				bIpAddr = null;
				ipAddrLen = 0;
			}
			
			header = ProtoCommon.packHeader(ProtoCommon.TRACKER_PROTO_CMD_SERVER_LIST_STORAGE, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + ipAddrLen, (byte)0);
			byte[] wholePkg = new byte[header.length + bGroupName.length + ipAddrLen];
			System.arraycopy(header, 0, wholePkg, 0, header.length);
			System.arraycopy(bGroupName, 0, wholePkg, header.length, bGroupName.length);
			if (ipAddrLen > 0)
			{
				System.arraycopy(bIpAddr, 0, wholePkg, header.length + bGroupName.length, ipAddrLen);
			}
			out.write(wholePkg);
			
			ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(trackerSocket.getInputStream(),
	                                     ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
			this.errno = pkgInfo.errno;
			if (pkgInfo.errno != 0)
			{
				return null;
			}
			
			ProtoStructDecoder decoder = new ProtoStructDecoder();
			return decoder.decode(pkgInfo.body, StructStorageStat.class, StructStorageStat.getFieldsTotalSize());
		}
		catch(IOException ex)
		{
			if (!bNewConnection)
			{
				try
				{
					trackerServer.close();
				}
				catch(IOException ex1)
				{
					ex1.printStackTrace();
				}
			}
			
			throw ex;
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
			this.errno = ProtoCommon.ERR_NO_EINVAL;
			return null;
		}
		finally
		{
			if (bNewConnection)
			{
				try
				{
					trackerServer.close();
				}
				catch(IOException ex1)
				{
					ex1.printStackTrace();
				}
			}
		}
	}

	/**
	* delete a storage server from the tracker server
	* @param trackerServer the connected tracker server
	*	@param groupName the group name of storage server
	* @param storageIpAddr the storage server ip address
	* @return true for success, false for fail
	*/
	private boolean deleteStorage(TrackerServer trackerServer,
			String groupName, String storageIpAddr) throws IOException
	{
		byte[] header;
		byte[] bGroupName;
		byte[] bs;
		int len;
		Socket trackerSocket;
		
		trackerSocket = trackerServer.getSocket();
		OutputStream out = trackerSocket.getOutputStream();
		
		bs = groupName.getBytes(ClientGlobal.g_charset);
		bGroupName = new byte[ProtoCommon.FDFS_GROUP_NAME_MAX_LEN];
		
		if (bs.length <= ProtoCommon.FDFS_GROUP_NAME_MAX_LEN)
		{
			len = bs.length;
		}
		else
		{
			len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;
		}
		Arrays.fill(bGroupName, (byte)0);
		System.arraycopy(bs, 0, bGroupName, 0, len);
		
		int ipAddrLen;
		byte[] bIpAddr = storageIpAddr.getBytes(ClientGlobal.g_charset);
		if (bIpAddr.length < ProtoCommon.FDFS_IPADDR_SIZE)
		{
			ipAddrLen = bIpAddr.length;
		}
		else
		{
			ipAddrLen = ProtoCommon.FDFS_IPADDR_SIZE - 1;
		}

		header = ProtoCommon.packHeader(ProtoCommon.TRACKER_PROTO_CMD_SERVER_DELETE_STORAGE, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + ipAddrLen, (byte)0);
		byte[] wholePkg = new byte[header.length + bGroupName.length + ipAddrLen];
		System.arraycopy(header, 0, wholePkg, 0, header.length);
		System.arraycopy(bGroupName, 0, wholePkg, header.length, bGroupName.length);
		System.arraycopy(bIpAddr, 0, wholePkg, header.length + bGroupName.length, ipAddrLen);
		out.write(wholePkg);
		
		ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(trackerSocket.getInputStream(),
                                     ProtoCommon.TRACKER_PROTO_CMD_RESP, 0);
		this.errno = pkgInfo.errno;
		return pkgInfo.errno == 0;
	}

	/**
	* delete a storage server from the global FastDFS cluster
	*	@param groupName the group name of storage server
	* @param storageIpAddr the storage server ip address
	* @return true for success, false for fail
	*/
	public boolean deleteStorage(String groupName, String storageIpAddr) throws IOException
	{
		return this.deleteStorage(ClientGlobal.g_tracker_group, groupName, storageIpAddr);
	}
	
	/**
	* delete a storage server from the FastDFS cluster
	* @param trackerGroup the tracker server group
	*	@param groupName the group name of storage server
	* @param storageIpAddr the storage server ip address
	* @return true for success, false for fail
	*/
	public boolean deleteStorage(TrackerGroup trackerGroup,
			String groupName, String storageIpAddr) throws IOException
	{
		int serverIndex;
		int notFoundCount;
		TrackerServer trackerServer;
				
		notFoundCount = 0;
		for (serverIndex=0; serverIndex




© 2015 - 2024 Weber Informatics LLC | Privacy Policy