org.opennms.netmgt.dao.support.FilesystemResourceStorageDao.java Source code

Java tutorial

Introduction

Here is the source code for org.opennms.netmgt.dao.support.FilesystemResourceStorageDao.java

Source

/*******************************************************************************
 * This file is part of OpenNMS(R).
 *
 * Copyright (C) 2007-2015 The OpenNMS Group, Inc.
 * OpenNMS(R) is Copyright (C) 1999-2015 The OpenNMS Group, Inc.
 *
 * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
 *
 * OpenNMS(R) is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * OpenNMS(R) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with OpenNMS(R).  If not, see:
 *      http://www.gnu.org/licenses/
 *
 * For more information contact:
 *     OpenNMS(R) Licensing <license@opennms.org>
 *     http://www.opennms.org/
 *     http://www.opennms.com/
 *******************************************************************************/

package org.opennms.netmgt.dao.support;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.io.FileUtils;
import org.opennms.core.spring.BeanUtils;
import org.opennms.netmgt.dao.api.ResourceStorageDao;
import org.opennms.netmgt.model.OnmsAttribute;
import org.opennms.netmgt.model.ResourcePath;
import org.opennms.netmgt.rrd.RrdStrategy;
import org.opennms.netmgt.rrd.RrdMetaDataUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.collect.Maps;

/**
 * Used in conjunction with RRD/JRB strategies that persist
 * metrics to the local disk.
 *
 * @author jwhite
 */
public class FilesystemResourceStorageDao implements ResourceStorageDao, InitializingBean {

    private static final Logger LOG = LoggerFactory.getLogger(FilesystemResourceStorageDao.class);

    @Autowired
    private RrdStrategy<?, ?> m_rrdStrategy;

    private static String RRD_EXTENSION = null;

    private File m_rrdDirectory;

    @Override
    public void afterPropertiesSet() throws Exception {
        BeanUtils.assertAutowiring(this);
        setRrdExtension(m_rrdStrategy.getDefaultFileExtension());
    }

    @Override
    public boolean exists(ResourcePath path, int depth) {
        Preconditions.checkArgument(depth >= 0, "depth must be non-negative");
        return exists(toFile(path).toPath(), depth);
    }

    @Override
    public boolean existsWithin(ResourcePath path, int depth) {
        Preconditions.checkArgument(depth >= 0, "depth must be non-negative");
        return existsWithin(toFile(path).toPath(), depth);
    }

    @Override
    public Set<ResourcePath> children(ResourcePath path, int depth) {
        Preconditions.checkArgument(depth > 0, "depth must be positive");
        final File root = toFile(path);
        if (!root.isDirectory()) {
            return Collections.emptySet();
        }

        try (Stream<Path> stream = Files.list(root.toPath())) {
            return stream.filter(p -> p.toFile().isDirectory()) // filter for directories
                    .filter(p -> exists(p, depth - 1)) // filter for folders with metrics
                    .map(p -> ResourcePath.get(path, p.toFile().getName())).collect(Collectors.toSet());
        } catch (IOException e) {
            LOG.error("Failed to list {}. Returning empty set of children.", path, e);
            return Collections.emptySet();
        }
    }

    @Override
    public Set<OnmsAttribute> getAttributes(ResourcePath path) {
        return RrdResourceAttributeUtils.getAttributesAtRelativePath(m_rrdDirectory, toRelativePath(path),
                RRD_EXTENSION);
    }

    @Override
    public void setStringAttribute(ResourcePath path, String key, String value) {
        try {
            RrdResourceAttributeUtils.updateStringProperty(toFile(path), value, key);
        } catch (IOException e) {
            throw Throwables.propagate(e);
        }
    }

    @Override
    public String getStringAttribute(ResourcePath path, String key) {
        return RrdResourceAttributeUtils.getStringProperty(toFile(path), key);
    }

    @Override
    public Map<String, String> getStringAttributes(ResourcePath path) {
        Properties props = RrdResourceAttributeUtils.getStringProperties(m_rrdDirectory, toRelativePath(path));
        return Maps.fromProperties(props);
    }

    @Override
    public void updateMetricToResourceMappings(ResourcePath path, Map<String, String> metricsNameToResourceNames) {
        RrdResourceAttributeUtils.updateDsProperties(toFile(path), metricsNameToResourceNames);
    }

    @Override
    public Map<String, String> getMetaData(ResourcePath path) {
        return RrdMetaDataUtils.readMetaDataFile(getRrdDirectory(), toRelativePath(path));
    }

    @Override
    public boolean delete(ResourcePath path) {
        return FileUtils.deleteQuietly(toFile(path));
    }

    private boolean exists(Path root, int depth) {
        if (!root.toFile().isDirectory()) {
            return false;
        }

        try (Stream<Path> stream = Files.list(root)) {
            if (depth == 0) {
                return stream.anyMatch(isRrdFile);
            } else {
                return stream.anyMatch(p -> exists(p, depth - 1));
            }
        } catch (IOException e) {
            LOG.error("Failed to list {}. Marking path as non-existent.", root, e);
            return false;
        }
    }

    private boolean existsWithin(Path root, int depth) {
        if (depth < 0 || !root.toFile().isDirectory()) {
            return false;
        }

        try (Stream<Path> stream = Files.list(root)) {
            return stream.anyMatch(p -> (isRrdFile.test(p) || existsWithin(p, depth - 1)));
        } catch (IOException e) {
            LOG.error("Failed to list {}. Marking path as non-existent.", root, e);
            return false;
        }
    }

    private File toFile(ResourcePath path) {
        return Paths.get(m_rrdDirectory.getAbsolutePath(), path.elements()).toFile();
    }

    private String toRelativePath(ResourcePath path) {
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (final String el : path) {
            if (!first) {
                sb.append(File.separator);
            } else {
                first = false;
            }
            sb.append(el);
        }
        return sb.toString();
    }

    public void setRrdDirectory(File rrdDirectory) {
        m_rrdDirectory = rrdDirectory;
    }

    public File getRrdDirectory() {
        return m_rrdDirectory;
    }

    public void setRrdStrategy(RrdStrategy<?, ?> rrdStrategy) {
        m_rrdStrategy = rrdStrategy;
        setRrdExtension(m_rrdStrategy.getDefaultFileExtension());
    }

    public void setRrdExtension(String rrdExtension) {
        RRD_EXTENSION = rrdExtension;
    }

    private static Predicate<Path> isRrdFile = new Predicate<Path>() {
        @Override
        public boolean test(Path path) {
            final File file = path.toFile();
            return file.isFile() && file.getName().endsWith(RRD_EXTENSION);
        }
    };
}