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