Java tutorial
/* * Copyright (c) 2015 mgm technology partners GmbH * * 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 com.mgmtp.jfunk.core.config; import static com.google.common.base.Preconditions.checkState; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; import java.nio.charset.Charset; import java.util.ArrayDeque; import java.util.Deque; import java.util.Set; import javax.inject.Inject; import javax.inject.Provider; import javax.inject.Singleton; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.io.IOUtils; import com.google.common.base.Charsets; import com.google.common.eventbus.EventBus; import com.google.inject.Provides; import com.google.inject.Scope; import com.google.inject.matcher.Matchers; import com.mgmtp.jfunk.common.JFunkConstants; import com.mgmtp.jfunk.common.config.ModuleScoped; import com.mgmtp.jfunk.common.config.ScriptScoped; import com.mgmtp.jfunk.common.config.StackedScope; import com.mgmtp.jfunk.common.config.ThreadScope; import com.mgmtp.jfunk.common.random.MathRandom; import com.mgmtp.jfunk.common.util.Configuration; import com.mgmtp.jfunk.core.data.DataSetAdapter; import com.mgmtp.jfunk.core.event.AfterCommandEvent; import com.mgmtp.jfunk.core.event.BeforeCommandEvent; import com.mgmtp.jfunk.core.event.EventHandlers; import com.mgmtp.jfunk.core.mail.EmailModule; import com.mgmtp.jfunk.core.reporting.ReportContext; import com.mgmtp.jfunk.core.scripting.BreakIndex; import com.mgmtp.jfunk.core.scripting.Cmd; import com.mgmtp.jfunk.core.scripting.ExecutionMode; import com.mgmtp.jfunk.core.scripting.ModuleArchiver; import com.mgmtp.jfunk.core.scripting.ModuleArchiver.ArchivingMode; import com.mgmtp.jfunk.core.scripting.ModuleMetaData; import com.mgmtp.jfunk.core.scripting.ScriptContext; import com.mgmtp.jfunk.core.scripting.ScriptMetaData; import com.mgmtp.jfunk.core.scripting.ScriptingModule; import com.mgmtp.jfunk.core.util.CsvDataProcessor; import com.mgmtp.jfunk.data.DataSourceModule; /** * Guice module for jFunk which is always needed. It is loaded automatically by the * {@link ModulesLoader}. Additional modules need to be configured in a properties file (see * {@link ModulesLoader}. */ public final class JFunkBaseModule extends BaseJFunkGuiceModule { @Override protected void doConfigure() { ThreadScope scope = new ThreadScope(); scope.enterScope(); // need to enter it right away for the main thread bindScope(ThreadScope.class, scope, ScriptScoped.class); bindScope(StackedScope.class, new StackedScope(), ModuleScoped.class); bindListener(Matchers.any(), new ConfigurationTypeListener(getProvider(Configuration.class))); bind(ScriptMetaData.class); bind(ModuleMetaData.class); bind(DataSetAdapter.class); bind(CsvDataProcessor.class); bindCommandInterceptor(); String encoding = System.getProperty("file.encoding"); Charset charset = null; try { charset = Charset.forName(encoding); } catch (IllegalArgumentException ex) { charset = Charsets.UTF_8; } bind(Charset.class).toInstance(charset); install(new DataSourceModule()); install(new ScriptingModule()); install(new EmailModule()); } private <T extends Scope> void bindScope(final Class<T> scopeClass, final T scope, final Class<? extends Annotation> scopeAnnotation) { // We need a custom thread scope for things related to test runs, because each test runs in // its own thread. This gives us thread-local Guice singletons. bindScope(scopeAnnotation, scope); // We also need to get a hold of the ThreadScope instance via Guice in order to be able to // call its cleanUp method after a thread is done. We need to do a clean-up in order to // avoid memory leaks. bind(scopeClass).toInstance(scope); } private void bindCommandInterceptor() { MethodInterceptor interceptor = new MethodInterceptor() { @Inject Provider<EventBus> eventBusProvider; @Override public Object invoke(final MethodInvocation invocation) throws Throwable { //NOSONAR String command = invocation.getMethod().getName(); Object[] params = invocation.getArguments(); boolean success = false; EventBus eventBus = eventBusProvider.get(); try { eventBus.post(new BeforeCommandEvent(command, params)); Object result = invocation.proceed(); success = true; return result; } finally { eventBus.post(new AfterCommandEvent(command, params, success)); } } }; requestInjection(interceptor); bindInterceptor(Matchers.subclassesOf(ScriptContext.class), Matchers.annotatedWith(Cmd.class), interceptor); } /** * Provides the version of perfLoad as specified in the Maven pom. * * @return the version string */ @Provides @Singleton @JFunkVersion protected String providePerfLoadVersion() { ClassLoader loader = Thread.currentThread().getContextClassLoader(); InputStream is = loader.getResourceAsStream("com/mgmtp/jfunk/common/version.txt"); try { return IOUtils.toString(is, "UTF-8"); } catch (IOException ex) { throw new IllegalStateException("Could not read jFunk version.", ex); } finally { IOUtils.closeQuietly(is); } } @Provides @ScriptScoped Deque<ReportContext> provideReportContextStack() { return new ArrayDeque<>(); } @Provides @ScriptScoped Configuration provideConfiguration(final DataSetAdapter dsAdapter, final Charset charset) { Configuration configuration = new Configuration(dsAdapter, charset); configuration.load(JFunkConstants.SCRIPT_PROPERTIES, false); return configuration; } @Provides @Singleton EventBus provideEventBus(@EventHandlers final Set<Object> eventHandlers) { EventBus eventBus = new EventBus(); for (Object eventHandler : eventHandlers) { eventBus.register(eventHandler); } return eventBus; } @Provides @ArchiveDir File provideArchiveDir(final Configuration config) { File archiveDir = new File(config.get(JFunkConstants.ARCHIVE_DIR, JFunkConstants.ARCHIVE_DIR_DEFAULT)) .getAbsoluteFile(); archiveDir.mkdirs(); checkState(archiveDir.exists(), "Could not create archive directory: %s", archiveDir); return archiveDir; } @Provides @ModuleArchiveDir File provideModuleArchiveDir(final Provider<ModuleArchiver> moduleArchiverProvider) { return moduleArchiverProvider.get().getModuleArchiveDir(); } @Provides @ScriptScoped MathRandom provideMathRandom(final Configuration config) { String seedString = config.get(JFunkConstants.RANDOM_SEED, false); return seedString == null ? new MathRandom() : new MathRandom(Long.parseLong(seedString)); } @Provides ExecutionMode provideExecutionMode(final Configuration config) { String execMode = config.get(JFunkConstants.EXECUTION_MODE, JFunkConstants.EXECUTION_MODE_ALL); return ExecutionMode.valueOf(execMode); } @Provides @BreakIndex int provideBreakIndex(final Configuration config) { return config.getInteger(JFunkConstants.STEP, 0); } @Provides ArchivingMode provideArchivingMode(final Configuration config) { return ArchivingMode.valueOf(config.get(JFunkConstants.ARCHIVING_MODE, JFunkConstants.ARCHIVING_MODE_ALL)); } }