Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tml/f19886dff9b7ad2e6724b261bc9668ba to your computer and use it in GitHub Desktop.
Save tml/f19886dff9b7ad2e6724b261bc9668ba to your computer and use it in GitHub Desktop.
Oak count node check in script console - use while AEM / Oak is running
  1. Go to http://host:port/system/console/bundles and install these two bundles
  2. Go to http://host/system/console/configMgr/org.apache.sling.jcr.base.internal.LoginAdminWhitelist
  3. Add org.apache.felix.webconsole.plugins.scriptconsole to "Whitelist regexp" and save
  4. After the two bundles fully install then go to http://host:port/system/console/sc
  5. Select "Groovy" as the language
  6. Copy/Paste the contents of countNodes-*.groovy script below which matches your oak version to the script console
  7. Click "Execute"
  8. Don't close the browser, the output is displayed in the console UI

Side note: The scripts below are an adaptation of this script updated to work in the Felix Script console: https://gist.github.com/stillalex/06303f8cc1d3780d3eab4c72575883ae

import java.io.InputStream;
import java.util.concurrent.atomic.AtomicInteger
import org.apache.jackrabbit.oak.api.Type
import org.apache.jackrabbit.oak.plugins.segment.SegmentBlob
import org.apache.jackrabbit.oak.spi.state.NodeState
def countNodes(NodeState n, deep = false, String path = "/", Integer flush = 50000, AtomicInteger count = new AtomicInteger(0), AtomicInteger binaries = new AtomicInteger(0), root = true) {
if(root) {
out.println "Counting nodes in tree ${path}"
}
cnt = count.incrementAndGet()
if (cnt % flush == 0) out.println(" " + cnt)
def propname = "";
try {
try {
for(prop in n.getProperties()) {
propname = prop.getName();
if(prop.getType() == Type.BINARY || prop.getType() == Type.BINARIES) {
for(b in prop.getValue(Type.BINARIES)) {
binaries.incrementAndGet()
if(deep) {
InputStream s = b.getNewStream();
try {
byte[] buffer = new byte[1024];
int l = s.read(buffer, 0, buffer.length);
} finally {
s.close();
}
} else if(b instanceof SegmentBlob) {
if(!((SegmentBlob)b).isExternal()) {
b.length()
}
} else {
b.length()
}
}
} else {
if(prop.isArray()) {
for(sf in prop.getValue(prop.getType())) {
// do nothing - we just need to read all values
}
} else {
prop.getValue(prop.getType());
}
}
}
} catch(ex) {
out.println "warning unable to read node ${path}@" + propname + " : " + ex.getMessage()
}
propname = "";
for(child in n.getChildNodeEntries()) {
countNodes(child.getNodeState(), deep, path + child.getName() + "/", flush, count, binaries, false)
}
} catch(e) {
out.println "warning unable to read node ${path} : " + e.getMessage()
}
if(root) {
out.println "Total nodes in tree ${path}: ${cnt}"
out.println "Total binaries in tree ${path}: ${binaries.get()}"
}
return cnt
}
def countNodes(session) {
def nstore = session.getRootNode().sessionDelegate.root.store
def rs = nstore.root
out.println("Running node counter")
countNodes(rs)
out.println("Done")
null
}
def countNodes() {
def repo = osgi.getService(org.apache.sling.jcr.api.SlingRepository)
def session = repo.loginAdministrative(null)
try {
countNodes(session)
} finally {
session.logout()
}
}
countNodes()
//Adaptation of @stillalex's script from here https://gist.github.com/stillalex/06303f8cc1d3780d3eab4c72575883ae
//This version works with Oak 1.6 and later versions
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicInteger
import org.apache.jackrabbit.oak.api.Type
import org.apache.jackrabbit.oak.spi.state.NodeState
import org.apache.jackrabbit.oak.spi.state.NodeStore
def countNodes(NodeState n, deep = false, String path = "/", Integer flush = 100000, AtomicInteger count = new AtomicInteger(0), AtomicInteger binaries = new AtomicInteger(0), root = true) {
if(root) {
out.println "Counting nodes in tree ${path}"
}
cnt = count.incrementAndGet()
if (cnt % flush == 0) out.println(" " + cnt)
try {
try {
for(prop in n.getProperties()) {
if(prop.getType() == Type.BINARIES) {
for(b in prop.getValue(Type.BINARIES)) {
binaries.incrementAndGet()
if(deep) {
InputStream s = b.getNewStream();
try {
byte[] buffer = new byte[1024];
int l = s.read(buffer, 0, buffer.length);
} finally {
s.close();
}
} else {
b.length();
}
binaries.incrementAndGet();
}
} else if(prop.getType() == Type.BINARY) {
def b = prop.getValue(Type.BINARY);
if(deep) {
InputStream s = b.getNewStream();
try {
byte[] buffer = new byte[1024];
int l = s.read(buffer, 0, buffer.length);
} finally {
s.close();
}
} else {
b.length();
}
binaries.incrementAndGet();
} else {
// Check regular properties for missing segments
if(prop.isArray()) {
for(sf in prop.getValue(prop.getType())) {
// do nothing - we just need to read all values
}
} else {
prop.getValue(prop.getType());
}
}
}
} catch(e) {
out.println "warning unable to read node properties ${path} : " + e.getMessage()
org.codehaus.groovy.runtime.StackTraceUtils.printSanitizedStackTrace(e, out)
}
try {
for(child in n.getChildNodeEntries()) {
try {
countNodes(child.getNodeState(), deep, path + child.getName() + "/", flush, count, binaries, false)
} catch(e) {
out.println "warning unable to read child node ${path} : " + e.getMessage()
org.codehaus.groovy.runtime.StackTraceUtils.printSanitizedStackTrace(e, out)
}
}
} catch(e) {
out.println "warning unable to read child entries ${path} : " + e.getMessage()
org.codehaus.groovy.runtime.StackTraceUtils.printSanitizedStackTrace(e, out)
}
} catch(e) {
out.println "warning unable to read node ${path} : " + e.getMessage()
org.codehaus.groovy.runtime.StackTraceUtils.printSanitizedStackTrace(e, out)
}
if(root) {
out.println "Total nodes in tree ${path}: ${cnt}"
out.println "Total binaries in tree ${path}: ${binaries.get()}"
}
return cnt
}
def countNodes(session) {
NodeStore nstore = session.getRootNode().sessionDelegate.root.store
def rs = nstore.root
def ns = rs
out.println("Running node counter")
countNodes(ns)
out.println("Done")
null
}
def countNodes() {
def repo = osgi.getService(org.apache.sling.jcr.api.SlingRepository)
def session = repo.loginAdministrative(null)
try {
countNodes(session)
} finally {
session.logout()
}
}
countNodes()
//Adaptation of @stillalex's script from here https://gist.github.com/stillalex/06303f8cc1d3780d3eab4c72575883ae
//This version works with Oak 1.6 and later versions
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicInteger
import org.apache.jackrabbit.oak.api.Type
import org.apache.jackrabbit.oak.spi.state.NodeState
import org.apache.jackrabbit.oak.spi.state.NodeStore
def countNodes(n, deep = false, String path = "/", Integer flush = 100000, AtomicInteger count = new AtomicInteger(0), AtomicInteger binaries = new AtomicInteger(0), root = true) {
if(root) {
println "Counting nodes in tree ${path}"
}
cnt = count.incrementAndGet()
if (cnt % flush == 0) println(" " + cnt)
try {
try {
for(prop in n.getProperties()) {
if(prop.getType() == Type.BINARY || prop.getType() == Type.BINARIES) {
for(b in prop.getValue(Type.BINARIES)) {
binaries.incrementAndGet()
if(b instanceof SegmentBlob) {
if(!((SegmentBlob)b).isExternal()) {
b.length()
}
}
}
} else if(prop.getType() == Type.BINARY) {
def b = prop.getValue(Type.BINARY);
binaries.incrementAndGet()
if(b instanceof SegmentBlob) {
if(!((SegmentBlob)b).isExternal()) {
b.length()
}
}
binaries.incrementAndGet();
} else {
// Check regular properties for missing segments
if(prop.isArray()) {
for(sf in prop.getValue(prop.getType())) {
// do nothing - we just need to read all values
}
} else {
prop.getValue(prop.getType());
}
}
}
} catch(e) {
println "warning unable to read node properties ${path} : " + e.getMessage()
org.codehaus.groovy.runtime.StackTraceUtils.printSanitizedStackTrace(e)
}
try {
for(child in n.getChildNodeEntries()) {
try {
countNodes(child.getNodeState(), deep, path + child.getName() + "/", flush, count, binaries, false)
} catch(e) {
println "warning unable to read child node ${path} : " + e.getMessage()
org.codehaus.groovy.runtime.StackTraceUtils.printSanitizedStackTrace(e)
}
}
} catch(e) {
println "warning unable to read child entries ${path} : " + e.getMessage()
org.codehaus.groovy.runtime.StackTraceUtils.printSanitizedStackTrace(e)
}
} catch(e) {
println "warning unable to read node ${path} : " + e.getMessage()
org.codehaus.groovy.runtime.StackTraceUtils.printSanitizedStackTrace(e)
}
if(root) {
println "Total nodes in tree ${path}: ${cnt}"
println "Total binaries in tree ${path}: ${binaries.get()}"
}
return cnt
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment