public class ZooKeeperMetaManager extends AbstractCanalLifeCycle implements CanalMetaManager {
private static final String ENCODE = "UTF-8"; private ZkClientx zkClientx;
public void start() { super.start();
Assert.notNull(zkClientx); }
public void stop() { zkClientx = null; super.stop(); }
public void subscribe(ClientIdentity clientIdentity) throws CanalMetaManagerException { String path = ZookeeperPathUtils.getClientIdNodePath(clientIdentity.getDestination(), clientIdentity.getClientId());
try { zkClientx.createPersistent(path, true); } catch (ZkNodeExistsException e) { } if (clientIdentity.hasFilter()) { String filterPath = ZookeeperPathUtils.getFilterPath(clientIdentity.getDestination(), clientIdentity.getClientId());
byte[] bytes = null; try { bytes = clientIdentity.getFilter().getBytes(ENCODE); } catch (UnsupportedEncodingException e) { throw new CanalMetaManagerException(e); }
try { zkClientx.createPersistent(filterPath, bytes); } catch (ZkNodeExistsException e) { zkClientx.writeData(filterPath, bytes); } } }
public boolean hasSubscribe(ClientIdentity clientIdentity) throws CanalMetaManagerException { String path = ZookeeperPathUtils.getClientIdNodePath(clientIdentity.getDestination(), clientIdentity.getClientId()); return zkClientx.exists(path); }
public void unsubscribe(ClientIdentity clientIdentity) throws CanalMetaManagerException { String path = ZookeeperPathUtils.getClientIdNodePath(clientIdentity.getDestination(), clientIdentity.getClientId()); zkClientx.deleteRecursive(path); }
public List<ClientIdentity> listAllSubscribeInfo(String destination) throws CanalMetaManagerException { if (zkClientx == null) { return new ArrayList<>(); } String path = ZookeeperPathUtils.getDestinationPath(destination); List<String> childs = null; try { childs = zkClientx.getChildren(path); } catch (ZkNoNodeException e) { }
if (CollectionUtils.isEmpty(childs)) { return new ArrayList<>(); } List<Short> clientIds = new ArrayList<>(); for (String child : childs) { if (StringUtils.isNumeric(child)) { clientIds.add(ZookeeperPathUtils.getClientId(child)); } }
Collections.sort(clientIds); List<ClientIdentity> clientIdentities = Lists.newArrayList(); for (Short clientId : clientIds) { path = ZookeeperPathUtils.getFilterPath(destination, clientId); byte[] bytes = zkClientx.readData(path, true); String filter = null; if (bytes != null) { try { filter = new String(bytes, ENCODE); } catch (UnsupportedEncodingException e) { throw new CanalMetaManagerException(e); } } clientIdentities.add(new ClientIdentity(destination, clientId, filter)); }
return clientIdentities; }
public Position getCursor(ClientIdentity clientIdentity) throws CanalMetaManagerException { String path = ZookeeperPathUtils.getCursorPath(clientIdentity.getDestination(), clientIdentity.getClientId());
byte[] data = zkClientx.readData(path, true); if (data == null || data.length == 0) { return null; }
return JsonUtils.unmarshalFromByte(data, Position.class); }
public void updateCursor(ClientIdentity clientIdentity, Position position) throws CanalMetaManagerException { String path = ZookeeperPathUtils.getCursorPath(clientIdentity.getDestination(), clientIdentity.getClientId()); byte[] data = JsonUtils.marshalToByte(position, JSONWriter.Feature.WriteClassName); try { zkClientx.writeData(path, data); } catch (ZkNoNodeException e) { zkClientx.createPersistent(path, data, true); } }
public Long addBatch(ClientIdentity clientIdentity, PositionRange positionRange) throws CanalMetaManagerException { String path = ZookeeperPathUtils.getBatchMarkPath(clientIdentity.getDestination(), clientIdentity.getClientId()); byte[] data = JsonUtils.marshalToByte(positionRange, JSONWriter.Feature.WriteClassName); String batchPath = zkClientx .createPersistentSequential(path + ZookeeperPathUtils.ZOOKEEPER_SEPARATOR, data, true); String batchIdString = StringUtils.substringAfterLast(batchPath, ZookeeperPathUtils.ZOOKEEPER_SEPARATOR); return ZookeeperPathUtils.getBatchMarkId(batchIdString); }
public void addBatch(ClientIdentity clientIdentity, PositionRange positionRange, Long batchId) throws CanalMetaManagerException { String path = ZookeeperPathUtils .getBatchMarkWithIdPath(clientIdentity.getDestination(), clientIdentity.getClientId(), batchId); byte[] data = JsonUtils.marshalToByte(positionRange, JSONWriter.Feature.WriteClassName); zkClientx.createPersistent(path, data, true); }
public PositionRange removeBatch(ClientIdentity clientIdentity, Long batchId) throws CanalMetaManagerException { String batchsPath = ZookeeperPathUtils.getBatchMarkPath(clientIdentity.getDestination(), clientIdentity.getClientId()); List<String> nodes = zkClientx.getChildren(batchsPath); if (CollectionUtils.isEmpty(nodes)) { return null; }
ArrayList<Long> batchIds = new ArrayList<>(nodes.size()); for (String batchIdString : nodes) { batchIds.add(Long.valueOf(batchIdString)); } Long minBatchId = Collections.min(batchIds); if (!minBatchId.equals(batchId)) { throw new CanalMetaManagerException(String.format("batchId:%d is not the firstly:%d", batchId, minBatchId)); }
if (!batchIds.contains(batchId)) { return null; } PositionRange positionRange = getBatch(clientIdentity, batchId); if (positionRange != null) { String path = ZookeeperPathUtils .getBatchMarkWithIdPath(clientIdentity.getDestination(), clientIdentity.getClientId(), batchId); zkClientx.delete(path); }
return positionRange; }
public PositionRange getBatch(ClientIdentity clientIdentity, Long batchId) throws CanalMetaManagerException { String path = ZookeeperPathUtils .getBatchMarkWithIdPath(clientIdentity.getDestination(), clientIdentity.getClientId(), batchId); byte[] data = zkClientx.readData(path, true); if (data == null) { return null; }
PositionRange positionRange = JsonUtils.unmarshalFromByte(data, PositionRange.class); return positionRange; }
public void clearAllBatchs(ClientIdentity clientIdentity) throws CanalMetaManagerException { String path = ZookeeperPathUtils.getBatchMarkPath(clientIdentity.getDestination(), clientIdentity.getClientId()); List<String> batchChilds = zkClientx.getChildren(path);
for (String batchChild : batchChilds) { String batchPath = path + ZookeeperPathUtils.ZOOKEEPER_SEPARATOR + batchChild; zkClientx.delete(batchPath); } }
public PositionRange getLastestBatch(ClientIdentity clientIdentity) { String path = ZookeeperPathUtils.getBatchMarkPath(clientIdentity.getDestination(), clientIdentity.getClientId()); List<String> nodes = null; try { nodes = zkClientx.getChildren(path); } catch (ZkNoNodeException e) { }
if (CollectionUtils.isEmpty(nodes)) { return null; } ArrayList<Long> batchIds = new ArrayList<>(nodes.size()); for (String batchIdString : nodes) { batchIds.add(Long.valueOf(batchIdString)); } Long maxBatchId = Collections.max(batchIds); PositionRange result = getBatch(clientIdentity, maxBatchId); if (result == null) { return getLastestBatch(clientIdentity); } else { return result; } }
public PositionRange getFirstBatch(ClientIdentity clientIdentity) { String path = ZookeeperPathUtils.getBatchMarkPath(clientIdentity.getDestination(), clientIdentity.getClientId()); List<String> nodes = null; try { nodes = zkClientx.getChildren(path); } catch (ZkNoNodeException e) { }
if (CollectionUtils.isEmpty(nodes)) { return null; } ArrayList<Long> batchIds = new ArrayList<>(nodes.size()); for (String batchIdString : nodes) { batchIds.add(Long.valueOf(batchIdString)); } Long minBatchId = Collections.min(batchIds); PositionRange result = getBatch(clientIdentity, minBatchId); if (result == null) { return getFirstBatch(clientIdentity); } else { return result; } }
public Map<Long, PositionRange> listAllBatchs(ClientIdentity clientIdentity) { String path = ZookeeperPathUtils.getBatchMarkPath(clientIdentity.getDestination(), clientIdentity.getClientId()); List<String> nodes = null; try { nodes = zkClientx.getChildren(path); } catch (ZkNoNodeException e) { }
if (CollectionUtils.isEmpty(nodes)) { return Maps.newHashMap(); } ArrayList<Long> batchIds = new ArrayList<>(nodes.size()); for (String batchIdString : nodes) { batchIds.add(Long.valueOf(batchIdString)); }
Collections.sort(batchIds); Map<Long, PositionRange> positionRanges = Maps.newLinkedHashMap(); for (Long batchId : batchIds) { PositionRange result = getBatch(clientIdentity, batchId); if (result == null) { return listAllBatchs(clientIdentity); } else { positionRanges.put(batchId, result); } }
return positionRanges; }
public void setZkClientx(ZkClientx zkClientx) { this.zkClientx = zkClientx; }
}
|