com.cloudera.csd.tools.MetricDescriptorGeneratorTool.java Source code

Java tutorial

Introduction

Here is the source code for com.cloudera.csd.tools.MetricDescriptorGeneratorTool.java

Source

// Licensed to Cloudera, Inc. under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  Cloudera, Inc. licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.cloudera.csd.tools;

import com.cloudera.csd.components.JsonMdlParser;
import com.cloudera.csd.descriptors.MetricEntityTypeDescriptor;
import com.cloudera.csd.descriptors.RoleMonitoringDefinitionsDescriptor;
import com.cloudera.csd.descriptors.ServiceMonitoringDefinitionsDescriptor;
import com.cloudera.csd.tools.MetricTools.MetricTool;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.List;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.configuration.MapConfiguration;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MetricDescriptorGeneratorTool implements MetricTool {

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

    @SuppressWarnings({ "AccessStaticViaInstance", "static-access" })
    private static final Option OPT_INPUT_MDL = OptionBuilder.withLongOpt("mdl").withArgName("FILE").hasArg()
            .withDescription("The base monitoring definitions file. This should "
                    + "be partially populated with entity attribute and type information "
                    + "as well as any manually defined metrics. This file should be in"
                    + "ServiceMonitoringDefinitionsDescriptor format. See that class for " + "more information.")
            .isRequired(false).create();

    @SuppressWarnings({ "AccessStaticViaInstance", "static-access" })
    private static final Option OPT_INPUT_FIXTURE = OptionBuilder.withLongOpt("fixture").withArgName("FILE")
            .hasArg()
            .withDescription("The fixture input file. This will be provided as "
                    + "input to the adapter. The format of this file depends on the "
                    + "adapter class used. See the adapter class for more information.")
            .isRequired(false).create();

    @SuppressWarnings({ "AccessStaticViaInstance", "static-access" })
    private static final Option OPT_INPUT_CONVENTIONS = OptionBuilder.withLongOpt("conventions").withArgName("FILE")
            .hasArg()
            .withDescription("The conventions input file. This will be provided "
                    + "as input to the adapter. The conventions file can be used to "
                    + "supply domain specific metric context conventions to the "
                    + "adapter. The format of this file depends on the adapter class "
                    + "used. Se ethe adapter class for more information.")
            .isRequired(false).create();

    @SuppressWarnings({ "AccessStaticViaInstance", "static-access" })
    private static final Option OPT_ADAPTER_CLASS = OptionBuilder.withLongOpt("adapter").withArgName("FORMAT")
            .hasArg()
            .withDescription("The adapter class to use to parse the fixture and "
                    + "produce the metric descriptors. Cloudera Manager " + "supplies the following adapters:\n"
                    + "1) com.cloudera.csd.tools.codahale.CodahaleMetricAdapter")
            .isRequired(false).create();

    @SuppressWarnings({ "AccessStaticViaInstance", "static-access" })
    private static final Option OPT_GENERATE_OUPTUT = OptionBuilder.withLongOpt("output").withArgName("FILE")
            .hasArg().withDescription("The generated metric descriptor output file name. By "
                    + "default service_monitoring_definitions.json will be used.")
            .isRequired(false).create();

    private static final String ADAPTER_CLASS_CONFIG = "adapterClass";
    private static final String DEFAULT_OUTPUT_FILE = "service_monitoring_definitions.json";

    public static void addToolOptions(Options options) {
        options.addOption(OPT_INPUT_MDL);
        options.addOption(OPT_INPUT_FIXTURE);
        options.addOption(OPT_INPUT_CONVENTIONS);
        options.addOption(OPT_ADAPTER_CLASS);
        options.addOption(OPT_GENERATE_OUPTUT);
    }

    @Override
    public void run(CommandLine cmdLine, OutputStream out, OutputStream err) throws Exception {
        Preconditions.checkNotNull(cmdLine);
        Preconditions.checkNotNull(out);
        Preconditions.checkNotNull(err);

        FileInputStream mdlInputStream = null;
        MapConfiguration config = generateAndValidateConfig(cmdLine);
        try {
            mdlInputStream = new FileInputStream(config.getString(OPT_INPUT_MDL.getLongOpt()));
            JsonMdlParser mdlParser = new JsonMdlParser();
            ServiceMonitoringDefinitionsDescriptor mdl = mdlParser.parse(IOUtils.toByteArray(mdlInputStream));
            ServiceMonitoringDefinitionsDescriptorImpl.Builder mdlBuilder = new ServiceMonitoringDefinitionsDescriptorImpl.Builder(
                    mdl);

            MetricFixtureAdapter adapter = newMetricFixtureAdapter(config, out, err);
            adapter.init(config.getString(OPT_INPUT_FIXTURE.getLongOpt()),
                    config.getString(OPT_INPUT_CONVENTIONS.getLongOpt()));

            mdlBuilder.addMetricDefinitions(adapter.getServiceMetrics());

            if (null != mdl.getRoles()) {
                List<RoleMonitoringDefinitionsDescriptor> roles = Lists.newArrayList();
                for (RoleMonitoringDefinitionsDescriptor role : mdl.getRoles()) {
                    RoleMonitoringDefinitionsDescriptorImpl.Builder roleBuilder = new RoleMonitoringDefinitionsDescriptorImpl.Builder(
                            role);
                    roleBuilder.addMetricDefinitions(adapter.getRoleMetrics(role.getName()));
                    roles.add(roleBuilder.build());
                }
                mdlBuilder.setRoles(roles);
            }

            if (null != mdl.getMetricEntityTypeDefinitions()) {
                List<MetricEntityTypeDescriptor> entities = Lists.newArrayList();
                for (MetricEntityTypeDescriptor entity : mdl.getMetricEntityTypeDefinitions()) {
                    MetricEntityTypeDescriptorImpl.Builder entityBuilder = new MetricEntityTypeDescriptorImpl.Builder(
                            entity);
                    entityBuilder.addMetricDefinitions(adapter.getEntityMetrics(entity.getName()));
                    entities.add(entityBuilder.build());
                }
                mdlBuilder.setMetricEntityTypeDescriptor(entities);
            }
            FileUtils.write(new File(config.getString(OPT_GENERATE_OUPTUT.getLongOpt(), DEFAULT_OUTPUT_FILE)),
                    mdlParser.valueAsString(mdlBuilder.build(), true));
        } catch (Exception ex) {
            LOG.error("Could not run MetricGenerator tool.", ex);
            IOUtils.write(ex.getMessage() + "\n", err);
            throw ex;
        } finally {
            IOUtils.closeQuietly(mdlInputStream);
        }
    }

    private MetricFixtureAdapter newMetricFixtureAdapter(MapConfiguration config, OutputStream out,
            OutputStream err) throws IllegalAccessException, InstantiationException {
        Preconditions.checkNotNull(config);
        Preconditions.checkNotNull(out);
        Preconditions.checkNotNull(err);
        // All implementations of the MetricFixtureAdapter must have a no-argument
        // c'tor.
        LOG.info("Instantiating new metric fixture of class " + config.getString(OPT_ADAPTER_CLASS.getLongOpt()));
        Class<?> adapterClass = (Class<?>) config.getProperty(ADAPTER_CLASS_CONFIG);
        Preconditions.checkNotNull(adapterClass);
        return (MetricFixtureAdapter) adapterClass.newInstance();
    }

    private MapConfiguration generateAndValidateConfig(CommandLine cmdLine) throws ParseException {
        Preconditions.checkNotNull(cmdLine);
        MapConfiguration ret = new MapConfiguration(Maps.<String, Object>newHashMap());

        for (Option option : cmdLine.getOptions()) {
            ret.addProperty(option.getLongOpt(), option.getValue());
        }

        if (null == ret.getProperty(OPT_INPUT_MDL.getLongOpt())) {
            throw new ParseException("MetricGeneratorTool missing mdl file " + "location");
        } else {
            String fileName = ret.getString(OPT_INPUT_MDL.getLongOpt());
            File file = new File(fileName);
            if (!file.exists()) {
                throw new ParseException("MDL file '" + fileName + "' does not " + "exist");
            } else if (!file.isFile()) {
                throw new ParseException("MDL file '" + fileName + "' is not a " + "file");
            }
        }

        if (null == ret.getProperty(OPT_INPUT_FIXTURE.getLongOpt())) {
            throw new ParseException("MetricGeneratorTool missing fixture file " + "location");
        } else {
            String fileName = ret.getString(OPT_INPUT_FIXTURE.getLongOpt());
            File file = new File(fileName);
            if (!file.exists()) {
                throw new ParseException("Fixture file '" + fileName + "' does not " + "exist");
            } else if (!file.isFile()) {
                throw new ParseException("Fixture file '" + fileName + "' is not a " + "file");
            }
        }

        if (null != ret.getProperty(OPT_INPUT_CONVENTIONS.getLongOpt())) {
            String fileName = ret.getString(OPT_INPUT_CONVENTIONS.getLongOpt());
            File file = new File(fileName);
            if (!file.exists()) {
                throw new ParseException("Conventions file '" + fileName + "' does " + "not exist");
            } else if (!file.isFile()) {
                throw new ParseException("Conventions file '" + fileName + "' is " + "not a file");
            }
        }

        if (null == ret.getProperty(OPT_ADAPTER_CLASS.getLongOpt())) {
            throw new ParseException("MetricGeneratorTool missing adapter class");
        } else {
            String className = ret.getString(OPT_ADAPTER_CLASS.getLongOpt());
            try {
                Class<?> adapterClass = this.getClass().getClassLoader().loadClass(className);
                if (!MetricFixtureAdapter.class.isAssignableFrom(adapterClass)) {
                    throw new ParseException("Adapter class " + className + "is of the " + "wrong type");
                }
                ret.addProperty(ADAPTER_CLASS_CONFIG, adapterClass);
            } catch (ClassNotFoundException e) {
                throw new ParseException("Unknown metric adapter " + className);
            }
        }
        return ret;
    }

    @Override
    public String getName() {
        return this.getClass().getSimpleName();
    }
}