tmf: Update text trace unit tests
[deliverable/tracecompass.git] / org.eclipse.tracecompass.lttng2.control.ui / src / org / eclipse / tracecompass / internal / lttng2 / control / ui / views / service / LTTngControlServiceMI.java
CommitLineData
0df4af5f 1/**********************************************************************
ed902a2b 2 * Copyright (c) 2014, 2015 Ericsson
0df4af5f
JRJ
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 * Jonathan Rajotte - Initial support for machine interface lttng 2.6
e5237dc5 11 * Bernd Hufmann - Fix check for live session
0df4af5f
JRJ
12 **********************************************************************/
13
9bc60be7 14package org.eclipse.tracecompass.internal.lttng2.control.ui.views.service;
0df4af5f
JRJ
15
16import java.io.IOException;
17import java.io.StringReader;
6651c1b4 18import java.math.BigInteger;
0df4af5f
JRJ
19import java.net.URL;
20import java.util.ArrayList;
21import java.util.List;
22import java.util.regex.Matcher;
23
24import javax.xml.parsers.DocumentBuilder;
25import javax.xml.parsers.DocumentBuilderFactory;
26import javax.xml.parsers.ParserConfigurationException;
27
28import org.eclipse.core.commands.ExecutionException;
29import org.eclipse.core.runtime.IProgressMonitor;
67f8cadd 30import org.eclipse.osgi.util.NLS;
9bc60be7
AM
31import org.eclipse.tracecompass.internal.lttng2.control.core.model.IBaseEventInfo;
32import org.eclipse.tracecompass.internal.lttng2.control.core.model.IChannelInfo;
33import org.eclipse.tracecompass.internal.lttng2.control.core.model.IDomainInfo;
34import org.eclipse.tracecompass.internal.lttng2.control.core.model.IEventInfo;
35import org.eclipse.tracecompass.internal.lttng2.control.core.model.IFieldInfo;
36import org.eclipse.tracecompass.internal.lttng2.control.core.model.IProbeEventInfo;
37import org.eclipse.tracecompass.internal.lttng2.control.core.model.ISessionInfo;
38import org.eclipse.tracecompass.internal.lttng2.control.core.model.ISnapshotInfo;
39import org.eclipse.tracecompass.internal.lttng2.control.core.model.IUstProviderInfo;
40import org.eclipse.tracecompass.internal.lttng2.control.core.model.LogLevelType;
41import org.eclipse.tracecompass.internal.lttng2.control.core.model.TraceDomainType;
42import org.eclipse.tracecompass.internal.lttng2.control.core.model.TraceEnablement;
43import org.eclipse.tracecompass.internal.lttng2.control.core.model.TraceEventType;
44import org.eclipse.tracecompass.internal.lttng2.control.core.model.TraceLogLevel;
45import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.BaseEventInfo;
46import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.BufferType;
47import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.ChannelInfo;
48import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.DomainInfo;
49import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.EventInfo;
50import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.FieldInfo;
51import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.ProbeEventInfo;
52import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.SessionInfo;
53import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.SnapshotInfo;
54import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.UstProviderInfo;
55import org.eclipse.tracecompass.internal.lttng2.control.ui.views.handlers.XmlMiValidationErrorHandler;
56import org.eclipse.tracecompass.internal.lttng2.control.ui.views.messages.Messages;
ec619615
BH
57import org.eclipse.tracecompass.tmf.remote.core.shell.ICommandResult;
58import org.eclipse.tracecompass.tmf.remote.core.shell.ICommandShell;
0df4af5f
JRJ
59import org.w3c.dom.Document;
60import org.w3c.dom.Node;
61import org.w3c.dom.NodeList;
62import org.xml.sax.InputSource;
63import org.xml.sax.SAXException;
64
65/**
66 * Service for sending LTTng trace control commands to remote host via machine
67 * interface mode.
68 *
69 * @author Jonathan Rajotte
70 */
71public class LTTngControlServiceMI extends LTTngControlService {
72
73 // ------------------------------------------------------------------------
74 // Attributes
75 // ------------------------------------------------------------------------
76
77 private final DocumentBuilder fDocumentBuilder;
78
79 // ------------------------------------------------------------------------
80 // Constructors
81 // ------------------------------------------------------------------------
82
83 /**
84 * Constructor
85 *
86 * @param shell
87 * the command shell implementation to use
88 * @param xsdUrl
89 * the xsd schema file for validation
90 * @throws ExecutionException
91 * if the creation of the Schema and DocumentBuilder objects
92 * fails
93 */
94 public LTTngControlServiceMI(ICommandShell shell, URL xsdUrl) throws ExecutionException {
95 super(shell);
96
97 DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
98 docBuilderFactory.setValidating(false);
99
100 // TODO: Add xsd validation for machine interface via mi_lttng.xsd from LTTng
101 try {
102 fDocumentBuilder = docBuilderFactory.newDocumentBuilder();
103 } catch (ParserConfigurationException e) {
104 throw new ExecutionException(Messages.TraceControl_XmlDocumentBuilderError, e);
105 }
106
107 fDocumentBuilder.setErrorHandler(new XmlMiValidationErrorHandler());
108
109 }
110
111 /**
112 * Generate a Document object from an array of String.
113 *
114 * @param xmlStrings
115 * array of strings representing an xml input
116 * @return Document generated from strings input
117 * @throws ExecutionException
118 * when parsing has failed
119 */
120 private Document getDocumentFromStrings(String[] xmlStrings) throws ExecutionException {
121 StringBuilder concatenedString = new StringBuilder();
122 for (String string : xmlStrings) {
123 concatenedString.append(string);
124 }
125 InputSource stream = new InputSource(new StringReader(concatenedString.toString()));
126
127 Document document;
128 try {
129 document = fDocumentBuilder.parse(stream);
130 } catch (SAXException | IOException e) {
131 throw new ExecutionException(Messages.TraceControl_XmlParsingError, e);
132 }
133 return document;
134
135 }
136
137 /**
138 * Parse, populate and set the internal LTTngVersion variable
139 *
140 * @param xmlOutput
141 * the mi xml output of lttng version
142 * @throws ExecutionException
143 * when xml extraction fail
144 */
145 public void setVersion(String[] xmlOutput) throws ExecutionException {
146 Document doc = getDocumentFromStrings(xmlOutput);
147 NodeList element = doc.getElementsByTagName(MIStrings.VERSION);
148 int major = 0;
149 int minor = 0;
150 int patchLevel = 0;
151 String license = ""; //$NON-NLS-1$
152 String commit = ""; //$NON-NLS-1$
153 String name = ""; //$NON-NLS-1$
154 String description = ""; //$NON-NLS-1$
155 String url = ""; //$NON-NLS-1$
156 String fullVersion = ""; //$NON-NLS-1$
157 if (element.getLength() == 1) {
158 NodeList child = element.item(0).getChildNodes();
159 // Get basic information
160 for (int i = 0; i < child.getLength(); i++) {
161 Node node = child.item(i);
162 switch (node.getNodeName()) {
163 case MIStrings.VERSION_MAJOR:
164 major = Integer.parseInt(node.getTextContent());
165 break;
166 case MIStrings.VERSION_MINOR:
167 minor = Integer.parseInt(node.getTextContent());
168 break;
169 case MIStrings.VERSION_PATCH_LEVEL:
170 patchLevel = Integer.parseInt(node.getTextContent());
171 break;
172 case MIStrings.VERSION_COMMIT:
173 commit = node.getTextContent();
174 break;
175 case MIStrings.VERSION_DESCRIPTION:
176 description = node.getTextContent();
177 break;
178 case MIStrings.VERSION_LICENSE:
179 license = node.getTextContent();
180 break;
181 case MIStrings.VERSION_NAME:
182 name = node.getTextContent();
183 break;
184 case MIStrings.VERSION_STR:
185 fullVersion = node.getTextContent();
186 break;
187 case MIStrings.VERSION_WEB:
188 url = node.getTextContent();
189 break;
190 default:
191 break;
192 }
193 }
194 setVersion(new LttngVersion(major, minor, patchLevel, license, commit, name, description, url, fullVersion));
195 } else {
196 throw new ExecutionException(Messages.TraceControl_UnsupportedVersionError);
197 }
198 }
199
200 @Override
201 public String[] getSessionNames(IProgressMonitor monitor) throws ExecutionException {
774a7993
BH
202 List<String> command = createCommand(LTTngControlServiceConstants.COMMAND_LIST);
203 ICommandResult result = executeCommand(command, monitor);
0df4af5f
JRJ
204
205 Document doc = getDocumentFromStrings(result.getOutput());
206
207 NodeList elements = doc.getElementsByTagName(MIStrings.NAME);
208
209 ArrayList<String> retArray = new ArrayList<>();
210 for (int i = 0; i < elements.getLength(); i++) {
211 Node node = elements.item(i);
212 if (node.getParentNode().getNodeName().equalsIgnoreCase(MIStrings.SESSION)) {
213 retArray.add(node.getTextContent());
214 }
215 }
216 return retArray.toArray(new String[retArray.size()]);
217 }
218
219 @Override
220 public ISessionInfo getSession(String sessionName, IProgressMonitor monitor) throws ExecutionException {
774a7993
BH
221 List<String> command = createCommand(LTTngControlServiceConstants.COMMAND_LIST, sessionName);
222 ICommandResult result = executeCommand(command, monitor);
0df4af5f
JRJ
223
224 ISessionInfo sessionInfo = new SessionInfo(sessionName);
225 Document document = getDocumentFromStrings(result.getOutput());
226
227 NodeList sessionsNode = document.getElementsByTagName(MIStrings.SESSION);
228 // There should be only one session
229 if (sessionsNode.getLength() != 1) {
517c0261 230 throw new ExecutionException(NLS.bind(Messages.TraceControl_MiInvalidNumberOfElementError, MIStrings.SESSION));
0df4af5f
JRJ
231 }
232
233 // Populate session information
67f8cadd
JRJ
234 Node rawSession = sessionsNode.item(0);
235 parseSession(sessionInfo, rawSession);
236
237 // Fetch the snapshot info
238 if (sessionInfo.isSnapshotSession()) {
239 ISnapshotInfo snapshot = getSnapshotInfo(sessionName, monitor);
240 sessionInfo.setSnapshotInfo(snapshot);
241 }
242
243 return sessionInfo;
244 }
245
246 /**
247 * @param sessionInfo
248 * @param rawSession
249 * @throws ExecutionException
250 */
251 private void parseSession(ISessionInfo sessionInfo, Node rawSession) throws ExecutionException {
252 if (!rawSession.getNodeName().equalsIgnoreCase(MIStrings.SESSION)) {
253 throw new ExecutionException(Messages.TraceControl_MiInvalidElementError);
254 }
255 NodeList rawSessionInfos = rawSession.getChildNodes();
0df4af5f
JRJ
256 for (int i = 0; i < rawSessionInfos.getLength(); i++) {
257 Node rawInfo = rawSessionInfos.item(i);
258 switch (rawInfo.getNodeName()) {
67f8cadd
JRJ
259 case MIStrings.NAME:
260 sessionInfo.setName(rawInfo.getTextContent());
261 break;
0df4af5f
JRJ
262 case MIStrings.PATH:
263 sessionInfo.setSessionPath(rawInfo.getTextContent());
264 break;
265 case MIStrings.ENABLED:
266 sessionInfo.setSessionState(rawInfo.getTextContent());
267 break;
268 case MIStrings.SNAPSHOT_MODE:
269 if (rawInfo.getTextContent().equals(LTTngControlServiceConstants.TRUE_NUMERICAL)) {
270 // real name will be set later
271 ISnapshotInfo snapshotInfo = new SnapshotInfo(""); //$NON-NLS-1$
272 sessionInfo.setSnapshotInfo(snapshotInfo);
273 }
274 break;
275 case MIStrings.LIVE_TIMER_INTERVAL:
ae02b8eb 276 long liveDelay = Long.parseLong(rawInfo.getTextContent());
e5237dc5 277 if ((liveDelay > 0 && (liveDelay <= LTTngControlServiceConstants.MAX_LIVE_TIMER_INTERVAL))) {
ae02b8eb
MAL
278 sessionInfo.setLive(true);
279 sessionInfo.setLiveUrl(SessionInfo.DEFAULT_LIVE_NETWORK_URL);
280 sessionInfo.setLivePort(SessionInfo.DEFAULT_LIVE_PORT);
281 sessionInfo.setLiveDelay(liveDelay);
282 }
0df4af5f
JRJ
283 break;
284 case MIStrings.DOMAINS:
285 // Extract the domains node
286 NodeList rawDomains = rawInfo.getChildNodes();
287 IDomainInfo domain = null;
288 for (int j = 0; j < rawDomains.getLength(); j++) {
289 if (rawDomains.item(j).getNodeName().equalsIgnoreCase(MIStrings.DOMAIN)) {
290 domain = parseDomain(rawDomains.item(j));
291 sessionInfo.addDomain(domain);
292 }
293 }
294 break;
295 default:
296 break;
297 }
298 }
299
300 if (!sessionInfo.isSnapshotSession()) {
301 Matcher matcher = LTTngControlServiceConstants.TRACE_NETWORK_PATTERN.matcher(sessionInfo.getSessionPath());
302 if (matcher.matches()) {
303 sessionInfo.setStreamedTrace(true);
304 }
305 }
0df4af5f
JRJ
306 }
307
308 /**
f4401569
JRJ
309 * Parse a raw domain XML node to a IDomainInfo object
310 *
311 * @param rawDomain
0df4af5f 312 * a domain xml node
f4401569
JRJ
313 * @return a populated {@link DomainInfo} object
314 * @throws ExecutionException
315 * when missing required xml element (type)
0df4af5f 316 */
f4401569
JRJ
317 protected IDomainInfo parseDomain(Node rawDomain) throws ExecutionException {
318 IDomainInfo domain = null;
319 // Get the type
320 Node rawType = getFirstOf(rawDomain.getChildNodes(), MIStrings.TYPE);
321 if (rawType == null) {
322 throw new ExecutionException(Messages.TraceControl_MiMissingRequiredError);
323 }
324 String rawTypeString = rawType.getTextContent().toLowerCase();
325 TraceDomainType domainType = TraceDomainType.valueOfString(rawTypeString);
326 switch (domainType) {
327 case KERNEL:
328 domain = new DomainInfo(Messages.TraceControl_KernelProviderDisplayName);
329 domain.setIsKernel(true);
330 break;
331 case UST:
332 domain = new DomainInfo(Messages.TraceControl_UstGlobalDomainDisplayName);
333 domain.setIsKernel(false);
334 break;
335 case JUL:
336 /**
337 * TODO: Support for JUL JUL substructure and semantic is not the
338 * same as a regular UST or Kernel Domain There is no channel under
339 * JUL domain only events. The channel is activated in UST Channel
340 */
341 domain = new DomainInfo(Messages.TraceControl_JULDomainDisplayName);
342 domain.setIsKernel(false);
343 break;
344 case UNKNOWN:
345 domain = new DomainInfo(Messages.TraceControl_UnknownDomainDisplayName);
346 domain.setIsKernel(false);
347 break;
348 default:
349 throw new ExecutionException(Messages.TraceControl_MiInvalidElementError);
350 }
351
352 NodeList rawInfos = rawDomain.getChildNodes();
353 for (int i = 0; i < rawInfos.getLength(); i++) {
354 Node rawInfo = rawInfos.item(i);
355 switch (rawInfo.getNodeName()) {
356 case MIStrings.BUFFER_TYPE:
357 BufferType bufferType = BufferType.valueOfString(rawInfo.getTextContent());
358 domain.setBufferType(bufferType);
359 break;
360 case MIStrings.CHANNELS:
361 ArrayList<IChannelInfo> channels = new ArrayList<>();
362 parseChannels(rawInfo.getChildNodes(), channels);
363 if (channels.size() > 0) {
364 domain.setChannels(channels);
365 }
366 break;
367 default:
368 break;
369 }
370 }
371
372 return domain;
373 }
374
375 /**
376 * Parse a list of raw channel XML node into an ArrayList of IChannelInfo
377 *
378 * @param rawChannes
379 * List of raw channel XML node
380 * @param channels
381 * the parsed channels list
382 * @throws ExecutionException
383 * when missing required xml element (type)
384 */
385 private static void parseChannels(NodeList rawChannels, ArrayList<IChannelInfo> channels) throws ExecutionException {
386 IChannelInfo channel = null;
387 for (int i = 0; i < rawChannels.getLength(); i++) {
388 Node rawChannel = rawChannels.item(i);
389 if (rawChannel.getNodeName().equalsIgnoreCase(MIStrings.CHANNEL)) {
390 channel = new ChannelInfo(""); //$NON-NLS-1$
391
392 // Populate the channel
393 NodeList rawInfos = rawChannel.getChildNodes();
394 Node rawInfo = null;
395 for (int j = 0; j < rawInfos.getLength(); j++) {
396 rawInfo = rawInfos.item(j);
397 switch (rawInfo.getNodeName()) {
398 case MIStrings.NAME:
399 channel.setName(rawInfo.getTextContent());
400 break;
401 case MIStrings.ENABLED:
402 channel.setState(TraceEnablement.valueOfString(rawInfo.getTextContent()));
403 break;
404 case MIStrings.EVENTS:
405 List<IEventInfo> events = new ArrayList<>();
406 getEventInfo(rawInfo.getChildNodes(), events);
407 channel.setEvents(events);
408 break;
409 case MIStrings.ATTRIBUTES:
410 NodeList rawAttributes = rawInfo.getChildNodes();
411 for (int k = 0; k < rawAttributes.getLength(); k++) {
412 Node attribute = rawAttributes.item(k);
413 switch (attribute.getNodeName()) {
414 case MIStrings.OVERWRITE_MODE:
415 channel.setOverwriteMode(!LTTngControlServiceConstants.OVERWRITE_MODE_ATTRIBUTE_FALSE_MI.equalsIgnoreCase(attribute.getTextContent()));
416 break;
417 case MIStrings.SUBBUF_SIZE:
418 channel.setSubBufferSize(Long.valueOf(attribute.getTextContent()));
419 break;
420 case MIStrings.NUM_SUBBUF:
421 channel.setNumberOfSubBuffers(Integer.valueOf(attribute.getTextContent()));
422 break;
423 case MIStrings.SWITCH_TIMER_INTERVAL:
424 channel.setSwitchTimer(Long.valueOf(attribute.getTextContent()));
425 break;
426 case MIStrings.READ_TIMER_INTERVAL:
427 channel.setReadTimer(Long.valueOf(attribute.getTextContent()));
428 break;
429 case MIStrings.OUTPUT_TYPE:
430 channel.setOutputType(attribute.getTextContent());
431 break;
432 case MIStrings.TRACEFILE_SIZE:
433 channel.setMaxSizeTraceFiles(Integer.parseInt(attribute.getTextContent()));
434 break;
435 case MIStrings.TRACEFILE_COUNT:
436 channel.setMaxNumberTraceFiles(Integer.parseInt(attribute.getTextContent()));
437 break;
438 case MIStrings.LIVE_TIMER_INTERVAL:
439 // TODO: currently not supported by tmf
440 break;
441 default:
442 break;
443 }
444 }
445 break;
446 default:
447 break;
448 }
449 }
450 channels.add(channel);
451 }
452 }
453
0df4af5f
JRJ
454 }
455
456 @Override
457 public ISnapshotInfo getSnapshotInfo(String sessionName, IProgressMonitor monitor) throws ExecutionException {
4f9e6a03
JRJ
458 // TODO A session can have multiple snapshot output. This need to be
459 // supported in the future.
460 // Currently the SessionInfo object does not support multiple snashot
461 // output.
462 // For now only keep the last one.
774a7993
BH
463 List<String> command = createCommand(LTTngControlServiceConstants.COMMAND_SNAPSHOT, LTTngControlServiceConstants.COMMAND_LIST_SNAPSHOT_OUTPUT, LTTngControlServiceConstants.OPTION_SESSION, sessionName);
464 ICommandResult result = executeCommand(command, monitor);
4f9e6a03
JRJ
465 Document doc = getDocumentFromStrings(result.getOutput());
466 NodeList rawSnapshotsOutputs = doc.getElementsByTagName(MIStrings.SNAPSHOT_OUTPUTS);
467
468 ISnapshotInfo snapshotInfo = new SnapshotInfo(""); //$NON-NLS-1$
469
470 // TODO: tmf does not have a notion of a ctrl url.
471 for (int i = 0; i < rawSnapshotsOutputs.getLength(); i++) {
472 NodeList rawSnapshotOutput = rawSnapshotsOutputs.item(i).getChildNodes();
473 for (int j = 0; j < rawSnapshotOutput.getLength(); j++) {
474 Node rawInfo = rawSnapshotOutput.item(j);
475 switch (rawInfo.getNodeName()) {
476 case MIStrings.ID:
477 snapshotInfo.setId(Integer.parseInt(rawInfo.getTextContent()));
478 break;
479 case MIStrings.NAME:
480 snapshotInfo.setName(rawInfo.getTextContent());
481 break;
482 case MIStrings.SNAPSHOT_CTRL_URL:
483 // The use of the ctrl_url for the snapshot path is to assure
484 // basic support. Refactoring is necessary in lttng and
485 // tmf side.
486 // See http://bugs.lttng.org/issues/828 (+comment)
487 snapshotInfo.setSnapshotPath(rawInfo.getTextContent());
488 break;
489 default:
490 break;
491 }
492 }
493 }
494
495 // Check if the snapshot output is Streamed
496 Matcher matcher2 = LTTngControlServiceConstants.TRACE_NETWORK_PATTERN.matcher(snapshotInfo.getSnapshotPath());
497 if (matcher2.matches()) {
498 snapshotInfo.setStreamedSnapshot(true);
499 }
500
501 return snapshotInfo;
0df4af5f
JRJ
502 }
503
504 @Override
505 public List<IBaseEventInfo> getKernelProvider(IProgressMonitor monitor) throws ExecutionException {
774a7993
BH
506 List<String> command = createCommand(LTTngControlServiceConstants.COMMAND_LIST, LTTngControlServiceConstants.OPTION_KERNEL);
507 ICommandResult result = executeCommand(command, monitor, false);
0df4af5f
JRJ
508 List<IBaseEventInfo> events = new ArrayList<>();
509
517c0261
JRJ
510 if (isError(result) && result.getErrorOutput() != null) {
511 // Ignore the following 2 cases:
512 // Spawning a session daemon
513 // Error: Unable to list kernel events
514 // or:
515 // Error: Unable to list kernel events
516 if (ignoredPattern(result.getErrorOutput(), LTTngControlServiceConstants.LIST_KERNEL_NO_KERNEL_PROVIDER_PATTERN)) {
517 return events;
518 }
774a7993 519 throw new ExecutionException(Messages.TraceControl_CommandError + toCommandString(command));
0df4af5f
JRJ
520 }
521
522 Document document = getDocumentFromStrings(result.getOutput());
523 NodeList rawEvents = document.getElementsByTagName(MIStrings.EVENT);
f4401569 524 getBaseEventInfo(rawEvents, events);
0df4af5f
JRJ
525 return events;
526 }
527
528 @Override
529 public List<IUstProviderInfo> getUstProvider(IProgressMonitor monitor) throws ExecutionException {
774a7993 530 List<String> command = createCommand(LTTngControlServiceConstants.COMMAND_LIST, LTTngControlServiceConstants.OPTION_UST);
0df4af5f 531 // Get the field to
774a7993 532 command.add(LTTngControlServiceConstants.OPTION_FIELDS);
0df4af5f
JRJ
533
534 // Execute
774a7993 535 ICommandResult result = executeCommand(command, monitor, false);
0df4af5f
JRJ
536 List<IUstProviderInfo> allProviders = new ArrayList<>();
537
517c0261
JRJ
538 if (isError(result) && result.getErrorOutput() != null) {
539 // Ignore the following 2 cases:
540 // Spawning a session daemon
541 // Error: Unable to list UST events: Listing UST events failed
542 // or:
543 // Error: Unable to list UST events: Listing UST events failed
544 if (ignoredPattern(result.getErrorOutput(), LTTngControlServiceConstants.LIST_UST_NO_UST_PROVIDER_PATTERN)) {
545 return allProviders;
546 }
774a7993 547 throw new ExecutionException(Messages.TraceControl_CommandError + toCommandString(command));
0df4af5f
JRJ
548 }
549
550 Document document = getDocumentFromStrings(result.getOutput());
551 NodeList rawProviders = document.getElementsByTagName(MIStrings.PID);
552
553 IUstProviderInfo providerInfo = null;
554
555 for (int i = 0; i < rawProviders.getLength(); i++) {
556 Node provider = rawProviders.item(i);
557 Node name = getFirstOf(provider.getChildNodes(), MIStrings.NAME);
558 if (name == null) {
559 throw new ExecutionException(Messages.TraceControl_MiInvalidProviderError);
560 }
561 providerInfo = new UstProviderInfo(name.getTextContent());
562
563 // Populate provider
564 NodeList infos = provider.getChildNodes();
565 for (int j = 0; j < infos.getLength(); j++) {
566 Node info = infos.item(j);
567 switch (info.getNodeName()) {
568 case MIStrings.PID_ID:
569 providerInfo.setPid(Integer.parseInt(info.getTextContent()));
570 break;
571 case MIStrings.EVENTS:
572 List<IBaseEventInfo> events = new ArrayList<>();
573 NodeList rawEvents = info.getChildNodes();
f4401569 574 getBaseEventInfo(rawEvents, events);
0df4af5f
JRJ
575 providerInfo.setEvents(events);
576 break;
577 default:
578 break;
579 }
580 }
581 allProviders.add(providerInfo);
582 }
583
584 return allProviders;
585 }
586
587 @Override
588 public ISessionInfo createSession(ISessionInfo sessionInfo, IProgressMonitor monitor) throws ExecutionException {
67f8cadd
JRJ
589 if (sessionInfo.isStreamedTrace()) {
590 return createStreamedSession(sessionInfo, monitor);
591 }
592
774a7993 593 List<String> command = prepareSessionCreationCommand(sessionInfo);
67f8cadd 594
774a7993 595 ICommandResult result = executeCommand(command, monitor);
67f8cadd
JRJ
596
597 Document document = getDocumentFromStrings(result.getOutput());
598 NodeList sessions = document.getElementsByTagName(MIStrings.SESSION);
599
600 // Number of session should be equal to 1
601 if (sessions.getLength() != 1) {
602 throw new ExecutionException(Messages.TraceControl_CommandError + " " + command + "\n" //$NON-NLS-1$//$NON-NLS-2$
603 + NLS.bind(Messages.TraceControl_UnexpectedNumberOfElementError, MIStrings.SESSION) + " " + sessions.getLength()); //$NON-NLS-1$
604 }
605
606 // Fetch a session from output
607 ISessionInfo outputSession = new SessionInfo(""); //$NON-NLS-1$
608 parseSession(outputSession, sessions.item(0));
609
610 // Verify session name
611 if ((outputSession.getName().equals("")) || (!"".equals(sessionInfo.getName()) && !outputSession.getName().equals(sessionInfo.getName()))) { //$NON-NLS-1$ //$NON-NLS-2$
612 // Unexpected name returned
613 throw new ExecutionException(Messages.TraceControl_CommandError + " " + command + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
614 Messages.TraceControl_UnexpectedNameError + ": " + outputSession.getName()); //$NON-NLS-1$
615 }
616
617 // Verify session path
618 if (!sessionInfo.isSnapshotSession() &&
619 ((outputSession.getSessionPath() == null) || ((sessionInfo.getSessionPath() != null) && (!outputSession.getSessionPath().contains(sessionInfo.getSessionPath()))))) {
620 // Unexpected path
621 throw new ExecutionException(Messages.TraceControl_CommandError + " " + command + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
622 Messages.TraceControl_UnexpectedPathError + ": " + outputSession.getName()); //$NON-NLS-1$
623 }
624
625 if (sessionInfo.isSnapshotSession()) {
626 // Make it a snapshot session - content of snapshot info need to
627 // set afterwards using getSession() or getSnapshotInfo()
628 outputSession.setSnapshotInfo(new SnapshotInfo("")); //$NON-NLS-1$
629 }
630
631 return outputSession;
632 }
633
634 private ISessionInfo createStreamedSession(ISessionInfo sessionInfo, IProgressMonitor monitor) throws ExecutionException {
635
774a7993 636 List<String> command = prepareStreamedSessionCreationCommand(sessionInfo);
67f8cadd 637
774a7993 638 ICommandResult result = executeCommand(command, monitor);
67f8cadd
JRJ
639
640 Document document = getDocumentFromStrings(result.getOutput());
641 NodeList sessions = document.getElementsByTagName(MIStrings.SESSION);
642
643 // Number of session should be equal to 1
644 if (sessions.getLength() != 1) {
645 throw new ExecutionException(Messages.TraceControl_CommandError + " " + command + "\n" //$NON-NLS-1$//$NON-NLS-2$
646 + NLS.bind(Messages.TraceControl_UnexpectedNumberOfElementError, MIStrings.SESSION) + " " + sessions.getLength()); //$NON-NLS-1$
647 }
648
649 // Fetch a session from output
650 ISessionInfo outputSession = new SessionInfo(""); //$NON-NLS-1$
651 parseSession(outputSession, sessions.item(0));
652
653 // Verify session name
654 if ((outputSession.getName().equals("")) || (!"".equals(sessionInfo.getName()) && !outputSession.getName().equals(sessionInfo.getName()))) { //$NON-NLS-1$ //$NON-NLS-2$
655 // Unexpected name returned
656 throw new ExecutionException(Messages.TraceControl_CommandError + " " + command + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
657 Messages.TraceControl_UnexpectedNameError + ": " + outputSession.getName()); //$NON-NLS-1$
658 }
659
660 sessionInfo.setName(outputSession.getName());
661 sessionInfo.setStreamedTrace(true);
662
663 // Verify session path
664 if (sessionInfo.getNetworkUrl() != null) {
665 if (!sessionInfo.isSnapshotSession() && (outputSession.getSessionPath() == null)) {
666 // Unexpected path
667 throw new ExecutionException(Messages.TraceControl_CommandError + " " + command + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
668 Messages.TraceControl_UnexpectedPathError + ": " + outputSession.getName()); //$NON-NLS-1$
669 }
670
671 if (sessionInfo.isSnapshotSession()) {
672 sessionInfo.setStreamedTrace(false);
673 } else {
674 sessionInfo.setSessionPath(outputSession.getSessionPath());
675 // Check file protocol
676 Matcher matcher = LTTngControlServiceConstants.TRACE_FILE_PROTOCOL_PATTERN.matcher(outputSession.getSessionPath());
677 if (matcher.matches()) {
678 sessionInfo.setStreamedTrace(false);
679 }
680 }
681 }
682
683 // When using controlUrl and dataUrl the full session path is not known
684 // yet
685 // and will be set later on when listing the session
686 return sessionInfo;
687
0df4af5f
JRJ
688 }
689
690 @Override
691 public void destroySession(String sessionName, IProgressMonitor monitor) throws ExecutionException {
774a7993 692 List<String> command = createCommand(LTTngControlServiceConstants.COMMAND_DESTROY_SESSION, sessionName);
0df4af5f 693
774a7993 694 ICommandResult result = executeCommand(command, monitor, false);
517c0261 695 String[] errorOutput = result.getErrorOutput();
0df4af5f 696
517c0261
JRJ
697 if (isError(result) && (errorOutput != null)) {
698 // Don't treat this as an error
699 if (ignoredPattern(errorOutput, LTTngControlServiceConstants.SESSION_NOT_FOUND_ERROR_PATTERN)) {
700 return;
0df4af5f 701
517c0261 702 }
774a7993 703 throw new ExecutionException(Messages.TraceControl_CommandError + " " + toCommandString(command) + "\n" + formatOutput(result)); //$NON-NLS-1$ //$NON-NLS-2$
517c0261
JRJ
704 }
705
706 // Check for action effect
707 Document doc = getDocumentFromStrings(result.getOutput());
708 NodeList sessions = doc.getElementsByTagName(MIStrings.SESSION);
709 if (sessions.getLength() != 1) {
710 throw new ExecutionException(NLS.bind(Messages.TraceControl_MiInvalidNumberOfElementError, MIStrings.SESSION));
711 }
0df4af5f 712
517c0261
JRJ
713 Node rawSessionName = getFirstOf(sessions.item(0).getChildNodes(), MIStrings.NAME);
714 if (rawSessionName == null) {
715 throw new ExecutionException(Messages.TraceControl_MiMissingRequiredError);
716 }
717
718 // Validity check
719 if (!rawSessionName.getTextContent().equals(sessionName)) {
720 throw new ExecutionException(NLS.bind(Messages.TraceControl_UnexpectedValueError, rawSessionName.getTextContent(), sessionName));
721 }
0df4af5f
JRJ
722 }
723
0df4af5f
JRJ
724 /**
725 * @param strings
726 * array of string that make up a command line
727 * @return string buffer with created command line
728 */
729 @Override
774a7993
BH
730 protected List<String> createCommand(String... strings) {
731 List<String> command = new ArrayList<>();
732 command.add(LTTngControlServiceConstants.CONTROL_COMMAND);
11b78e10 733 List<String> groupOption = getTracingGroupOption();
774a7993 734 if (!groupOption.isEmpty()) {
11b78e10 735 command.addAll(groupOption);
774a7993 736 }
11b78e10
BH
737 command.add(LTTngControlServiceConstants.CONTROL_COMMAND_MI_OPTION);
738 command.add(LTTngControlServiceConstants.CONTROL_COMMAND_MI_XML);
0df4af5f 739 for (String string : strings) {
774a7993 740 command.add(string);
0df4af5f
JRJ
741 }
742 return command;
743 }
744
745 /**
f4401569
JRJ
746 * @param xmlBaseEvents
747 * a Node list of base xml event element
0df4af5f
JRJ
748 * @param events
749 * list of event generated by the parsing of the xml event
750 * element
751 * @throws ExecutionException
752 * when a raw event is not a complete/valid xml event
753 */
f4401569 754 private static void getBaseEventInfo(NodeList xmlBaseEvents, List<IBaseEventInfo> events) throws ExecutionException {
0df4af5f 755 IBaseEventInfo eventInfo = null;
f4401569
JRJ
756 for (int i = 0; i < xmlBaseEvents.getLength(); i++) {
757 NodeList rawInfos = xmlBaseEvents.item(i).getChildNodes();
0df4af5f 758 // Search for name
f4401569 759 if (xmlBaseEvents.item(i).getNodeName().equalsIgnoreCase(MIStrings.EVENT)) {
0df4af5f
JRJ
760 Node rawName = getFirstOf(rawInfos, MIStrings.NAME);
761 if (rawName == null) {
762 throw new ExecutionException(Messages.TraceControl_MiMissingRequiredError);
763 }
764 eventInfo = new BaseEventInfo(rawName.getTextContent());
765
766 // Populate the event
767 for (int j = 0; j < rawInfos.getLength(); j++) {
768 Node infoNode = rawInfos.item(j);
769 switch (infoNode.getNodeName()) {
770 case MIStrings.TYPE:
771 eventInfo.setEventType(infoNode.getTextContent());
772 break;
773 case MIStrings.LOGLEVEL:
774 eventInfo.setLogLevel(infoNode.getTextContent());
775 break;
776 case MIStrings.EVENT_FIELDS:
777 List<IFieldInfo> fields = new ArrayList<>();
778 getFieldInfo(infoNode.getChildNodes(), fields);
779 eventInfo.setFields(fields);
780 break;
781 default:
782 break;
783 }
784 }
785 events.add(eventInfo);
786 }
787 }
788 }
789
f4401569
JRJ
790 /**
791 * @param xmlBaseEvents
792 * a Node list of xml event element linked to a session
793 * @param events
794 * list of event generated by the parsing of the xml event
795 * element
796 * @throws ExecutionException
797 * when a raw event is not a complete/valid xml event
798 */
799 static void getEventInfo(NodeList xmlEvents, List<IEventInfo> events) throws ExecutionException {
800 IEventInfo eventInfo = null;
801 for (int i = 0; i < xmlEvents.getLength(); i++) {
802 NodeList rawInfos = xmlEvents.item(i).getChildNodes();
803 // Search for name
804 if (xmlEvents.item(i).getNodeName().equalsIgnoreCase(MIStrings.EVENT)) {
805 Node rawName = getFirstOf(rawInfos, MIStrings.NAME);
806 if (rawName == null) {
807 throw new ExecutionException(Messages.TraceControl_MiMissingRequiredError);
808 }
809
810 eventInfo = new EventInfo(rawName.getTextContent());
811
812 // Basic information
813 for (int j = 0; j < rawInfos.getLength(); j++) {
814 Node infoNode = rawInfos.item(j);
815 switch (infoNode.getNodeName()) {
816 case MIStrings.TYPE:
817 eventInfo.setEventType(infoNode.getTextContent());
818 break;
819 case MIStrings.LOGLEVEL_TYPE:
820 eventInfo.setLogLevelType(LogLevelType.valueOfString(infoNode.getTextContent()));
821 break;
822 case MIStrings.LOGLEVEL:
823 eventInfo.setLogLevel(TraceLogLevel.valueOfString(infoNode.getTextContent()));
824 break;
825 case MIStrings.ENABLED:
826 eventInfo.setState(TraceEnablement.valueOfString(infoNode.getTextContent()));
827 break;
828 case MIStrings.FILTER:
829 // TODO
830 // See bug 334 http://bugs.lttng.org/issues/334 from
831 // LTTng
1ed5ac2e 832 // For now we emulate the non-mi behavior and simply put
f4401569
JRJ
833 // "with filter"
834 eventInfo.setFilterExpression("with filter"); //$NON-NLS-1$
835 break;
836 case MIStrings.EXCLUSION:
1ed5ac2e 837 // TODO: Currently not supported by tmf
f4401569
JRJ
838 // ExclusionS element is ignored
839 break;
840 default:
841 break;
842 }
843 }
844
845 boolean isProbeFunction = (eventInfo.getEventType().equals(TraceEventType.PROBE)) || (eventInfo.getEventType().equals(TraceEventType.FUNCTION));
846 if (isProbeFunction) {
847 IProbeEventInfo probeEvent = new ProbeEventInfo(eventInfo);
848 eventInfo = probeEvent;
f4401569
JRJ
849
850 Node rawDataNode = null;
851 switch (probeEvent.getEventType()) {
f4401569 852 case FUNCTION:
6651c1b4
JRJ
853 case PROBE: {
854 // get attributes
855 Node rawAttributes = getFirstOf(rawInfos, MIStrings.ATTRIBUTES);
856 if (rawAttributes == null) {
857 throw new ExecutionException(Messages.TraceControl_MiMissingRequiredError);
858 }
859 rawDataNode = getFirstOf(rawAttributes.getChildNodes(), MIStrings.PROBE_ATTRIBUTES);
f4401569 860 break;
6651c1b4 861 }
f4401569
JRJ
862 case SYSCALL:
863 case TRACEPOINT:
864 case UNKNOWN:
865 default:
866 throw new ExecutionException(Messages.TraceControl_MiInvalidElementError);
867 }
868
869 if (rawDataNode == null) {
870 throw new ExecutionException(Messages.TraceControl_MiInvalidElementError);
871 }
872
873 // Extract info
874 NodeList rawDatas = rawDataNode.getChildNodes();
875 for (int j = 0; j < rawDatas.getLength(); j++) {
876 Node rawData = rawDatas.item(j);
877 switch (rawData.getNodeName()) {
878 case MIStrings.SYMBOL_NAME:
879 probeEvent.setSymbol(rawData.getTextContent());
880 break;
881 case MIStrings.ADDRESS:
6651c1b4 882 probeEvent.setAddress(String.format("%#016x", new BigInteger(rawData.getTextContent()))); //$NON-NLS-1$
f4401569
JRJ
883 break;
884 case MIStrings.OFFSET:
6651c1b4 885 probeEvent.setOffset(String.format("%#016x", new BigInteger(rawData.getTextContent()))); //$NON-NLS-1$
f4401569
JRJ
886 break;
887 default:
888 break;
889 }
890 }
891 }
892
893 // Syscalls does not have name.
894 // Let put one to make sure this is user friendly via UI
895 if (eventInfo.getEventType().equals(TraceEventType.SYSCALL)) {
896 eventInfo.setName(TraceEventType.SYSCALL.getInName());
897 }
898
899 // Add the event
900 events.add(eventInfo);
901 }
902 }
903 }
904
0df4af5f
JRJ
905 /**
906 * @param fieldsList
907 * a list of xml event_field element
908 * @param fields
909 * a list of field generated by xml parsing
910 * @throws ExecutionException
911 * when parsing fail or required elements are missing
912 */
913 private static void getFieldInfo(NodeList fieldsList, List<IFieldInfo> fields) throws ExecutionException {
914 IFieldInfo fieldInfo = null;
915 for (int i = 0; i < fieldsList.getLength(); i++) {
916 Node field = fieldsList.item(i);
917 if (field.getNodeName().equalsIgnoreCase(MIStrings.EVENT_FIELD)) {
918 // Get name
919 Node name = getFirstOf(field.getChildNodes(), MIStrings.NAME);
920 if (name == null) {
921 throw new ExecutionException(Messages.TraceControl_MiMissingRequiredError);
922 }
923 fieldInfo = new FieldInfo(name.getTextContent());
924
925 // Populate the field information
926 NodeList infos = field.getChildNodes();
927 for (int j = 0; j < infos.getLength(); j++) {
928 Node info = infos.item(j);
929 switch (info.getNodeName()) {
930 case MIStrings.TYPE:
931 fieldInfo.setFieldType(info.getTextContent());
932 break;
933 default:
934 break;
935 }
936 }
937 fields.add(fieldInfo);
938 }
939 }
940 }
941
942 /**
943 * Retrieve the fist instance of a given node with tag name equal to tagName
944 * parameter
945 *
946 * @param nodeList
947 * the list of Node to search against
948 * @param tagName
949 * the tag name of the desired node
950 * @return the first occurrence of a node with a tag name equals to tagName
951 */
952 private static Node getFirstOf(NodeList nodeList, String tagName) {
953 Node node = null;
954 for (int i = 0; i < nodeList.getLength(); i++) {
955 if (nodeList.item(i).getNodeName() == tagName) {
956 node = nodeList.item(i);
957 break;
958 }
959 }
960 return node;
961 }
962
963}
This page took 0.100102 seconds and 5 git commands to generate.