Alon Bar-Lev has posted comments on this change.

Change subject: extensions test tool: logger
......................................................................


Patch Set 4:

(41 comments)

https://gerrit.ovirt.org/#/c/37886/4/Makefile
File Makefile:

Line 33: BUILD_UT=0
Line 34: EXTRA_BUILD_FLAGS=
Line 35: BUILD_VALIDATION=0
Line 36: BUILD_ENV_VALIDATION=0
Line 37: BUILD_JAVA_OPTS_MAVEN?=-XX:MaxPermSize=1024M
you should not change this while you work... you can just write make XXX=0
Line 38: BUILD_JAVA_OPTS_GWT?=
Line 39: DEV_REBUILD=1
Line 40: DEV_BUILD_GWT_DRAFT=0
Line 41: DEV_EXTRA_BUILD_FLAGS=


https://gerrit.ovirt.org/#/c/37886/4/backend/manager/extension-tool/backend/manager/extension-tool/src/main/modules/org/ovirt/engine/core/extension-tool/main/module.xml
File 
backend/manager/extension-tool/backend/manager/extension-tool/src/main/modules/org/ovirt/engine/core/extension-tool/main/module.xml:

Line 9:   <dependencies>
Line 10:     <module name="org.apache.commons.lang" />
Line 11:     <module name="org.ovirt.engine.api.ovirt-engine-extensions-api"/>
Line 12:     <module name="org.ovirt.engine.core.extensions-manager"/>
Line 13:     <module name="org.ovirt.engine.core.utils"/>
you should not use anything at utils, this is very bad module for us, lots of 
legacy.
Line 14:     <module name="org.ovirt.engine.core.uutils"/>
Line 15:     <module name="org.slf4j"/>
Line 16:   </dependencies>


https://gerrit.ovirt.org/#/c/37886/4/backend/manager/extension-tool/pom.xml
File backend/manager/extension-tool/pom.xml:

Line 38:       <dependency>
Line 39:           <groupId>${engine.groupId}</groupId>
Line 40:           <artifactId>utils</artifactId>
Line 41:           <version>${engine.version}</version>
Line 42:       </dependency>
same, do not use utils.
Line 43:      <dependency>
Line 44:         <groupId>org.slf4j</groupId>
Line 45:         <artifactId>slf4j-api</artifactId>
Line 46:         <version>${slf4j.version}</version>


https://gerrit.ovirt.org/#/c/37886/4/backend/manager/extension-tool/src/main/java/org/ovirt/engine/exttool/core/CoreUtil.java
File 
backend/manager/extension-tool/src/main/java/org/ovirt/engine/exttool/core/CoreUtil.java:

