package org.snmp4j.agent.tutorial.impl; import org.snmp4j.agent.mo.*; import org.snmp4j.agent.tutorial.Snmp4jAgentTutorialMib; import org.snmp4j.smi.OID; import org.snmp4j.smi.OctetString; import org.snmp4j.smi.Variable; import java.io.File; import java.io.IOException; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.*; /** * The {@link Snmp4JAgentTutorialFileTreeBUModel} implements a virtual table instrumentation * using the SNMP4J-AgentX {@link BufferedMOTableModel}. * * @author Frank Fock */ public class Snmp4JAgentTutorialFileTreeBUModel extends BufferedMOMutableTableModel { private MOScalar rootPathScalar; public Snmp4JAgentTutorialFileTreeBUModel(OID tableOID, MOTableIndex indexDef, MOColumn[] columns) { super(null); maxBufferSize = 1000; this.rootPathScalar = rootPathScalar; } public void setRootPathScalar(MOScalar rootPathScalar) { this.rootPathScalar = rootPathScalar; } protected File getRootDir() { if (rootPathScalar != null) { return new File(rootPathScalar.getValue().toString()); } return new File("."); } @Override public int getRowCount() { Path root = getRootDir().toPath(); try { long count = Files.walk(root).count(); return (int)count; } catch (IOException iox) { iox.printStackTrace(); } return 1; } @Override public boolean isEmpty() { return false; } @Override public boolean containsRow(OID oid) { return (fetchRow(oid) != null); } @Override public OID lastIndex() { return getLastFileIndexInDepthFirstOrder(getRootDir(), new OID("1")); } @Override public OID firstIndex() { return new OID("1"); } @Override protected Variable[] fetchRow(OID oid) { File f = getFileForOID(getRootDir(), oid); if (f == null) { return null; } try { return Snmp4JAgentTutorialFileTreeRowHelper.createRowFromFile(f); } catch (IOException e) { e.printStackTrace(); return null; } } @Override protected List fetchNextRows(OID oid, int chunkSize) { File startFile = getRootDir(); try { final OID index = new OID("1"); final List rows = new ArrayList<>(chunkSize); SimpleFileVisitor visitor = new SimpleFileVisitor() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { index.append(1); if (index.compareTo(oid) > 0) { rows.add(createRow(new OID(index), Snmp4JAgentTutorialFileTreeRowHelper.createRowFromPath(dir))); } if (rows.size() >= chunkSize) { return FileVisitResult.TERMINATE; } return super.preVisitDirectory(dir, attrs); } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { index.set(index.size()-1, index.last()+1); if (index.compareTo(oid) > 0) { rows.add(createRow(new OID(index), Snmp4JAgentTutorialFileTreeRowHelper.createRowFromPath(file))); } if (rows.size() >= chunkSize) { return FileVisitResult.TERMINATE; } return super.visitFile(file, attrs); } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { index.trim(1); return super.postVisitDirectory(dir, exc); } }; Files.walkFileTree(startFile.toPath(), visitor); return rows; } catch (IOException e) { e.printStackTrace(); } return null; } private OID getLastFileIndexInDepthFirstOrder(File rootDir, OID rootOID) { if (rootDir.isDirectory()) { File[] files = rootDir.listFiles(); if (files != null && files.length > 0) { return getLastFileIndexInDepthFirstOrder(files[files.length - 1], new OID(rootOID.getValue(), files.length - 1)); } } return rootOID; } private File getFileForOID(File rootDir, OID fileIndex) { if (fileIndex.size() == 0 || fileIndex.equals(firstIndex()) || (fileIndex.size() > 0 && fileIndex.get(1) == 0)) { return rootDir; } OID remainingIndex = new OID(fileIndex.getValue(), 1, fileIndex.size()-1); if (remainingIndex.size() > 0 && rootDir.isDirectory()) { // TODO: 20.06.2016 Use Files.walk to read only those files until index (might be faster)? File[] files = rootDir.listFiles(); if (files != null && files.length > remainingIndex.get(0)) { return getFileForOID(files[remainingIndex.get(0)-1], remainingIndex); } } return rootDir; } @Override protected void deleteAllRows() { } @Override protected void bulkDeleteRows(List indexList) { } @Override protected void insertRow(OID index, Variable[] values) { } @Override protected void writeRow(OID index, Variable[] values) { } @Override protected void deleteRow(OID index) { } @Override public Snmp4jAgentTutorialMib.Snmp4jAgentTutorialFileTreeBUEntryRow createRow(OID oid, Variable[] variables) throws UnsupportedOperationException { return rowFactory.createRow(oid, variables); } @Override public void freeRow(Snmp4jAgentTutorialMib.Snmp4jAgentTutorialFileTreeBUEntryRow snmp4jAgentTutorialFileTreeBUEntryRow) { } }