001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.reef.tang.util; 020 021import org.apache.reef.tang.*; 022import org.apache.reef.tang.annotations.Name; 023import org.apache.reef.tang.annotations.NamedParameter; 024import org.apache.reef.tang.annotations.Parameter; 025import org.apache.reef.tang.exceptions.BindException; 026import org.apache.reef.tang.exceptions.InjectionException; 027import org.apache.reef.tang.formats.AvroConfigurationSerializer; 028import org.apache.reef.tang.formats.CommandLine; 029import org.apache.reef.tang.implementation.InjectionPlan; 030import org.apache.reef.tang.implementation.protobuf.ProtocolBufferClassHierarchy; 031import org.apache.reef.tang.proto.ClassHierarchyProto; 032 033import javax.inject.Inject; 034import java.io.File; 035import java.io.FileInputStream; 036import java.io.IOException; 037import java.io.InputStream; 038 039public class ValidateConfiguration { 040 private final String target; 041 private final File ch; 042 private final File inConfig; 043 private final File outConfig; 044 045 @Inject 046 public ValidateConfiguration( 047 @Parameter(ClassHierarchyIn.class) final File ch, 048 @Parameter(ConfigurationIn.class) final File inConfig, 049 @Parameter(ConfigurationOut.class) final File outConfig) { 050 this.target = null; 051 this.ch = ch; 052 this.inConfig = inConfig; 053 this.outConfig = outConfig; 054 } 055 056 @Inject 057 public ValidateConfiguration( 058 @Parameter(Target.class) final String injectedClass, 059 @Parameter(ClassHierarchyIn.class) final File ch, 060 @Parameter(ConfigurationIn.class) final File inConfig, 061 @Parameter(ConfigurationOut.class) final File outConfig) { 062 this.target = injectedClass; 063 this.ch = ch; 064 this.inConfig = inConfig; 065 this.outConfig = outConfig; 066 } 067 068 public static void main(final String[] argv) throws IOException, BindException, InjectionException { 069 @SuppressWarnings("unchecked") final JavaConfigurationBuilder cb = Tang.Factory.getTang().newConfigurationBuilder( 070 (Class<? extends ExternalConstructor<?>>[]) new Class[]{FileParser.class}); 071 final CommandLine cl = new CommandLine(cb); 072 cl.processCommandLine(argv, 073 Target.class, 074 ClassHierarchyIn.class, 075 ConfigurationIn.class, 076 ConfigurationOut.class); 077 final ValidateConfiguration bip = 078 Tang.Factory.getTang().newInjector(cb.build()).getInstance(ValidateConfiguration.class); 079 bip.validatePlan(); 080 } 081 082 public void validatePlan() throws IOException, BindException, InjectionException { 083 084 final Tang t = Tang.Factory.getTang(); 085 086 // TODO[JIRA REEF-400] Use the AvroClassHierarchySerializer 087 final ClassHierarchyProto.Node root; 088 try (final InputStream chin = new FileInputStream(this.ch)) { 089 root = ClassHierarchyProto.Node.parseFrom(chin); 090 } 091 092 final ClassHierarchy classHierarchy = new ProtocolBufferClassHierarchy(root); 093 094 if (!inConfig.canRead()) { 095 throw new IOException("Cannot read input config file: " + inConfig); 096 } 097 098 final AvroConfigurationSerializer avroSerializer = new AvroConfigurationSerializer(); 099 final Configuration conf = avroSerializer.fromFile(inConfig, classHierarchy); 100 101 if (target != null) { 102 final Injector i = t.newInjector(conf); 103 final InjectionPlan<?> ip = i.getInjectionPlan(target); 104 if (!ip.isInjectable()) { 105 throw new InjectionException(target + " is not injectable: " + ip.toCantInjectString()); 106 } 107 } 108 109 avroSerializer.toFile(conf, outConfig); 110 } 111 112 public static class FileParser implements ExternalConstructor<File> { 113 private final File f; 114 115 @Inject 116 FileParser(final String name) { 117 f = new File(name); 118 } 119 120 @Override 121 public File newInstance() { 122 return f; 123 } 124 125 } 126 127 @NamedParameter(short_name = "class") 128 public class Target implements Name<String> { 129 } 130 131 @NamedParameter(short_name = "ch") 132 public class ClassHierarchyIn implements Name<File> { 133 } 134 135 @NamedParameter(short_name = "in") 136 public class ConfigurationIn implements Name<File> { 137 } 138 139 @NamedParameter(short_name = "out") 140 public class ConfigurationOut implements Name<File> { 141 } 142}