Re-structure LTTng sub-project as per the Linux Tools guidelines
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.ui / src / org / eclipse / linuxtools / lttng / ui / tracecontrol / subsystems / TraceSubSystem.java
1 /*******************************************************************************
2 * Copyright (c) 2011 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Polytechnique Montréal - Initial API and implementation
11 * Bernd Hufmann - Productification, enhancements and fixes
12 *
13 *******************************************************************************/
14 package org.eclipse.linuxtools.lttng.ui.tracecontrol.subsystems;
15
16 import java.util.ArrayList;
17 import java.util.Arrays;
18 import java.util.Vector;
19 import java.util.concurrent.TimeUnit;
20
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.jface.dialogs.MessageDialog;
23 import org.eclipse.linuxtools.lttng.core.LttngConstants;
24 import org.eclipse.linuxtools.lttng.core.tracecontrol.model.ProviderResource;
25 import org.eclipse.linuxtools.lttng.core.tracecontrol.model.TargetResource;
26 import org.eclipse.linuxtools.lttng.core.tracecontrol.model.TraceResource;
27 import org.eclipse.linuxtools.lttng.core.tracecontrol.model.TraceResource.TraceState;
28 import org.eclipse.linuxtools.lttng.core.tracecontrol.model.config.TraceConfig;
29 import org.eclipse.linuxtools.lttng.core.tracecontrol.service.ILttControllerService;
30 import org.eclipse.linuxtools.lttng.core.tracecontrol.service.LttControllerServiceProxy;
31 import org.eclipse.linuxtools.lttng.ui.LTTngUiPlugin;
32 import org.eclipse.linuxtools.lttng.ui.tracecontrol.TraceControlConstants;
33 import org.eclipse.linuxtools.lttng.ui.tracecontrol.Messages;
34 import org.eclipse.linuxtools.lttng.ui.tracecontrol.actions.PauseTrace;
35 import org.eclipse.linuxtools.lttng.ui.tracecontrol.connectorservice.TraceConnectorService;
36 import org.eclipse.rse.core.events.ISystemResourceChangeEvents;
37 import org.eclipse.rse.core.events.SystemResourceChangeEvent;
38 import org.eclipse.rse.core.filters.ISystemFilter;
39 import org.eclipse.rse.core.filters.ISystemFilterPoolReference;
40 import org.eclipse.rse.core.model.IHost;
41 import org.eclipse.rse.core.model.ISystemMessageObject;
42 import org.eclipse.rse.core.model.ISystemRegistry;
43 import org.eclipse.rse.core.model.SystemMessageObject;
44 import org.eclipse.rse.core.model.SystemStartHere;
45 import org.eclipse.rse.core.subsystems.CommunicationsEvent;
46 import org.eclipse.rse.core.subsystems.ICommunicationsListener;
47 import org.eclipse.rse.core.subsystems.IConnectorService;
48 import org.eclipse.rse.core.subsystems.SubSystem;
49 import org.eclipse.rse.services.clientserver.NamePatternMatcher;
50 import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
51 import org.eclipse.rse.ui.SystemBasePlugin;
52 import org.eclipse.swt.widgets.Display;
53 import org.eclipse.tm.tcf.protocol.IToken;
54 import org.eclipse.tm.tcf.util.TCFTask;
55
56 /**
57 * <b><u>TraceSubSystem</u></b>
58 * <p>
59 * Implementation of the trace subsystem. Provides methods to initialize connections
60 * to the remote system, connection handling, filtering and retrival of remote
61 * system configuration.
62 * </p>
63 */
64 public class TraceSubSystem extends SubSystem implements ICommunicationsListener {
65
66 // ------------------------------------------------------------------------
67 // Attributes
68 // ------------------------------------------------------------------------
69 private ProviderResource[] fProviders; // master list of Providers
70
71 // ------------------------------------------------------------------------
72 // Constructors
73 // ------------------------------------------------------------------------
74 /**
75 * @param host
76 * @param connectorService
77 */
78 public TraceSubSystem(IHost host, IConnectorService connectorService) {
79 super(host, connectorService);
80 }
81
82 // ------------------------------------------------------------------------
83 // Operations
84 // ------------------------------------------------------------------------
85
86 /*
87 * (non-Javadoc)
88 * @see org.eclipse.rse.core.subsystems.SubSystem#initializeSubSystem(org.eclipse.core.runtime.IProgressMonitor)
89 */
90 @Override
91 public void initializeSubSystem(IProgressMonitor monitor) {
92 getConnectorService().addCommunicationsListener(this);
93 }
94
95 /*
96 * (non-Javadoc)
97 * @see org.eclipse.rse.core.subsystems.SubSystem#uninitializeSubSystem(org.eclipse.core.runtime.IProgressMonitor)
98 */
99 @Override
100 public void uninitializeSubSystem(IProgressMonitor monitor) {
101 }
102
103 /*
104 * (non-Javadoc)
105 * @see org.eclipse.rse.core.subsystems.SubSystem#getObjectWithAbsoluteName(java.lang.String)
106 *
107 * For drag and drop, and clipboard support of remote objects.
108 *
109 * Return the remote object within the subsystem that corresponds to the specified unique ID. Because each subsystem maintains it's own objects, it's the responsability of the subsystem to determine how an ID (or key) for a given object maps to
110 * the real object. By default this returns null.
111 */
112 @Override
113 public Object getObjectWithAbsoluteName(String key) {
114 return null;
115 }
116
117 /*
118 * (non-Javadoc)
119 * @see org.eclipse.rse.core.subsystems.SubSystem#internalResolveFilterString(java.lang.String, org.eclipse.core.runtime.IProgressMonitor)
120 */
121 @Override
122 protected Object[] internalResolveFilterString(String filterString, IProgressMonitor monitor) throws java.lang.reflect.InvocationTargetException, java.lang.InterruptedException {
123
124 ProviderResource[] allProviders;
125
126 try {
127 allProviders = getAllProviders();
128 } catch (SystemMessageException e) {
129 SystemBasePlugin.logError("TraceSubSystem", e); //$NON-NLS-1$
130 Object[] children = new SystemMessageObject[1];
131 children[0] = new SystemMessageObject(e.getSystemMessage(), ISystemMessageObject.MSGTYPE_ERROR, null);
132 return children;
133 }
134
135 // Now, subset master list, based on filter string...
136 NamePatternMatcher subsetter = new NamePatternMatcher(filterString);
137 Vector<ProviderResource> v = new Vector<ProviderResource>();
138 for (int idx = 0; idx < allProviders.length; idx++) {
139 if (subsetter.matches(allProviders[idx].getName())) {
140 v.addElement(allProviders[idx]);
141 }
142 }
143 return allProviders;
144 }
145 /*
146 * (non-Javadoc)
147 * @see org.eclipse.rse.core.subsystems.SubSystem#internalResolveFilterString(java.lang.Object, java.lang.String, org.eclipse.core.runtime.IProgressMonitor)
148 */
149 @Override
150 protected Object[] internalResolveFilterString(Object parent, String filterString, IProgressMonitor monitor) throws java.lang.reflect.InvocationTargetException, java.lang.InterruptedException {
151 return null;
152 }
153
154 /* (non-Javadoc)
155 * @see org.eclipse.rse.core.subsystems.SubSystem#filterEventFilterCreated(java.lang.Object, org.eclipse.rse.core.filters.ISystemFilter)
156 */
157 @Override
158 public void filterEventFilterCreated(Object selectedObject, ISystemFilter newFilter) {
159 super.filterEventFilterCreated(selectedObject, newFilter);
160 ISystemRegistry registry = SystemStartHere.getSystemRegistry();
161 registry.fireEvent(new SystemResourceChangeEvent(this, ISystemResourceChangeEvents.EVENT_REFRESH, null));
162 }
163
164 /* (non-Javadoc)
165 * @see org.eclipse.rse.core.subsystems.SubSystem#filterEventFilterPoolReferenceCreated(org.eclipse.rse.core.filters.ISystemFilterPoolReference)
166 */
167 @Override
168 public void filterEventFilterPoolReferenceCreated(ISystemFilterPoolReference newPoolRef) {
169 super.filterEventFilterPoolReferenceCreated(newPoolRef);
170 if (getSystemFilterPoolReferenceManager().getSystemFilterPoolReferenceCount() == 1) {
171 ISystemRegistry registry = SystemStartHere.getSystemRegistry();
172 registry.fireEvent(new SystemResourceChangeEvent(this, ISystemResourceChangeEvents.EVENT_REFRESH, null));
173 }
174 }
175
176 /**
177 * Retrieves all provider resources from the remote system and updates local references.
178 *
179 * @return provider resources
180 * @throws SystemMessageException
181 * @throws InterruptedException
182 */
183 public ProviderResource[] getAllProviders() throws SystemMessageException, InterruptedException {
184 ProviderResource[] providers = createProviders();
185 if (fProviders == null) {
186 fProviders = providers;
187 }
188 else {
189 for (int i = 0; i < fProviders.length; i++) {
190 for (int j = 0; j < providers.length; j++) {
191 if(fProviders[i].getName().equals(providers[j].getName())) {
192 // Check if all targets already exist
193 fProviders[i].refreshTargets(providers[j].getTargets());
194 }
195 }
196 }
197 }
198 return fProviders;
199 }
200
201 /**
202 * Get the list of all targets.
203 *
204 * @return targets The list of targets.
205 * @throws SystemMessageException
206 */
207 public TargetResource[] getAllTargets() throws SystemMessageException {
208 ArrayList<TargetResource> targets = new ArrayList<TargetResource>();
209 if (fProviders != null) {
210 for (int i = 0; i < fProviders.length; i++) {
211 targets.addAll(Arrays.asList(fProviders[i].getTargets()));
212 }
213 }
214 return targets.toArray(new TargetResource[0]);
215 }
216
217 /**
218 * Get the list of all traces.
219 *
220 * @return traces The list of traces.
221 * @throws SystemMessageException
222 */
223 public TraceResource[] getAllTraces() throws SystemMessageException {
224 ArrayList<TraceResource> traces = new ArrayList<TraceResource>();
225 if (fProviders != null) {
226 for (int i = 0; i < fProviders.length; i++) {
227 ProviderResource provider = fProviders[i];
228 int numTargets = provider.getTargets().length;
229 for (int j = 0; j < numTargets; j++) {
230 TargetResource target = provider.getTargets()[j];
231 if (provider.getName().equals(LttngConstants.Lttng_Provider_Kernel)) {
232 traces.addAll(Arrays.asList(target.getTraces()));
233 }
234 }
235 }
236 }
237 return traces.toArray(new TraceResource[0]);
238 }
239
240 /**
241 * Get the list of all traces for given provider and target.
242 *
243 * @param provider
244 * @param target
245 * @returns trace resources
246 */
247 public TraceResource[] getAllTraces(String providerName, String targetName) throws SystemMessageException {
248 ArrayList<TraceResource> traces = new ArrayList<TraceResource>();
249 ProviderResource selectedProvider = null;
250 if (fProviders != null) {
251 for (int i = 0; i < fProviders.length; i++) {
252 ProviderResource provider = fProviders[i];
253 if (provider.getName().equals(providerName)) {
254 selectedProvider = fProviders[i];
255 break;
256 }
257 }
258
259 if (selectedProvider != null) {
260 int numTargets = selectedProvider.getTargets().length;
261 for (int j = 0; j < numTargets; j++) {
262 TargetResource target = selectedProvider.getTargets()[j];
263 if (target.getName().equals(targetName)) {
264 traces.addAll(Arrays.asList(target.getTraces()));
265 break;
266 }
267 }
268 }
269 }
270 return traces.toArray(new TraceResource[0]);
271 }
272
273 /**
274 * Finds a trace resource within a given provider and target for a given trace name
275 *
276 * @param targetName - target name to be searched
277 * @param traceName - trace name to be searched
278 * @return trace resource or null (if not found)
279 */
280 public TraceResource findTrace(String providerName, String targetName, String traceName) {
281 TraceResource trace = null;
282 TraceResource[] traces;
283 try {
284 traces = getAllTraces(providerName, targetName);
285 for (int i = 0; i < traces.length; i++) {
286 if (traces[i].getName().equals(traceName)) {
287 trace = traces[i];
288 break;
289 }
290 }
291 } catch (SystemMessageException e) {
292 SystemBasePlugin.logError("TraceSubSystem", e); //$NON-NLS-1$
293 }
294
295 return trace;
296 }
297
298 /*
299 * Retrieves the providers from the remote system.
300 */
301 private ProviderResource[] createProviders() throws SystemMessageException {
302 ProviderResource[] providers = null;
303 try {
304
305 final ILttControllerService service = getControllerService();
306
307 // Create future task
308 providers = new TCFTask<ProviderResource[]>() {
309 @Override
310 public void run() {
311
312 // Get provider using Lttng controller service proxy
313 service.getProviders(new ILttControllerService.DoneGetProviders() {
314
315 @Override
316 public void doneGetProviders(IToken token, Exception error, String[] str) {
317 if (error != null) {
318 // Notify with error
319 error(error);
320 return;
321 }
322
323 // Create provider list
324 ProviderResource[] providers = new ProviderResource[str.length];
325
326 for (int i = 0; i < str.length; i++) {
327 ProviderResource tempProvider = new ProviderResource(TraceSubSystem.this);
328 tempProvider.setName(str[i]);
329 providers[i] = tempProvider;
330 }
331
332 // Notify with provider list
333 done(providers);
334 }
335 });
336 }}.get(TraceControlConstants.DEFAULT_TCF_TASK_TIMEOUT, TimeUnit.SECONDS);
337 } catch (Exception e) {
338 if (e instanceof SystemMessageException) throw (SystemMessageException)e;
339 throw new SystemMessageException(LTTngUiPlugin.getDefault().getMessage(e));
340 }
341
342 for (int i = 0; i < providers.length; i++) {
343 createTargets(providers[i]);
344 }
345
346 return providers;
347 }
348
349 /*
350 * Retrieves the targets for given provider from the remote system.
351 */
352 private TargetResource[] createTargets(final ProviderResource provider) throws SystemMessageException {
353 TargetResource[] targets;
354 try {
355 final ILttControllerService service = getControllerService();
356
357 // Create future task
358 targets = new TCFTask<TargetResource[]>() {
359 @Override
360 public void run() {
361
362 // Get targets using Lttng controller service proxy
363 service.getTargets(provider.getName(), new ILttControllerService.DoneGetTargets() {
364
365 @Override
366 public void doneGetTargets(IToken token, Exception error, String[] str) {
367 if (error != null) {
368 // Notify with error
369 error(error);
370 return;
371 }
372
373 // Create targets
374 TargetResource[] targets = new TargetResource[str.length];
375 for (int i = 0; i < str.length; i++) {
376 TargetResource tempTarget = new TargetResource(TraceSubSystem.this);
377 tempTarget.setName(str[i]);
378 tempTarget.setParent(provider);
379 targets[i] = tempTarget;
380 }
381 // Notify with target list
382 done(targets);
383 }
384 });
385 }}.get(TraceControlConstants.DEFAULT_TCF_TASK_TIMEOUT, TimeUnit.SECONDS);
386 } catch (Exception e) {
387 provider.setTargets(new TargetResource[0]);
388 if (e instanceof SystemMessageException) throw (SystemMessageException)e;
389 throw new SystemMessageException(LTTngUiPlugin.getDefault().getMessage(e));
390 }
391
392 provider.setTargets(targets);
393 for (int i = 0; i < targets.length; i++) {
394 if (targets[i].getParent().getName().equals(LttngConstants.Lttng_Provider_Kernel)) {
395 createTraces(targets[i]);
396 }
397 }
398
399 return targets;
400 }
401
402 /*
403 * Retrieves the trace instances for a given target from the remote system.
404 */
405 private TraceResource[] createTraces(final TargetResource target) throws SystemMessageException {
406 TraceResource[] traces;
407 try {
408 final ILttControllerService service = getControllerService();
409
410 // Create future task
411 traces = new TCFTask<TraceResource[]>() {
412 @Override
413 public void run() {
414 // Get targets using Lttng controller service proxy
415 service.getTraces(target.getParent().getName(), target.getName(), new ILttControllerService.DoneGetTraces() {
416
417 @Override
418 public void doneGetTraces(IToken token, Exception error, String[] str) {
419 if (error != null) {
420 // Notify with error
421 error(error);
422 return;
423 }
424
425 // Create trace list
426 TraceResource[] traces = new TraceResource[str.length];
427 for (int i = 0; i < str.length; i++) {
428 TraceResource trace = new TraceResource(TraceSubSystem.this, service);
429 trace.setName(str[i]);
430 trace.setParent(target);
431 trace.setTraceState(TraceState.CREATED);
432 traces[i] = trace;
433 }
434
435 // Notify with trace list
436 done(traces);
437 }
438 });
439 }}.get(TraceControlConstants.DEFAULT_TCF_TASK_TIMEOUT, TimeUnit.SECONDS);
440 } catch (Exception e) {
441 target.setTraces(new TraceResource[0]);
442 if (e instanceof SystemMessageException) throw (SystemMessageException)e;
443 throw new SystemMessageException(LTTngUiPlugin.getDefault().getMessage(e));
444 }
445
446 target.setTraces(traces);
447
448 // get active trace information (is only supported for kernel traces)
449 createTraceConfigurations(target, traces);
450 return traces;
451 }
452
453 /*
454 * Retrieves the trace configurations for the given trace from the remote system.
455 */
456 private void createTraceConfigurations(final TargetResource target, TraceResource[] traces) throws SystemMessageException {
457 if (!target.isUst() && (traces.length > 0)) {
458 // get active traces
459 String[] activeTraceNames;
460 try {
461 final ILttControllerService service = getControllerService();
462 activeTraceNames = new TCFTask<String[]>() {
463 @Override
464 public void run() {
465 // Get targets using Lttng controller service proxy
466 service.getActiveTraces(target.getParent().getName(), target.getName(), new ILttControllerService.DoneGetActiveTraces() {
467
468 @Override
469 public void doneGetActiveTraces(IToken token, Exception error, String[] str) {
470 if (error != null) {
471 // Notify with error
472 error(error);
473 return;
474 }
475
476 // Notify with active trace list
477 done(str);
478 }
479 });
480 }}.get(TraceControlConstants.DEFAULT_TCF_TASK_TIMEOUT, TimeUnit.SECONDS);
481 } catch (Exception e) {
482 if (e instanceof SystemMessageException) throw (SystemMessageException)e;
483 throw new SystemMessageException(LTTngUiPlugin.getDefault().getMessage(e));
484 }
485
486 // get active trace information
487 for (int j = 0; j < activeTraceNames.length; j++) {
488 final TraceResource trace = target.getTrace(activeTraceNames[j]);
489 if (trace != null) {
490 // get trace info
491 TraceConfig traceConfig;
492
493 // Currently, if a trace is active then all the setup commands have been executed
494 // and it's either started or paused. However, currently there is no means to retrieve
495 // the state (paused or started). So we set it to state started (even if trace is not actually
496 // started on target the command pause will be successful. However, the use will have the wrong
497 // impression that the trace is started) Therefore ... the state needs to be retrievable.
498 // TODO update to correct state if there is a possibility to retrieve the correct state.
499 trace.setTraceState(TraceState.STARTED);
500 try {
501 final ILttControllerService service = getControllerService();
502 traceConfig = new TCFTask<TraceConfig>() {
503 @Override
504 public void run() {
505 // Get targets using Lttng controller service proxy
506 service.getActiveTraceInfo(target.getParent().getName(), target.getName(), trace.getName(), new ILttControllerService.DoneGetActiveTraceInfo() {
507
508 @Override
509 public void doneGetActiveTraceInfo(IToken token, Exception error, String[] str) {
510 if (error != null) {
511 // Notify with error
512 error(error);
513 return;
514 }
515
516 TraceConfig config = new TraceConfig();
517 config.setIsAppend(false);
518 if (str[3].equals("true")) { //$NON-NLS-1$
519 config.setMode(TraceConfig.FLIGHT_RECORDER_MODE);
520 }
521 else if (str[1].equals("true")) { //$NON-NLS-1$
522 config.setMode(TraceConfig.NORMAL_MODE);
523 }
524
525 if (str[5].equals(TraceConfig.InvalidTracePath)) {
526 config.setNetworkTrace(true);
527 }
528 else {
529 config.setNetworkTrace(false);
530 }
531 config.setNumChannel(Integer.valueOf(str[0]));
532 config.setTraceName(trace.getName());
533 config.setTracePath(str[5]);
534 config.setTraceTransport(TraceControlConstants.Lttng_Trace_Transport_Relay);
535
536 // Notify with active trace list
537 done(config);
538 }
539 });
540 }}.get(TraceControlConstants.DEFAULT_TCF_TASK_TIMEOUT, TimeUnit.SECONDS);
541 } catch (Exception e) {
542 if (e instanceof SystemMessageException) throw (SystemMessageException)e;
543 throw new SystemMessageException(LTTngUiPlugin.getDefault().getMessage(e));
544 }
545 trace.setTraceConfig(traceConfig);
546 }
547 }
548 }
549 }
550
551 /*
552 * (non-Javadoc)
553 * @see org.eclipse.rse.core.subsystems.ICommunicationsListener#communicationsStateChange(org.eclipse.rse.core.subsystems.CommunicationsEvent)
554 */
555 @Override
556 public void communicationsStateChange(CommunicationsEvent e) {
557 switch (e.getState())
558 {
559 case CommunicationsEvent.BEFORE_CONNECT :
560 break;
561 case CommunicationsEvent.AFTER_CONNECT :
562 break;
563 case CommunicationsEvent.BEFORE_DISCONNECT :
564
565 try {
566 final TraceResource[] traces = getAllTraces();
567
568 StringBuffer traceNames = new StringBuffer(""); //$NON-NLS-1$
569 String filler = ""; //$NON-NLS-1$
570 for (int j = 0; j < traces.length; j++) {
571 // For network traces, ask user to pause tracing
572 if (traces[j].isNetworkTraceAndStarted()) {
573 traceNames.append(filler);
574 traceNames.append(traces[j].getName());
575 }
576 filler = ", "; //$NON-NLS-1$
577 }
578 if (!"".equals(traceNames.toString())) { //$NON-NLS-1$
579 final String finalTraceNames = traceNames.toString();
580 Display.getDefault().syncExec(new Runnable() {
581
582 @Override
583 public void run() {
584 MessageDialog.openWarning(Display.getDefault().getActiveShell(), Messages.Ltt_ShutdownWarning, Messages.Ltt_NetworkTraceRunningWarning + ":\n" + finalTraceNames); //$NON-NLS-1$
585
586 // Pause tracing
587 PauseTrace pauseAction = new PauseTrace();
588 pauseAction.setSelectedTraces(new ArrayList<TraceResource>(Arrays.asList(traces)));
589 pauseAction.run(null);
590 try {
591 Thread.sleep(2000); // allow time for target to pause traces before disconnecting the channel
592 } catch (InterruptedException e) {
593 e.printStackTrace();
594 }
595 }
596 });
597 }
598
599 if (fProviders != null) {
600 // reset all providers and it's children
601 for (int i = 0; i < fProviders.length; i++) {
602 fProviders[i].removeAllTargets();
603 }
604 fProviders = null;
605 }
606
607 } catch (SystemMessageException ex) {
608 SystemBasePlugin.logError("TraceSubSystem", ex); //$NON-NLS-1$
609 }
610 break;
611 case CommunicationsEvent.AFTER_DISCONNECT :
612 getConnectorService().removeCommunicationsListener(this);
613 break;
614 case CommunicationsEvent.CONNECTION_ERROR :
615 // TODO notify user about the lost connection ?!
616 getConnectorService().removeCommunicationsListener(this);
617 try {
618 this.disconnect();
619 } catch (Exception e1) {
620 // Nothing to do
621 }
622 break;
623 default :
624 break;
625 }
626 }
627
628 /*
629 * (non-Javadoc)
630 * @see org.eclipse.rse.core.subsystems.ICommunicationsListener#isPassiveCommunicationsListener()
631 */
632 @Override
633 public boolean isPassiveCommunicationsListener() {
634 return true;
635 }
636
637 /**
638 * Returns the trace controller service.
639 *
640 * @return trace controller service
641 * @throws Exception
642 */
643 public LttControllerServiceProxy getControllerService() throws Exception {
644 return ((TraceConnectorService)getConnectorService()).getControllerService();
645 }
646 }
This page took 0.046118 seconds and 5 git commands to generate.