Mercurial > hg > release > thermostat-1.4
changeset 1744:a23998f093d2
Add new API for tracking a command's dependencies
Reviewed-by: omajid
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2015-September/015729.html
PR2605
author | Severin Gehwolf <sgehwolf@redhat.com> |
---|---|
date | Wed, 02 Sep 2015 17:54:51 +0200 |
parents | ca91f13ef261 |
children | 0e4c60a50547 |
files | common/core/src/main/java/com/redhat/thermostat/common/cli/DependencyServices.java common/core/src/test/java/com/redhat/thermostat/common/cli/DependencyServicesTest.java vm-gc/command/src/main/java/com/redhat/thermostat/vm/gc/command/internal/ShowGcNameCommand.java vm-profiler/client-cli/src/main/java/com/redhat/thermostat/vm/profiler/client/cli/internal/DependencyServices.java vm-profiler/client-cli/src/main/java/com/redhat/thermostat/vm/profiler/client/cli/internal/ProfileVmCommand.java vm-profiler/client-cli/src/test/java/com/redhat/thermostat/vm/profiler/client/cli/internal/DependencyServicesTest.java |
diffstat | 6 files changed, 182 insertions(+), 188 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/core/src/main/java/com/redhat/thermostat/common/cli/DependencyServices.java Wed Sep 02 17:54:51 2015 +0200 @@ -0,0 +1,96 @@ +/* + * Copyright 2012-2015 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.cli; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * Contains dependencies for a command. + * + * Provides ways to add ({@link #addService(Class, Object)}), remove ( + * {@link #removeService(Class)}) and fetch ({@link #getService(Class)}) + * services. Fetching has timeout support. + */ +public class DependencyServices { + + private Map<Class<?>, BlockingQueue<?>> serviceHolder = new HashMap<>(); + + private <T> BlockingQueue<T> getHolder(Class<T> serviceClass) { + if (!serviceHolder.containsKey(serviceClass)) { + serviceHolder.put(serviceClass, new LinkedBlockingQueue<T>(1)); + } + return (BlockingQueue<T>) serviceHolder.get(serviceClass); + } + + /** @throws IllegalArgumentException if service is already added */ + public <T> void addService(Class<T> serviceClass, T item) { + Objects.requireNonNull(item); + BlockingQueue<T> holder = getHolder(serviceClass); + boolean added = holder.offer(item); + if (!added) { + throw new IllegalArgumentException("service is already being tracked"); + } + } + + public <T> void removeService(Class<T> serviceClass) { + BlockingQueue<T> holder = getHolder(serviceClass); + if (holder.peek() != null) { + holder.remove(); + } + } + + /** @return the service, or {@code null} */ + public <T> T getService(Class<T> serviceClass) { + BlockingQueue<T> holder = getHolder(serviceClass); + try { + // a crappy version of peek()-with-timeout + T retValue = holder.poll(500, TimeUnit.MILLISECONDS); + if (retValue != null) { + holder.add(retValue); + } + return retValue; + } catch (InterruptedException e) { + return null; + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/core/src/test/java/com/redhat/thermostat/common/cli/DependencyServicesTest.java Wed Sep 02 17:54:51 2015 +0200 @@ -0,0 +1,76 @@ +/* + * Copyright 2012-2015 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.cli; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +public class DependencyServicesTest { + + @Test + public void uninjectedServiceIsNotAvailable() throws Exception { + DependencyServices services = new DependencyServices(); + + assertNull(services.getService(Object.class)); + } + + @Test + public void injectedServiceIsAvailable() throws Exception { + DependencyServices services = new DependencyServices(); + services.addService(Object.class, services); + + assertEquals(services, services.getService(Object.class)); + } + + @Test(expected=IllegalArgumentException.class) + public void injectingSameServiceTwiceIsAnError() { + DependencyServices services = new DependencyServices(); + services.addService(Object.class, services); + services.addService(Object.class, services); + } + + @Test + public void injectedAndRemovedServiceIsNotAvailable() { + DependencyServices services = new DependencyServices(); + services.addService(Object.class, services); + + services.removeService(Object.class); + assertNull(services.getService(Object.class)); + } +}
--- a/vm-gc/command/src/main/java/com/redhat/thermostat/vm/gc/command/internal/ShowGcNameCommand.java Wed Sep 02 18:49:42 2015 +0200 +++ b/vm-gc/command/src/main/java/com/redhat/thermostat/vm/gc/command/internal/ShowGcNameCommand.java Wed Sep 02 17:54:51 2015 +0200 @@ -38,13 +38,12 @@ import java.io.PrintStream; import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; import com.redhat.thermostat.client.cli.HostVMArguments; import com.redhat.thermostat.common.cli.AbstractCommand; import com.redhat.thermostat.common.cli.CommandContext; import com.redhat.thermostat.common.cli.CommandException; +import com.redhat.thermostat.common.cli.DependencyServices; import com.redhat.thermostat.shared.locale.LocalizedString; import com.redhat.thermostat.shared.locale.Translate; import com.redhat.thermostat.storage.core.VmId; @@ -62,18 +61,15 @@ static final String REGISTER_NAME = "show-gc-name"; private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer(); private static final GcCommonNameMapper mapper = new GcCommonNameMapper(); - private CountDownLatch servicesAvailableLatch = new CountDownLatch(2); // vmInfo dao and vmGcStat dao + private final DependencyServices services = new DependencyServices(); private VmInfoDAO vmInfoDao; private VmGcStatDAO gcDao; @Override public void run(CommandContext ctx) throws CommandException { - try { - servicesAvailableLatch.await(500, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - throw new CommandException(translator.localize(LocaleResources.COMMAND_INTERRUPTED)); - } - + this.vmInfoDao = services.getService(VmInfoDAO.class); + this.gcDao = services.getService(VmGcStatDAO.class); + requireNonNull(vmInfoDao, translator.localize(LocaleResources.VM_SERVICE_UNAVAILABLE)); requireNonNull(gcDao, translator.localize(LocaleResources.GC_STAT_DAO_SERVICE_UNAVAILABLE)); @@ -91,19 +87,16 @@ } void setVmInfo(VmInfoDAO vmInfoDAO) { - this.vmInfoDao = vmInfoDAO; - servicesAvailableLatch.countDown(); + services.addService(VmInfoDAO.class, vmInfoDAO); } void setVmGcStat(VmGcStatDAO vmGcStat) { - this.gcDao = vmGcStat; - servicesAvailableLatch.countDown(); + services.addService(VmGcStatDAO.class, vmGcStat); } void servicesUnavailable() { - this.gcDao = null; - this.vmInfoDao = null; - servicesAvailableLatch = new CountDownLatch(2); + services.removeService(VmInfoDAO.class); + services.removeService(VmGcStatDAO.class); } /**
--- a/vm-profiler/client-cli/src/main/java/com/redhat/thermostat/vm/profiler/client/cli/internal/DependencyServices.java Wed Sep 02 18:49:42 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/* - * Copyright 2012-2015 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <http://www.gnu.org/licenses/>. - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.profiler.client.cli.internal; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; - -/** - * Contains dependencies for a command. - * - * Provides ways to add ({@link #addService(Class, Object)}), remove ( - * {@link #removeService(Class)}) and fetch ({@link #getService(Class)}) - * services. Fetching has timeout support. - */ -public class DependencyServices { - - private Map<Class<?>, BlockingQueue<?>> serviceHolder = new HashMap<>(); - - private <T> BlockingQueue<T> getHolder(Class<T> serviceClass) { - if (!serviceHolder.containsKey(serviceClass)) { - serviceHolder.put(serviceClass, new LinkedBlockingQueue<T>(1)); - } - return (BlockingQueue<T>) serviceHolder.get(serviceClass); - } - - /** @throws IllegalArgumentException if service is already added */ - public <T> void addService(Class<T> serviceClass, T item) { - Objects.requireNonNull(item); - BlockingQueue<T> holder = getHolder(serviceClass); - boolean added = holder.offer(item); - if (!added) { - throw new IllegalArgumentException("service is already being tracked"); - } - } - - public <T> void removeService(Class<T> serviceClass) { - BlockingQueue<T> holder = getHolder(serviceClass); - if (holder.peek() != null) { - holder.remove(); - } - } - - /** @return the service, or {@code null} */ - public <T> T getService(Class<T> serviceClass) { - BlockingQueue<T> holder = getHolder(serviceClass); - try { - // a crappy version of peek()-with-timeout - T retValue = holder.poll(500, TimeUnit.MILLISECONDS); - if (retValue != null) { - holder.add(retValue); - } - return retValue; - } catch (InterruptedException e) { - return null; - } - } - -}
--- a/vm-profiler/client-cli/src/main/java/com/redhat/thermostat/vm/profiler/client/cli/internal/ProfileVmCommand.java Wed Sep 02 18:49:42 2015 +0200 +++ b/vm-profiler/client-cli/src/main/java/com/redhat/thermostat/vm/profiler/client/cli/internal/ProfileVmCommand.java Wed Sep 02 17:54:51 2015 +0200 @@ -50,6 +50,7 @@ import com.redhat.thermostat.common.cli.CommandContext; import com.redhat.thermostat.common.cli.CommandException; import com.redhat.thermostat.common.cli.Console; +import com.redhat.thermostat.common.cli.DependencyServices; import com.redhat.thermostat.common.command.Request; import com.redhat.thermostat.common.command.RequestResponseListener; import com.redhat.thermostat.common.command.Response;
--- a/vm-profiler/client-cli/src/test/java/com/redhat/thermostat/vm/profiler/client/cli/internal/DependencyServicesTest.java Wed Sep 02 18:49:42 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright 2012-2015 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <http://www.gnu.org/licenses/>. - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.profiler.client.cli.internal; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -import org.junit.Test; - -public class DependencyServicesTest { - - @Test - public void uninjectedServiceIsNotAvailable() throws Exception { - DependencyServices services = new DependencyServices(); - - assertNull(services.getService(Object.class)); - } - - @Test - public void injectedServiceIsAvailable() throws Exception { - DependencyServices services = new DependencyServices(); - services.addService(Object.class, services); - - assertEquals(services, services.getService(Object.class)); - } - - @Test(expected=IllegalArgumentException.class) - public void injectingSameServiceTwiceIsAnError() { - DependencyServices services = new DependencyServices(); - services.addService(Object.class, services); - services.addService(Object.class, services); - } - - @Test - public void injectedAndRemovedServiceIsNotAvailable() { - DependencyServices services = new DependencyServices(); - services.addService(Object.class, services); - - services.removeService(Object.class); - assertNull(services.getService(Object.class)); - } -}