storm源码分析(四)


2021SC@SDUSC
我们接着上一篇继续分析AclEnforcement类。

代码分析

verifyParentWithTopoChildrenDeleteDead()方法

首先该方法传入的参数有:
CuratorFramework zk :zookeeper的客户端框架
ACL superUserAcl:用户权限
String path:路径
Map<String, Id> topoToZkCreds:id
boolean fixUp: 如果要修复则传入的fixUp为true,否的话为false

private static void verifyParentWithTopoChildrenDeleteDead(CuratorFramework zk, ACL superUserAcl, String path,
                                                               Map<String, Id> topoToZkCreds, boolean fixUp,int perms) throws Exception {
        if (zk.checkExists().forPath(path) != null) {
            verifyAclStrict(zk, Arrays.asList(superUserAcl), path, fixUp);
            //可能是坏节点的id的集合
            Set<String> possiblyBadIds = new HashSet<>();
			
			//通过一个for循环来将坏节点的id加入集合中
            for (String topoId : zk.getChildren().forPath(path)) {
                String childPath = path + ClusterUtils.ZK_SEPERATOR + topoId;
                if (!topoToZkCreds.containsKey(topoId)) {
                	//topoToZkCreds中不存在topoId键值
                    possiblyBadIds.add(topoId);
                } else {
                    List<ACL> rwAcl = getTopoAcl(path, topoId, topoToZkCreds, superUserAcl, fixUp, perms);
                    verifyAclStrictRecursive(zk, rwAcl, childPath, fixUp);
                }
            }

1、首先zk.checkExists().forPath(path)判断是否存在该节点。
如果该节点存在,则调用verifyAclStrict()方法,验证该节点的acl权限。
2、通过一个for循环将坏节点的id加入到一个集合中,topoToZkCreds.containsKey(topoId)如果在topoToZkCreds中不存在topoId键值,则将他的id加入集合。存在的话就获取acl权限,然后通过verifyAclStrictRecursive()方法校验acl严格递归。

if (!possiblyBadIds.isEmpty()) {
                //Lets reread the children in STORMS as the source of truth and see if a new one was created in the background
        
                possiblyBadIds.removeAll(zk.getChildren().forPath(ClusterUtils.STORMS_SUBTREE));
                for (String topoId : possiblyBadIds) {
                    //Now we know for sure that this is a bad id
                    String childPath = path + ClusterUtils.ZK_SEPERATOR + topoId;
                    zk.delete().deletingChildrenIfNeeded().forPath(childPath);
                }
            }
        }
    }

3、如果possiblyBadIds集合为空,就重新查看一边子节点,看看是否在背景中创建了一个新的。
4、移除符合zk.getChildren().forPath(ClusterUtils.STORMS_SUBTREE)的子节点的id。通过for循环遍历集合中剩下的id,然后删除childPath路径的节点。

各种校验方法

private static void verifyParentWithTopoChildren(CuratorFramework zk, ACL superUserAcl, String path,
                                                     Map<String, Id> topoToZkCreds, boolean fixUp, int perms) throws Exception {
        if (zk.checkExists().forPath(path) != null) {
            verifyAclStrict(zk, Arrays.asList(superUserAcl), path, fixUp);
            for (String topoId : zk.getChildren().forPath(path)) {
                String childPath = path + ClusterUtils.ZK_SEPERATOR + topoId;
                List<ACL> rwAcl = getTopoAcl(path, topoId, topoToZkCreds, superUserAcl, fixUp, perms);
                verifyAclStrictRecursive(zk, rwAcl, childPath, fixUp);
            }
        }
    }

👆校验有子节点的父节点。

private static void verifyParentWithReadOnlyTopoChildren(CuratorFramework zk, ACL superUserAcl, String path,
                                                             Map<String, Id> topoToZkCreds, boolean fixUp) throws Exception {
        verifyParentWithTopoChildren(zk, superUserAcl, path, topoToZkCreds, fixUp, ZooDefs.Perms.READ);
    }

    private static void verifyParentWithReadWriteTopoChildren(CuratorFramework zk, ACL superUserAcl, String path,
                                                              Map<String, Id> topoToZkCreds, boolean fixUp) throws Exception {
        verifyParentWithTopoChildren(zk, superUserAcl, path, topoToZkCreds, fixUp, ZooDefs.Perms.ALL);
    }

👆校验只读的子节点的父子点。
👆校验有读写的子节点的父节点。

private static void verifyAclStrictRecursive(CuratorFramework zk, List<ACL> strictAcl, String path, boolean fixUp) throws Exception {
        verifyAclStrict(zk, strictAcl, path, fixUp);
        for (String child : zk.getChildren().forPath(path)) {
            String newPath = path + ClusterUtils.ZK_SEPERATOR + child;
            verifyAclStrictRecursive(zk, strictAcl, newPath, fixUp);
        }
    }

👆递归校验acl。

private static void verifyAclStrict(CuratorFramework zk, List<ACL> strictAcl, String path, boolean fixUp) throws Exception {
        try {
            List<ACL> foundAcl = zk.getACL().forPath(path);
            if (!equivalent(foundAcl, strictAcl)) {
                if (fixUp) {
                    LOG.warn("{} expected to have ACL {}, but has {}.  Fixing...", path, strictAcl, foundAcl);
                    zk.setACL().withACL(strictAcl).forPath(path);
                } else {
                    throw new IllegalStateException(path + " did not have the correct ACL found " + foundAcl + " expected " + strictAcl);
                }
            }
        } catch (KeeperException.NoNodeException ne) {
            LOG.debug("{} removed in the middle of checking it", ne);
        }
    }

👆校验acl。

private static boolean equivalent(List<ACL> a, List<ACL> b) {
        if (a.size() == b.size()) {
            for (ACL acl : a) {
                if (!b.contains(acl)) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

👆判断两个acl权限列表是否相等。

到这里AclEnforcement类就结束了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值