From a3d5ee30429d6d87f83fb381735566e3e666bcf7 Mon Sep 17 00:00:00 2001 From: Patrick Dowler Date: Mon, 24 Jun 2024 09:36:26 -0700 Subject: [PATCH] vault: lazy init of root node allows NodePersistenceImpl to recover if AAI is down at startup --- vault/VERSION | 2 +- .../opencadc/vault/NodePersistenceImpl.java | 103 ++++++++++-------- 2 files changed, 61 insertions(+), 44 deletions(-) diff --git a/vault/VERSION b/vault/VERSION index f7f13882..6423351a 100644 --- a/vault/VERSION +++ b/vault/VERSION @@ -4,6 +4,6 @@ # tags with and without build number so operators use the versioned # tag but we always keep a timestamped tag in case a semantic tag gets # replaced accidentally -VER=1.0.6 +VER=1.0.7 TAGS="${VER} ${VER}-$(date -u +"%Y%m%dT%H%M%S")" unset VER diff --git a/vault/src/main/java/org/opencadc/vault/NodePersistenceImpl.java b/vault/src/main/java/org/opencadc/vault/NodePersistenceImpl.java index e680f699..e6d3d7f6 100644 --- a/vault/src/main/java/org/opencadc/vault/NodePersistenceImpl.java +++ b/vault/src/main/java/org/opencadc/vault/NodePersistenceImpl.java @@ -161,7 +161,7 @@ public class NodePersistenceImpl implements NodePersistence { private final Map kpDaoConfig; private final boolean singlePool; - private final ContainerNode root; + private ContainerNode root; private final List allocationParents = new ArrayList<>(); private final Namespace storageNamespace; @@ -187,52 +187,13 @@ public NodePersistenceImpl(URI resourceID, String appName) { this.invDaoConfig = VaultInitAction.getInvConfig(config); this.kpDaoConfig = VaultInitAction.getKeyPairConfig(config); this.singlePool = nodeDaoConfig.get("jndiDataSourceName").equals(invDaoConfig.get("jndiDataSourceName")); + this.localGroupsOnly = false; - // root node - IdentityManager identityManager = AuthenticationUtil.getIdentityManager(); - UUID rootID = new UUID(0L, 0L); - this.root = new ContainerNode(rootID, ""); - root.owner = getRootOwner(config, identityManager); - root.ownerDisplay = identityManager.toDisplayString(root.owner); - log.info("ROOT owner: " + root.owner); - root.ownerID = identityManager.toOwner(root.owner); - root.isPublic = true; - root.inheritPermissions = false; - - // allocations - for (String ap : VaultInitAction.getAllocationParents(config)) { - if (ap.isEmpty()) { - // allocations are in root - allocationParents.add(root); - log.info("allocationParent: /"); - } else { - try { - - // simple top-level names only - ContainerNode cn = (ContainerNode) get(root, ap); - String str = ""; - if (cn == null) { - cn = new ContainerNode(ap); - cn.parent = root; - str = "created/"; - } - cn.isPublic = true; - cn.owner = root.owner; - cn.inheritPermissions = false; - put(cn); - allocationParents.add(cn); - log.info(str + "loaded allocationParent: /" + cn.getName()); - } catch (NodeNotSupportedException bug) { - throw new RuntimeException("BUG: failed to update isPublic=true on allocationParent " + ap, bug); - } - } - } + initRootNode(); String ns = config.getFirstPropertyValue(VaultInitAction.STORAGE_NAMESPACE_KEY); this.storageNamespace = new Namespace(ns); - - this.localGroupsOnly = false; - + String pnf = config.getFirstPropertyValue(VaultInitAction.PREVENT_NOT_FOUND_KEY); if (pnf != null) { this.preventNotFound = Boolean.valueOf(pnf); @@ -252,6 +213,61 @@ private Subject getRootOwner(MultiValuedProperties mvp, IdentityManager im) { return im.augment(ret); } + private void initRootNode() { + if (root != null) { + return; + } + try { + MultiValuedProperties config = VaultInitAction.getConfig(); + IdentityManager identityManager = AuthenticationUtil.getIdentityManager(); + UUID rootID = new UUID(0L, 0L); + ContainerNode rn = new ContainerNode(rootID, ""); + rn.owner = getRootOwner(config, identityManager); + rn.ownerDisplay = identityManager.toDisplayString(rn.owner); + log.info("ROOT owner: " + rn.owner); + rn.ownerID = identityManager.toOwner(rn.owner); + rn.isPublic = true; + rn.inheritPermissions = false; + + // allocations + List aps = new ArrayList<>(); + for (String ap : VaultInitAction.getAllocationParents(config)) { + if (ap.isEmpty()) { + // allocations are in root + aps.add(root); + log.info("allocationParent: /"); + } else { + try { + + // simple top-level names only + ContainerNode cn = (ContainerNode) get(root, ap); + String str = ""; + if (cn == null) { + cn = new ContainerNode(ap); + cn.parent = root; + cn.isPublic = true; + cn.inheritPermissions = false; + cn.owner = root.owner; + str = "created/"; + put(cn); + } + aps.add(cn); + log.info(str + "loaded allocationParent: /" + cn.getName()); + } catch (NodeNotSupportedException bug) { + throw new RuntimeException("BUG: failed to update isPublic=true on allocationParent " + ap, bug); + } + } + } + + // success + this.root = rn; + this.allocationParents.addAll(aps); + } catch (Exception ex) { + log.error("failed to init ROOT ContainerNode", ex); + + } + } + @Override public Views getViews() { return new Views(); @@ -298,6 +314,7 @@ public URI getResourceID() { */ @Override public ContainerNode getRootNode() { + initRootNode(); return root; }