Mercurial > hg > release > thermostat-1.6
view vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/DumpHeapCommand.java @ 2049:a92d602216ad
Update copyright license headers for 2017
PR3290
Reviewed-by: jerboaa
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-January/021974.html
author | Andrew Azores <aazores@redhat.com> |
---|---|
date | Tue, 17 Jan 2017 12:19:56 -0500 |
parents | 3784a15aef43 |
children |
line wrap: on
line source
/* * Copyright 2012-2017 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.heap.analysis.command.internal; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.concurrent.Semaphore; import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.vm.heap.analysis.common.model.HeapInfo; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; import com.redhat.thermostat.client.cli.HostVMArguments; import com.redhat.thermostat.client.command.RequestQueue; 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.shared.locale.Translate; import com.redhat.thermostat.storage.dao.AgentInfoDAO; import com.redhat.thermostat.storage.dao.VmInfoDAO; import com.redhat.thermostat.vm.heap.analysis.command.locale.LocaleResources; import com.redhat.thermostat.vm.heap.analysis.common.HeapDAO; public class DumpHeapCommand extends AbstractCommand { private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer(); private BundleContext context; private final DumpHeapHelper implementation; public DumpHeapCommand() { this(FrameworkUtil.getBundle(DumpHeapCommand.class).getBundleContext(), new DumpHeapHelper()); } DumpHeapCommand(BundleContext context, DumpHeapHelper impl) { this.context = context; this.implementation = impl; } @Override public void run(final CommandContext ctx) throws CommandException { ServiceReference vmInfoRef = context.getServiceReference(VmInfoDAO.class.getName()); requireNonNull(vmInfoRef, translator.localize(LocaleResources.VM_SERVICE_UNAVAILABLE)); VmInfoDAO vmInfoDAO = (VmInfoDAO) context.getService(vmInfoRef); ServiceReference agentInfoRef = context.getServiceReference(AgentInfoDAO.class.getName()); requireNonNull(agentInfoRef, translator.localize(LocaleResources.AGENT_SERVICE_UNAVAILABLE)); AgentInfoDAO agentInfoDAO = (AgentInfoDAO) context.getService(agentInfoRef); ServiceReference requestQueueRef = context.getServiceReference(RequestQueue.class.getName()); requireNonNull(requestQueueRef, translator.localize(LocaleResources.REQUEST_QUEUE_UNAVAILABLE)); RequestQueue queue = (RequestQueue) context.getService(requestQueueRef); ServiceReference heapRef = context.getServiceReference(HeapDAO.class.getName()); requireNonNull(heapRef, translator.localize(LocaleResources.HEAP_SERVICE_UNAVAILABLE)); final HeapDAO heapDAO = (HeapDAO) context.getService(heapRef); final HostVMArguments args = new HostVMArguments(ctx.getArguments()); final CommandException[] ex = new CommandException[1]; final Semaphore s = new Semaphore(0); Runnable successHandler = new Runnable() { @Override public void run() { String latestHeapId = getLatestHeapId(heapDAO, args.getVM()); // latestHeapId may be null if last heap dump is actually not yet available in storage if (latestHeapId != null) { ctx.getConsole().getOutput().println(translator.localize(LocaleResources.COMMAND_HEAP_DUMP_DONE, latestHeapId).getContents()); } else { ctx.getConsole().getOutput().println(translator.localize(LocaleResources.COMMAND_HEAP_DUMP_DONE_NOID).getContents()); } s.release(); } }; Runnable errorHandler = new Runnable() { public void run() { ex[0] = new CommandException(translator.localize( LocaleResources.HEAP_DUMP_ERROR, args.getHost() .getStringID(), args.getVM().getVmId())); s.release(); } }; implementation.execute(vmInfoDAO, agentInfoDAO, args.getVM(), queue, successHandler, errorHandler); context.ungetService(vmInfoRef); context.ungetService(agentInfoRef); context.ungetService(requestQueueRef); try { s.acquire(); } catch (InterruptedException e) { // Nothing to do here, just return ASAP. } if (ex[0] != null) { throw ex[0]; } } // FIXME: storage may actually return us outdated results which do not contain the latest // heap dump(s). This can result in an empty list being returned (which we signal here by // returning null), or can result in a second dump-heap command incorrectly echoing the same // heap dump ID as the immediately prior dump-heap command. // See discussion here: http://icedtea.classpath.org/pipermail/thermostat/2016-May/018753.html static String getLatestHeapId(HeapDAO heapDao, VmRef vmRef) { Collection<HeapInfo> heapInfos = heapDao.getAllHeapInfo(vmRef); if (heapInfos.isEmpty()) { return null; } List<HeapInfo> sortedByLatest = new ArrayList<>(heapInfos); Collections.sort(sortedByLatest, new Comparator<HeapInfo>() { @Override public int compare(HeapInfo a, HeapInfo b) { return Long.compare(b.getTimeStamp(), a.getTimeStamp()); } }); HeapInfo latest = sortedByLatest.get(0); return latest.getHeapId(); } }