Java tutorial
/* * Copyright 2011 Oliver B. Fischer * * Licensed 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 de.fischer.thotti.core.configuration; import de.fischer.thotti.core.annotations.DistributedTestJob; import de.fischer.thotti.core.annotations.HadoopJobFlow; import de.fischer.thotti.core.annotations.JVMArgs; import de.fischer.thotti.core.annotations.NDTest; import de.fischer.thotti.core.annotations.ParamGrp; import de.fischer.thotti.core.annotations.ParamSet; import de.fischer.thotti.core.annotations.ParamVal; import de.fischer.thotti.core.annotations.Run; import de.fischer.thotti.ec2.core.ThottiRuntimeException; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; import java.util.Collection; import static org.apache.commons.lang3.StringUtils.isNotEmpty; /** * @author Oliver B. Fischer */ public class ConfigDenormalizer { public void denormalize(Configuration config, ConfigurationWriter writer) { Collection<ThottiAnnotationHolder<NDTest>> ndTests = config.getAllNDTests(); Collection<ThottiAnnotationHolder<HadoopJobFlow>> hjFlows = config.getAllHadoopJobFlows(); if (!ndTests.isEmpty() && !hjFlows.isEmpty()) { // @todo Throw something better throw new ThottiRuntimeException("Either NDtests or HDtests!"); } // @todo What to do if both are empty if (!ndTests.isEmpty()) { for (ThottiAnnotationHolder<NDTest> test : ndTests) { denormalizeNDTest(test, config, writer); } } if (!hjFlows.isEmpty()) { denormalizeHJFlows(hjFlows, config, writer); } } protected void denormalizeHJFlows(Collection<ThottiAnnotationHolder<HadoopJobFlow>> hjFlows, Configuration config, ConfigurationWriter writer) { writer.startDistributedTestSuite(); for (ThottiAnnotationHolder<HadoopJobFlow> holder : hjFlows) { createHDTests(holder, config, writer); } writer.finishDistributedTestSuite(); } private void createHDTests(ThottiAnnotationHolder<HadoopJobFlow> flowHolder, Configuration config, ConfigurationWriter writer) { writer.startFlow(); writer.withFlowName(flowHolder.getAnnotation().id()); // find all tests in the same package or subpackages Package pack = getPackageOfJobFlow(flowHolder); String packageName = pack.getName(); Collection<ThottiAnnotationHolder<DistributedTestJob>> allDistributedTestJobs = config .getAllDistributedTestJobs(); for (ThottiAnnotationHolder<DistributedTestJob> dtholder : allDistributedTestJobs) { Package packageOfDTJ = getPackageOfDTJ(dtholder); String clazz = getFQCNFromHolderOfDTJ(dtholder); String packageNameOfDTJ = packageOfDTJ.getName(); if (packageNameOfDTJ.startsWith(packageName)) { writer.startTestStep().withTestStepJobClass(clazz).withTestStepID(dtholder.getAnnotation().id()) .withActionOnFailure(dtholder.getAnnotation().onFailure()); for (String argument : dtholder.getAnnotation().jobArguments()) { writer.addTestStepArgument(argument); } writer.finishTestStep(); } } writer.finishFlow(); } private Package getPackageOfDTJ(ThottiAnnotationHolder<DistributedTestJob> holder) { AnnotatedElement origin = holder.getOrigin(); return ((Class) origin).getPackage(); } private Package getPackageOfJobFlow(ThottiAnnotationHolder<HadoopJobFlow> holder) { AnnotatedElement origin = holder.getOrigin(); return ((Class) origin).getPackage(); } void denormalizeNDTest(ThottiAnnotationHolder<NDTest> holder, Configuration config, ConfigurationWriter writer) { NDTest ndTest = holder.getAnnotation(); String fqcn = getFQCNFromHolder(holder); String method = getMethodNameFromHolder(holder); JVMArgs[] jvmArgs = getJVMArgsForTest(ndTest, config); ParamSet parameters = getParameterSetForText(ndTest, config); if (jvmArgs != null) { createNDTestSection(writer, ndTest, fqcn, method, parameters, jvmArgs); } else { createNDTestSection(writer, ndTest, fqcn, method, parameters, null); } writer.finishNDTestSection(); } private void createNDTestSection(ConfigurationWriter writer, NDTest ndTest, String fqcn, String method, ParamSet parameters, JVMArgs[] jvmArgs) { writer.startNDTestSection().withID(ndTest.id()).withDescription(ndTest.description()).withTargetClass(fqcn) .withTargetMethod(method); if (jvmArgs == null) { // Doing this allows us to pass the loop below // at least once jvmArgs = new JVMArgs[] { null }; } for (JVMArgs args : jvmArgs) { if (parameters != null) { // The current test will be executed once for every // parameter group contained in the given parameter set for (ParamGrp group : parameters.value()) { writer.startTest(); writer.withTestID(group.name()); if (args != null) { writer.withTestJVMArgs(args.value()); writer.withTestJVMArgsID(args.id()); } for (ParamVal val : group.values()) { writer.withParameter(val.name(), val.value()); } writer.finishTest(); } } else { writer.startTest(); if (args != null) { writer.withTestJVMArgs(args.value()); writer.withTestJVMArgsID(args.id()); } writer.finishTest(); } } } private String getFQCNFromHadoopJobFlow(ThottiAnnotationHolder<HadoopJobFlow> holder) { Class clazz = (Class) holder.getOrigin(); return clazz.getName(); } private String getFQCNFromHolderOfDTJ(ThottiAnnotationHolder<DistributedTestJob> holder) { AnnotatedElement element = holder.getOrigin(); assert element instanceof Class : "Only methods are currently supported."; Class clazz = (Class) element; assert clazz.isInterface() == false : "Annotation of interfaces is not supported."; return clazz.getCanonicalName(); } private String getFQCNFromHolder(ThottiAnnotationHolder<NDTest> holder) { AnnotatedElement element = holder.getOrigin(); assert element instanceof Method : "Only methods are currently supported."; Method method = (Method) element; Class clazz = method.getDeclaringClass(); assert clazz.isInterface() == false : "Annotation of interfaces is not supported."; return clazz.getCanonicalName(); } private String getMethodNameFromHolder(ThottiAnnotationHolder<NDTest> holder) { AnnotatedElement element = holder.getOrigin(); assert element instanceof Method : "Only methods are currently supported."; Method method = (Method) element; return method.getName(); } private ParamSet getParameterSetForText(NDTest ndTest, Configuration config) { assert ndTest.run().length == 1 : "There must be one run annotation!"; Run run = ndTest.run()[0]; boolean contained = ArrayUtils.isNotEmpty(run.paramSet()); boolean reference = StringUtils.isNotEmpty(run.paramSetRef()); // assert !reference && !contained // : "If a parameter set is present, it must be either contained " + // "or referenced."; if (reference) { ThottiAnnotationHolder<ParamSet> param = config.getParameterSet(run.paramSetRef()); assert param != null : "Parameter set " + run.paramSetRef() + " not found."; return param.getAnnotation(); } if (contained) return run.paramSet()[0]; // @todo it would be better to throw an exception // @todo evalutate has/find/get style return null; } private JVMArgs[] getJVMArgsForTest(NDTest ndTest, Configuration config) { // @todo Write unit tests for this assertion assert ndTest.run().length == 1 : "There must be one run annotation!"; Run run = ndTest.run()[0]; boolean contained = ArrayUtils.isNotEmpty(run.jvmArgs()); boolean reference = isNotEmpty(run.jvmArgsRef()); // @todo Add a message! assert (reference && !contained) || (!reference && contained); if (reference) { ThottiAnnotationHolder<JVMArgs> args = config.getJVMArgs(run.jvmArgsRef()); assert args != null : "JVM arguments " + run.jvmArgsRef() + " not found."; return new JVMArgs[] { args.getAnnotation() }; } return run.jvmArgs(); } }