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