Line 17:     }
Line 18: 
Line 19:     public static Properties loadProperties(Class<?> clazz, String 
resource) throws IOException{
Line 20:         Properties prop = new Properties();
Line 21:         InputStream is = clazz.getResourceAsStream(resource);
always use try with resources.
Line 22:         if(is.available() > 0) {
Line 23:             prop.load(is);
Line 24:         }
Line 25: 


Line 19:     public static Properties loadProperties(Class<?> clazz, String 
resource) throws IOException{
Line 20:         Properties prop = new Properties();
Line 21:         InputStream is = clazz.getResourceAsStream(resource);
Line 22:         if(is.available() > 0) {
Line 23:             prop.load(is);
do not load input stream as it does not support utf-8 use Reader.
Line 24:         }
Line 25: 
Line 26:         return prop;
Line 27:     }


Line 25: 
Line 26:         return prop;
Line 27:     }
Line 28: 
Line 29:     public static List<String> getLoggingLevels() {
not sure why you need this, but best to use reflection... extract all static 
Level from Level class.

anyway, this also can be in static context, so it is done once when class is 
loaded.

 private static final List<String> Levels = ...
Line 30:         return Arrays.asList(
Line 31:             Level.FINEST.getName(),
Line 32:             Level.FINER.getName(),
Line 33:             Level.FINE.getName(),


https://gerrit.ovirt.org/#/c/37886/4/backend/manager/extension-tool/src/main/java/org/ovirt/engine/exttool/core/ExtensionsToolExecutor.java
File 
backend/manager/extension-tool/src/main/java/org/ovirt/engine/exttool/core/ExtensionsToolExecutor.java:

Line 1: package org.ovirt.engine.exttool.core;
Line 2: 
Line 3: import org.apache.commons.lang.StringUtils;
Line 4: import org.ovirt.engine.core.extensions.mgr.ExtensionsManager;
Line 5: import org.ovirt.engine.core.utils.log.JavaLoggingUtils;
please do not use this.
Line 6: import org.ovirt.engine.core.uutils.cli.ParametersParser;
Line 7: 
Line 8: import java.io.File;
Line 9: import java.util.*;


Line 23:                 System.out.println(getUsage(moduleServices.keySet())); 
// FIXME:
Line 24:                 return;
Line 25:             }
Line 26: 
Line 27:             Deque<String> others = 
(Deque<String>)argMap.get("__other__");
better use simplest interface, in this case ordered is List
Line 28:             String module = others.removeFirst();
Line 29:             ModuleService moduleService = moduleServices.get(module);
Line 30: 
Line 31:             if(moduleService != null) {


Line 27:             Deque<String> others = 
(Deque<String>)argMap.get("__other__");
Line 28:             String module = others.removeFirst();
Line 29:             ModuleService moduleService = moduleServices.get(module);
Line 30: 
Line 31:             if(moduleService != null) {
always negative first....

 module = modules.get()
 if (modules == null) {
     throw exception
 }

 continue the green path
Line 32:                 moduleService.parseArguments(others);
Line 33:                 ExtensionsManager extensionsManager = new 
ExtensionsManager();
Line 34:                 File config = new 
File((String)argMap.get(ARG_EXT_CONFIG));
Line 35:                 if (!config.exists()) {


Line 28:             String module = others.removeFirst();
Line 29:             ModuleService moduleService = moduleServices.get(module);
Line 30: 
Line 31:             if(moduleService != null) {
Line 32:                 moduleService.parseArguments(others);
this should return something or another method added to get status, so we can 
handle:

 xxx logger --help

or any other valid case that skips the logic.
Line 33:                 ExtensionsManager extensionsManager = new 
ExtensionsManager();
Line 34:                 File config = new 
File((String)argMap.get(ARG_EXT_CONFIG));
Line 35:                 if (!config.exists()) {
Line 36:                     throw new Exception("Could not find extension 
configuration at the specified path");


Line 30: 
Line 31:             if(moduleService != null) {
Line 32:                 moduleService.parseArguments(others);
Line 33:                 ExtensionsManager extensionsManager = new 
ExtensionsManager();
Line 34:                 File config = new 
File((String)argMap.get(ARG_EXT_CONFIG));
we need a directory or worse multiple configs.
Line 35:                 if (!config.exists()) {
Line 36:                     throw new Exception("Could not find extension 
configuration at the specified path");
Line 37:                 }
Line 38:                 
extensionsManager.initialize(extensionsManager.load(config));


Line 34:                 File config = new 
File((String)argMap.get(ARG_EXT_CONFIG));
Line 35:                 if (!config.exists()) {
Line 36:                     throw new Exception("Could not find extension 
configuration at the specified path");
Line 37:                 }
Line 38:                 
extensionsManager.initialize(extensionsManager.load(config));
you should first load all then initialize all.
Line 39:                 moduleService.run(extensionsManager);
Line 40:             } else {
Line 41:                 System.out.println("No such " + module + " module 
exists. To list existing modules use --help argument.");
Line 42:             }


https://gerrit.ovirt.org/#/c/37886/4/backend/manager/extension-tool/src/main/java/org/ovirt/engine/exttool/core/ModuleService.java
File 
backend/manager/extension-tool/src/main/java/org/ovirt/engine/exttool/core/ModuleService.java:

Line 1: package org.ovirt.engine.exttool.core;
Line 2: 
Line 3: import org.ovirt.engine.core.extensions.mgr.ExtensionsManager;
Line 4: 
Line 5: import java.util.Deque;
the most primitive form, List is sufficient in this case.
Line 6: 
Line 7: public interface ModuleService {
Line 8: 
Line 9:     public void parseArguments(Deque<String> args) throws Exception;


Line 7: public interface ModuleService {
Line 8: 
Line 9:     public void parseArguments(Deque<String> args) throws Exception;
Line 10: 
Line 11:     public void run(ExtensionsManager extensionsManager) throws  
Exception;
please provide a context, and within that context put extensions manager, as it 
is expected that we will have more as time goes by.

the context should be provided using setContext() method.
Line 12: 
Line 13:     public String getName();


https://gerrit.ovirt.org/#/c/37886/4/backend/manager/extension-tool/src/main/java/org/ovirt/engine/exttool/logger/services/LoggerServiceImpl.java
File 
backend/manager/extension-tool/src/main/java/org/ovirt/engine/exttool/logger/services/LoggerServiceImpl.java:

Line 48:         } else {
Line 49:             throw new IllegalArgumentException(
Line 50:                 "No action specified for module " + getName()
Line 51:             );
Line 52:         }
exceptional pattern:

 if (fail) {
     throw
 }

 continue green flow
Line 53: 
Line 54:         LogRecord logRecord = new LogRecord(
Line 55:             (Level)argMap.get("level"),
Line 56:             (String)argMap.get("message")


Line 50:                 "No action specified for module " + getName()
Line 51:             );
Line 52:         }
Line 53: 
Line 54:         LogRecord logRecord = new LogRecord(
please separate to own function.

best to have some mapping....

Map such as:

 "log-record", new Runnable() { @Override void run() { logRecord() } }

then you have a method per command and generic logic.

here it is overkill, but will be obvious in next modules.
Line 55:             (Level)argMap.get("level"),
Line 56:             (String)argMap.get("message")
Line 57:         );
Line 58:         logRecord.setLoggerName((String)argMap.get("logger-name"));


Line 81:         );
Line 82:     }
Line 83: 
Line 84:     @Override
Line 85:     public String getName() {
please put this first (after constructor).
Line 86:         return "logger";
Line 87:     }


https://gerrit.ovirt.org/#/c/37886/4/backend/manager/extension-tool/src/main/resources/org/ovirt/engine/exttool/core/arguments.properties
File 
backend/manager/extension-tool/src/main/resources/org/ovirt/engine/exttool/core/arguments.properties:

Line 1: arg.extension-config.name = extension-config
extensions-conf.d  or extesions-dir ?
Line 2: arg.extension-config.help = path to directory of extensions
Line 3: arg.extension-config.type = required_argument
Line 4: arg.extension-config.default = /etc/ovirt-engine/extensions.d/
Line 5: arg.log-file.name = log-file


Line 7: arg.log-file.type = required_argument
Line 8: arg.log-level.name = log-level
Line 9: arg.log-level.help = file where log will be stored
Line 10: arg.log-level.type = required_argument
Line 11: arg.log-level.matcher = FINEST|FINER|FINE|CONFIG|INFO|WARNING|SEVERE
I think that numeric value is sufficient :)))

but ok.
Line 12: arg.help.name = help


https://gerrit.ovirt.org/#/c/37886/4/backend/manager/extension-tool/src/main/resources/org/ovirt/engine/exttool/logger/services/arguments.properties
File 
backend/manager/extension-tool/src/main/resources/org/ovirt/engine/exttool/logger/services/arguments.properties:

Line 1: arg.logger-name.name = extension-config
why extension-config?
Line 2: arg.logger-name.mandatory = true
Line 3: arg.logger-name.help = path to directory of extensions
Line 4: arg.logger-name.type = required_argument
Line 5: arg.message.name = log-file


Line 1: arg.logger-name.name = extension-config
Line 2: arg.logger-name.mandatory = true
Line 3: arg.logger-name.help = path to directory of extensions
this should be in the core
Line 4: arg.logger-name.type = required_argument
Line 5: arg.message.name = log-file
Line 6: arg.message.help = file where log will be stored
Line 7: arg.message.type = required_argument


Line 1: arg.logger-name.name = extension-config
Line 2: arg.logger-name.mandatory = true
Line 3: arg.logger-name.help = path to directory of extensions
Line 4: arg.logger-name.type = required_argument
Line 5: arg.message.name = log-file
we do not need log file, just name as in:

 LoggerFactory.getLogger(name)

this name will be issued within the core logger.
Line 6: arg.message.help = file where log will be stored
Line 7: arg.message.type = required_argument
Line 8: arg.message.mandatory = true
Line 9: arg.level.name = level


https://gerrit.ovirt.org/#/c/37886/4/backend/manager/modules/uutils/src/main/java/org/ovirt/engine/core/uutils/cli/ArgumentType.java
File 
backend/manager/modules/uutils/src/main/java/org/ovirt/engine/core/uutils/cli/ArgumentType.java:

Line 1: package org.ovirt.engine.core.uutils.cli;
please move this to cli.<something> so we can avoid mixing this and the old, or 
have some special prefix for these classes.
Line 2: 
Line 3: public enum ArgumentType {
Line 4: 
Line 5:     required_argument("required_argument"),


Line 1: package org.ovirt.engine.core.uutils.cli;
Line 2: 
Line 3: public enum ArgumentType {
this can be nested class.
Line 4: 
Line 5:     required_argument("required_argument"),
Line 6:     optional_argument("optional_argument"),
Line 7:     no_argument("no_argument");


https://gerrit.ovirt.org/#/c/37886/4/backend/manager/modules/uutils/src/main/java/org/ovirt/engine/core/uutils/cli/ParametersParser.java
File 
backend/manager/modules/uutils/src/main/java/org/ovirt/engine/core/uutils/cli/ParametersParser.java:

Line 13: import java.util.Set;
Line 14: import java.util.regex.Matcher;
Line 15: import java.util.regex.Pattern;
Line 16: 
Line 17:     public class ParametersParser {
indent
Line 18: 
Line 19:     private static final String LONG_PREFIX = "--";
Line 20: 
Line 21:     private Map<String, ParserArgument> arguments;


Line 18: 
Line 19:     private static final String LONG_PREFIX = "--";
Line 20: 
Line 21:     private Map<String, ParserArgument> arguments;
Line 22:     private Properties properties;
no reason to keep this
Line 23: 
Line 24:     public ParametersParser(Properties properties) {
Line 25:         this.properties = properties;
Line 26:         this.arguments = new HashMap<>();


Line 28:     }
Line 29: 
Line 30:     private void parseProperties() {
Line 31:         String _tmp;
Line 32:         ParserArgument argument;
no reason to define these at top level

_tmp is something that follows the 'private member' convention, please try to 
avoid using it for something else. a variable named 's' is sufficient for 'yet 
another  string'.
Line 33:         for(String name : getUsageArguments()) {
Line 34:             argument = new ParserArgument();
Line 35: 
Line 36:             argument.setName(getArgAttrValue(name, "name"));


Line 34:             argument = new ParserArgument();
Line 35: 
Line 36:             argument.setName(getArgAttrValue(name, "name"));
Line 37:             if(argument.getName() == null) {
Line 38:                 throw new IllegalArgumentException("Name of argument " 
+ name + " have to specified");
please use String.format() to format messages, do not concat strings.
Line 39:             }
Line 40: 
Line 41:             _tmp = getArgAttrValue(name, "type");
Line 42:             argument.setType(


Line 40: 
Line 41:             _tmp = getArgAttrValue(name, "type");
Line 42:             argument.setType(
Line 43:                 _tmp != null ? ArgumentType.valueOf(_tmp) : 
ArgumentType.no_argument
Line 44:             );
please use default properties file, and load the default and then the actual. 
this will allow you to have defaults for everything and reduce logic.
Line 45: 
Line 46:             argument.setHelp(getArgAttrValue(name, "help"));
Line 47: 
Line 48:             _tmp = getArgAttrValue(name, "matcher");


Line 47: 
Line 48:             _tmp = getArgAttrValue(name, "matcher");
Line 49:             if(_tmp != null) {
Line 50:                 argument.setMatcher(Pattern.compile(_tmp));
Line 51:             }
default matcher can be .* to reduce logic
Line 52: 
Line 53:             argument.setMandatory(
Line 54:                 Boolean.parseBoolean(getArgAttrValue(name, 
"mandatory"))
Line 55:             );


Line 56: 
Line 57:             _tmp = getArgAttrValue(name, "convert");
Line 58:             if(_tmp != null) {
Line 59:                 try {
Line 60:                     argument.setConvert(Class.forName(_tmp));
Please use the context classloader to locate the class.

 Thread.currentThread().getContextClassLoader()
Line 61:                 } catch (ClassNotFoundException ex) {
Line 62:                     throw new IllegalArgumentException("Can't convert 
argument: " + name + ". Class not found: " + _tmp);
Line 63:                 }
Line 64:             }


Line 71:         }
Line 72:     }
Line 73: 
Line 74: 
Line 75:     private Set<String> getUsageArguments() {
we will eventually need to sort based on the 3rtd component so we produce 
expected usage output.

 xxx.arg.yyy.aaa

yyy should be sorted
Line 76:         Set<String> args = new HashSet<>();
Line 77:         for (String argName : properties.stringPropertyNames()) {
Line 78:             String[] param = argName.split("\\.");
Line 79:             if (param.length < 3) {


Line 92:     public Map<String, Object> parse(List<String> args) throws 
Exception {
Line 93:         return parse(new ArrayDeque<String>(args));
Line 94:     }
Line 95: 
Line 96:     public Map<String, Object> parse(Deque<String> args) throws 
Exception {
no need for Deque, List should be sufficient.
Line 97:         Map<String, Object> argMap = new HashMap<>();
Line 98:         Deque<String> others = new ArrayDeque<>();
Line 99:         boolean firstNonParameter = false;
Line 100: 


Line 107:             if(arg.equals(LONG_PREFIX)) {
Line 108:                 break;
Line 109:             }
Line 110:             if(arg.startsWith(LONG_PREFIX)) {
Line 111:                 String[] _arg = parseArgument(arg.substring(2));
no _ prefix please
Line 112:                 ParserArgument parserArgument = 
arguments.get(_arg[0]);
Line 113:                 if(parserArgument == null) {
Line 114:                     others.addLast(arg);
Line 115:                     continue;


Line 110:             if(arg.startsWith(LONG_PREFIX)) {
Line 111:                 String[] _arg = parseArgument(arg.substring(2));
Line 112:                 ParserArgument parserArgument = 
arguments.get(_arg[0]);
Line 113:                 if(parserArgument == null) {
Line 114:                     others.addLast(arg);
why? this should be syntax error, no?
Line 115:                     continue;
Line 116:                 }
Line 117: 
Line 118:                 if(parserArgument.getDefaultValue() != null && 
_arg[1] == null) {


Line 116:                 }
Line 117: 
Line 118:                 if(parserArgument.getDefaultValue() != null && 
_arg[1] == null) {
Line 119:                     _arg[1] = 
String.valueOf(parserArgument.getDefaultValue());
Line 120:                 }
I do not understand this. you already filled the defaults, no?
Line 121: 
Line 122:                 if(parserArgument.getType() == 
ArgumentType.required_argument && _arg[1] == null) {
Line 123:                     throw new IllegalArgumentException(
Line 124:                         "Argument's '" + _arg[0] + "' value is 
reguired"


Line 136: 
Line 137:                 // convert value
Line 138:                 if(parserArgument.getConvert() != null) {
Line 139:                     argConverted = 
Util.getObjectValueByString(parserArgument.getConvert(), _arg[1]);
Line 140:                 }
converter class can be default java.lang.String and reduce logic.
Line 141: 
Line 142:                 argMap.put(
Line 143:                     _arg[0],
Line 144:                     argConverted == null ? _arg[1] : argConverted


Line 149:                 } else {
Line 150:                     others.addLast(arg);
Line 151:                 }
Line 152:                 firstNonParameter = true;
Line 153:             }
not sure what this else is doing, but should be first within condition.

 if {
     trivial block
 } else {
     non trivial block
 }
Line 154:         }
Line 155:         // Check all mandatory specified.
Line 156:         checkMandatory(argMap);
Line 157: 


Line 180:         if(!defaults.isEmpty()) {
Line 181:             for(String s : defaults) {
Line 182:                 args.addLast("--" + s);
Line 183:             }
Line 184:         }
I do not understand... why don't you just put the defaults in the map, then 
override these defaults while you parse the arguments?
Line 185:     }
Line 186: 
Line 187:     private void checkMandatory(Map<String, Object> argMap) {
Line 188:         Set<String> mandatory = new HashSet<>();


Line 189:         for(String arg : arguments.keySet()) {
Line 190:             if(arguments.get(arg).isMandatory()) {
Line 191:                 mandatory.add(arg);
Line 192:             }
Line 193:         }
this you can prepare ahead when parsing properties.
Line 194:         mandatory.removeAll(argMap.keySet());
Line 195:         if(!mandatory.isEmpty()) {
Line 196:             throw new IllegalArgumentException(
Line 197:                 "Argument(s) " + StringUtils.join(mandatory, ", ") + 
" required"


https://gerrit.ovirt.org/#/c/37886/4/backend/manager/modules/uutils/src/main/java/org/ovirt/engine/core/uutils/cli/Util.java
File 
backend/manager/modules/uutils/src/main/java/org/ovirt/engine/core/uutils/cli/Util.java:

Line 25:         typeBox.put(short.class, Short.class);
Line 26:         typeBox.put(void.class, Void.class);
Line 27:     }
Line 28: 
Line 29:     public static Object getObjectValueByString(Class<?> clazz, String 
value) {
it is more complex than what we need... but ok for now :))
Line 30:         Object v = null;
Line 31: 
Line 32:         if (clazz.isPrimitive()) {
Line 33:             clazz = typeBox.get(clazz);


-- 
To view, visit https://gerrit.ovirt.org/37886
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: Ie06113c5d56a49e58d557c851f9ff00b9a9ca409
Gerrit-PatchSet: 4
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Ondřej Macháček <machacek.on...@gmail.com>
Gerrit-Reviewer: Alon Bar-Lev <alo...@redhat.com>
Gerrit-Reviewer: Ondřej Macháček <machacek.on...@gmail.com>
Gerrit-Reviewer: automat...@ovirt.org
Gerrit-Reviewer: oVirt Jenkins CI Server
Gerrit-HasComments: Yes
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to