1 package org.admln.program.Zoo_Test; 2 3 import java.io.IOException; 4 import java.security.NoSuchAlgorithmException; 5 import java.util.ArrayList; 6 import java.util.List; 7 8 import org.apache.zookeeper.CreateMode; 9 import org.apache.zookeeper.WatchedEvent; 10 import org.apache.zookeeper.Watcher; 11 import org.apache.zookeeper.ZooDefs; 12 import org.apache.zookeeper.ZooDefs.Ids; 13 import org.apache.zookeeper.ZooKeeper; 14 import org.apache.zookeeper.data.ACL; 15 import org.apache.zookeeper.data.Id; 16 import org.apache.zookeeper.data.Stat; 17 import org.apache.zookeeper.server.auth.DigestAuthenticationProvider; 18 import org.junit.After; 19 import org.junit.Assert; 20 import org.junit.Before; 21 import org.junit.Test; 22 import org.slf4j.Logger; 23 import org.slf4j.LoggerFactory; 24 25 26 /** 27 * Test Method {create/exists/delete/getChildren/setData/getData/addAuthInfo/setACL/getACL} 28 * 29 * @author admln 30 * @date 2015年5月12日 上午9:35:48 31 */ 32 public class ZooJavaApi { 33 34 private static final int SESSION_TIMEOUT = 1000; 35 36 public static final Logger LOGGER = LoggerFactory.getLogger(ZooJavaApi.class); 37 38 public static final String HOST = "localhost:2181"; 39 40 private Watcher watcher = new Watcher() { 41 public void process(WatchedEvent we) { 42 LOGGER.info("process:" + we.getType()); 43 } 44 }; 45 46 private ZooKeeper zookeeper; 47 48 /* 49 * 開啟服務器連接 50 */ 51 @Before 52 public void connect() throws IOException { 53 zookeeper = new ZooKeeper(HOST, SESSION_TIMEOUT, watcher); 54 } 55 56 /* 57 * 關閉服務器連接 58 */ 59 @After 60 public void close() { 61 try { 62 zookeeper.close(); 63 } catch (InterruptedException e) { 64 e.printStackTrace(); 65 } 66 } 67 68 /* 69 * 測試創建節點方法; 70 * 調用zookeeper的 String create(final String path, byte data[], List<ACL> acl,CreateMode createMode)方法; 71 * path 創建節點名; 72 * data[] 節點的數據信息,字節數組類型; 73 * acl 訪問權限,List數組類型; 74 * createMode 節點持久化類型; 75 * Assert.fail() 方法加在期望中不可能到達的地方,一旦到達,表明測試失敗,結果與預期不同 76 */ 77 @Test 78 public void testCreate() { 79 String createNode = "/zk001"; 80 String createNodeData = "zk001Data"; 81 String result = null; 82 try { 83 result = zookeeper.create(createNode, createNodeData.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); 84 } catch (Exception e) { 85 LOGGER.error(e.getMessage()); 86 e.printStackTrace(); 87 Assert.fail(); 88 } 89 System.out.println("成功創建了NODE:" + result); 90 } 91 92 /* 93 * 測試刪除節點方法; 94 * 調用zookeeper的delete(final String path, int version)方法; 95 * path 節點名; 96 * version 節點版本; 97 * 版本為 -1 的話匹配所有版本 98 */ 99 @Test 100 public void testDelete() { 101 String deleteNode = "/zk001"; 102 try { 103 zookeeper.delete(deleteNode, -1); 104 } catch (Exception e) { 105 LOGGER.error(e.getMessage()); 106 e.printStackTrace(); 107 Assert.fail(); 108 } 109 System.out.println("成功刪除節點:" + deleteNode); 110 } 111 112 /* 113 * 測試獲取節點數據方法; 114 * 調用zookeeper的getData(final String path, Watcher watcher, Stat stat)方法; 115 * path 節點名稱; 116 * watcher 獲取節點信息時設置Watcher; 117 * stat 數據的版本等信息可以通過 stat 來指定; 118 */ 119 @Test 120 public void testGetData() { 121 String getDataNode = "/zk001"; 122 String result = null; 123 try { 124 byte[] bytes = zookeeper.getData(getDataNode, null, null); 125 result = new String(bytes); 126 } catch (Exception e) { 127 LOGGER.error(e.getMessage()); 128 e.printStackTrace(); 129 Assert.fail(); 130 } 131 System.out.println("獲取節點數據:" + result); 132 } 133 134 /* 135 * 測試設置節點數據方法; 136 * 調用zookeeper的setData(final String path, byte data[], int version)方法 137 * path 節點名稱; 138 * data[] 節點數據; 139 * version 節點版本; 140 * 版本設為-1則匹配所有版本; 141 * 返回 Stat 類型實例,通過Stat可以獲取節點各種信息,例如版本 142 */ 143 @Test 144 public void testSetData() { 145 String setDataNode = "/zk001"; 146 String setNodeData = "/zk001DataSetTest"; 147 Stat tempStat = null; 148 try { 149 tempStat = zookeeper.setData(setDataNode, setNodeData.getBytes(), -1); 150 151 } catch (Exception e) { 152 LOGGER.error(e.getMessage()); 153 e.printStackTrace(); 154 Assert.fail(); 155 } 156 System.out.println("成功設置數據:" + setNodeData + "; 設置后的版本為:" + tempStat.getVersion()); 157 } 158 159 /* 160 * 測試判斷節點是否存在方法; 161 * 調用zookeeper的exists(String path, boolean watch)方法; 162 * path 節點名; 163 * watch 是否監聽; 164 * 返回Stat類型的實例,可以獲取各種信息; 165 */ 166 @Test 167 public void testExists() { 168 String existsNode = "/zk001"; 169 Stat tempStat = null; 170 try { 171 tempStat = zookeeper.exists(existsNode, false); 172 } catch (Exception e) { 173 LOGGER.error(e.getMessage()); 174 e.printStackTrace(); 175 Assert.fail(); 176 } 177 System.out.println(tempStat.getCzxid() == 0 ? "節點是否存在:否":"節點是否存在:是"); 178 } 179 180 /* 181 * 測試獲取子節點方法; 182 * 調用zookeeper的getChildren(String path, boolean watch)方法; 183 * path 節點名稱; 184 * watch 是否設置監聽; 185 * 返回值為一個String類型的List; 186 */ 187 @Test 188 public void testGetChildren() { 189 String parentNode = "/zk001"; 190 List<String> list = null; 191 try { 192 list = zookeeper.getChildren(parentNode, false); 193 } catch (Exception e) { 194 LOGGER.error(e.getMessage()); 195 e.printStackTrace(); 196 Assert.fail(); 197 } 198 if(list.isEmpty()) { 199 System.out.println(parentNode + "無子節點"); 200 }else { 201 System.out.print(parentNode + "的子節點有:"); 202 for(String str : list) { 203 System.out.print(" " + str); 204 } 205 } 206 } 207 208 /* 209 * 測試設置節點訪問權限方法; 210 * 調用zookeeper的setACL(final String path, List<ACL> acl, int version)方法; 211 * path 節點名稱; 212 * acl 設置的權限信息; 213 * version 設置權限的版本; 214 * 返回Stat類型的屍體,可以查看節點信息; 215 */ 216 @Test 217 public void testSetAcl() { 218 String aclNode = "/zk001/zk002"; 219 String scheme = "digest"; 220 String authInfo = "admln:admln"; 221 List<ACL> acls = new ArrayList<ACL>(); 222 try { 223 Id id1 = new Id(scheme,DigestAuthenticationProvider.generateDigest(authInfo)); 224 ACL acl1 = new ACL(ZooDefs.Perms.ALL, id1); 225 acls.add(acl1); 226 Id id2 = new Id(scheme,DigestAuthenticationProvider.generateDigest("guest:guest")); 227 ACL acl2 = new ACL(ZooDefs.Perms.READ, id2); 228 acls.add(acl2); 229 } catch (NoSuchAlgorithmException e) { 230 e.printStackTrace(); 231 } 232 try { 233 zookeeper.setACL(aclNode, acls, -1); 234 } catch (Exception e) { 235 LOGGER.error(e.getMessage()); 236 e.printStackTrace(); 237 Assert.fail(); 238 } 239 System.out.println("成功為" + aclNode + "添加了ACL,scheme為:" + scheme + ",驗證信息為:" + authInfo); 240 } 241 242 /* 243 * 測試獲取節點權限信息方法; 244 * 調用zookeeper的getACL(final String path, Stat stat)方法; 245 * path 節點名稱; 246 * stat 節點狀態信息; 247 * 返回一個ACL列表; 248 */ 249 @Test 250 public void testGetAcl() { 251 String getAclNode = "/zk001/zk002"; 252 List<ACL> list = null; 253 try { 254 list = zookeeper.getACL(getAclNode, new Stat()); 255 } catch (Exception e) { 256 LOGGER.error(e.getMessage()); 257 e.printStackTrace(); 258 Assert.fail(); 259 } 260 if(list.isEmpty()) { 261 System.out.println(getAclNode + " 沒有ACL權限設置"); 262 }else { 263 System.out.println(getAclNode + " 的ACL權限信息: "); 264 for(ACL acl : list) { 265 System.out.print("\t" + acl.toString()); 266 } 267 } 268 } 269 /* 270 * 測試權限驗證方法; 271 * 調用zookeeper的addAuthInfo(String scheme, byte auth[])方法; 272 * scheme 權限類型; 273 * auth[] 權限信息; 274 */ 275 @Test 276 public void testAddAuthInfo() { 277 String addAuthInfoNode = "/zk001/zk002"; 278 String scheme = "digest"; 279 String authInfo = "admln:admln"; 280 String result = null; 281 try { 282 byte[] bytes = zookeeper.getData(addAuthInfoNode, null, null); 283 result = new String(bytes); 284 } catch (Exception e) { 285 System.out.println("沒有提供驗證信息前獲取節點信息:" + result + " ,返回錯誤信息:" + e.getMessage()); 286 } 287 zookeeper.addAuthInfo(scheme, authInfo.getBytes()); 288 try { 289 byte[] bytes = zookeeper.getData(addAuthInfoNode, null, null); 290 result = new String(bytes); 291 } catch (Exception e) { 292 System.out.println("沒有提供驗證信息前獲取節點信息:" + result + " ,返回錯誤信息:" + e.getMessage()); 293 } 294 System.out.println("提供驗證信息后獲取節點信息:" + result); 295 } 296 }
方法簡介:
String create(String path, byte[] data, List<ACL> acl,CreateMode createMode) | 創建一個給定的目錄節點 path, 並給它設置數據,CreateMode 標識有四種形式的目錄節點,分別是 PERSISTENT:持久化目錄節點,這個目錄節點存儲的數據不會丟失;PERSISTENT_SEQUENTIAL:順序自動編號的目錄節點,這種目錄節點會根據當前已近存在的節點數自動加 1,然后返回給客戶端已經成功創建的目錄節點名;EPHEMERAL:臨時目錄節點,一旦創建這個節點的客戶端與服務器端口也就是 session 超時,這種節點會被自動刪除;EPHEMERAL_SEQUENTIAL:臨時自動編號節點 |
Stat exists(String path, boolean watch) | 判斷某個 path 是否存在,並設置是否監控這個目錄節點,這里的 watcher 是在創建 ZooKeeper 實例時指定的 watcher,exists方法還有一個重載方法,可以指定特定的watcher |
Stat exists(String path,Watcher watcher) | 重載方法,這里給某個目錄節點設置特定的 watcher,Watcher 在 ZooKeeper 是一個核心功能,Watcher 可以監控目錄節點的數據變化以及子目錄的變化,一旦這些狀態發生變化,服務器就會通知所有設置在這個目錄節點上的 Watcher,從而每個客戶端都很快知道它所關注的目錄節點的狀態發生變化,而做出相應的反應 |
void delete(String path, int version) | 刪除 path 對應的目錄節點,version 為 -1 可以匹配任何版本,也就刪除了這個目錄節點所有數據 |
List<String>getChildren(String path, boolean watch) | 獲取指定 path 下的所有子目錄節點,同樣 getChildren方法也有一個重載方法可以設置特定的 watcher 監控子節點的狀態 |
Stat setData(String path, byte[] data, int version) | 給 path 設置數據,可以指定這個數據的版本號,如果 version 為 -1 怎可以匹配任何版本 |
byte[] getData(String path, boolean watch, Stat stat) | 獲取這個 path 對應的目錄節點存儲的數據,數據的版本等信息可以通過 stat 來指定,同時還可以設置是否監控這個目錄節點數據的狀態 |
voidaddAuthInfo(String scheme, byte[] auth) | 客戶端將自己的授權信息提交給服務器,服務器將根據這個授權信息驗證客戶端的訪問權限。 |
Stat setACL(String path,List<ACL> acl, int version) | 給某個目錄節點重新設置訪問權限,需要注意的是 Zookeeper 中的目錄節點權限不具有傳遞性,父目錄節點的權限不能傳遞給子目錄節點。目錄節點 ACL 由兩部分組成:perms 和 id。 Perms 有 ALL、READ、WRITE、CREATE、DELETE、ADMIN 幾種 而 id 標識了訪問目錄節點的身份列表,默認情況下有以下兩種: ANYONE_ID_UNSAFE = new Id("world", "anyone") 和 AUTH_IDS = new Id("auth", "") 分別表示任何人都可以訪問和創建者擁有訪問權限。 |
List<ACL>getACL(String path,Stat stat) | 獲取某個目錄節點的訪問權限列表 |
部分內容參考自:
http://www.cnblogs.com/ggjucheng/p/3370359.html
http://jm-blog.aliapp.com/?p=947