* Update Samples to 1.0 RC1

* Updates based on PR comments

Co-authored-by: Luke Bordonaro <lukebo@microsoft.com>
This commit is contained in:
Tristan Gibeau 2022-02-04 16:02:43 -08:00 коммит произвёл GitHub
Родитель 86ebf45b77
Коммит 169e32a6ce
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
16 изменённых файлов: 105 добавлений и 117 удалений

Просмотреть файл

@ -1,5 +1,5 @@
# Introduction
This sample plugin consists of a single Custom Data Source (CDS) that understands files with the `.txt` extension and a Custom Data Processor that processes simple text files with the following format:
This sample plugin consists of a single Processing Source that understands files with the `.txt` extension and a Custom Data Processor that processes simple text files with the following format:
```
2/4/2019 9:40:00 AM, Word1 Word2 Word3 ...
@ -15,5 +15,5 @@ See `SampleTextFile.txt` for an example of a file with this format.
2. [.NET Standard 2.0](https://dotnet.microsoft.com/download/visual-studio-sdks)
# Instructions
Please refer to [Using the SDK/Creating a Simple Custom Data Source](../../documentaiton/Using-the-SDK/Creating-a-simple-custom-data-source.md) for details
Please refer to [Using the SDK/Creating a Simple SDK Plugin](../../documentaiton/Using-the-SDK/Creating-a-simple-sdk-plugin.md) for details
on how to implement this source code.

Просмотреть файл

@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Performance.SDK" Version="0.108.0" />
<PackageReference Include="Microsoft.Performance.SDK" Version="1.0.14-rc1" />
</ItemGroup>
</Project>

Просмотреть файл

@ -17,10 +17,10 @@ namespace SampleCustomDataSource
//
// This is a sample Custom Data Processor that processes simple text files.
//
// Custom Data Processors are created in Custom Data Sources and are used to actually process the file(s).
// An instance of this Processor is created for each set of files opened whereas only one instance of the Custom Data Source is ever created.
// Note that CustomDataProcessorBase does not require any file(s) in its constructor, so another
// implementation might only store/process one file per instance.
// Custom Data Processors are created by a Processing Source and are used to actually process the source(s).
// An instance of this Processor is created for each set of sources opened whereas only one instance of the Processing Source is ever created.
// Note that CustomDataProcessor does not require any source(s) in its constructor, so another
// implementation might only store/process one source per instance.
//
// The data processor is responsible for instantiating the proper tables based on what the user has decided to enable.
// To receive a callback whenever a new table is enabled, implement OnTableEnabled. This sample does not implement
@ -28,11 +28,11 @@ namespace SampleCustomDataSource
//
//
// Derive the CustomDataProcessorBase abstract class.
// Derive the CustomDataProcessor abstract class.
//
public sealed class SimpleCustomDataProcessor
: CustomDataProcessorBase
: CustomDataProcessor
{
// The files this custom data processor will have to process
private readonly string[] filePaths;
@ -51,10 +51,8 @@ namespace SampleCustomDataSource
string[] filePaths,
ProcessorOptions options,
IApplicationEnvironment applicationEnvironment,
IProcessorEnvironment processorEnvironment,
IReadOnlyDictionary<TableDescriptor, Action<ITableBuilder, IDataExtensionRetrieval>> allTablesMapping,
IEnumerable<TableDescriptor> metadataTables)
: base(options, applicationEnvironment, processorEnvironment, allTablesMapping, metadataTables)
IProcessorEnvironment processorEnvironment)
: base(options, applicationEnvironment, processorEnvironment)
{
this.filePaths = filePaths;
}
@ -78,7 +76,7 @@ namespace SampleCustomDataSource
// In this sample, we take down the start and stop timestamps from the files
//
// Note: if you must do processing based on which tables are enabled, you would check the EnabledTables property
// (provided in the base class) on your class to see what you should do. For example, a custom data source with
// (provided in the base class) on your class to see what you should do. For example, a processing source with
// many disjoint tables may look at what tables are enabled in order to turn on only specific processors to avoid
// processing everything if it doesn't have to.
//
@ -188,7 +186,6 @@ namespace SampleCustomDataSource
protected override void BuildTableCore(
TableDescriptor tableDescriptor,
Action<ITableBuilder, IDataExtensionRetrieval> buildTableAction,
ITableBuilder tableBuilder)
{
//

Просмотреть файл

@ -8,57 +8,57 @@ using System.Linq;
namespace SampleCustomDataSource
{
//
// This is a sample Custom Data Source (CDS) that understands files with the .txt extension
// This is a sample Processing Source that understands files with the .txt extension
//
//
// In order for a CDS to be recognized, it MUST satisfy the following:
// In order for a processing source to be recognized, it MUST satisfy the following:
// a) Be a public type
// b) Have a public parameterless constructor
// c) Implement the ICustomDataSource interface
// d) Be decorated with the CustomDataSourceAttribute attribute
// c) Implement the IProcessingSource interface
// d) Be decorated with the ProcessingSourceAttribute attribute
// e) Be decorated with at least one of the derivatives of the DataSourceAttribute attribute
//
[CustomDataSource(
"{F73EACD4-1AE9-4844-80B9-EB77396781D1}", // The GUID must be unique for your Custom Data Source. You can use Visual Studio's Tools -> Create Guid… tool to create a new GUID
"Simple Data Source", // The Custom Data Source MUST have a name
"A data source to count words!")] // The Custom Data Source MUST have a description
[ProcessingSource(
"{F73EACD4-1AE9-4844-80B9-EB77396781D1}", // The GUID must be unique for your Processing Source. You can use Visual Studio's Tools -> Create Guid… tool to create a new GUID
"Simple Data Source", // The Processing Source MUST have a name
"A data source to count words!")] // The Processing Source MUST have a description
[FileDataSource(
".txt", // A file extension is REQUIRED
"Text files")] // A description is OPTIONAL. The description is what appears in the file open menu to help users understand what the file type actually is.
//
// There are two methods to creating a Custom Data Source that is recognized by the SDK:
// There are two methods to creating a Processing Source that is recognized by the SDK:
// 1. Using the helper abstract base classes
// 2. Implementing the raw interfaces
// This sample demonstrates method 1 where the CustomDataSourceBase abstract class
// helps provide a public parameterless constructor and implement the ICustomDataSource interface
//
public class SimpleCustomDataSource
: CustomDataSourceBase
public class SimpleProcessingSource
: ProcessingSource
{
private IApplicationEnvironment applicationEnvironment;
//
// Provides information about this Custom Data Source, such as the author,
// Provides information about this Processing Source, such as the author,
// a project link, licensing, etc. This information can be used by tools
// to display "About" information for your Custom Data Source. For example,
// to display "About" information for your Processing Source. For example,
// Windows Performance Analyzer (WPA) uses this information for Help->About.
//
public override CustomDataSourceInfo GetAboutInfo()
public override ProcessingSourceInfo GetAboutInfo()
{
return new CustomDataSourceInfo
return new ProcessingSourceInfo
{
//
// The copyright notice for this Custom Data Source.
// The copyright notice for this Processing Source.
//
CopyrightNotice = "Copyright 2021 Microsoft Corporation. All Rights Reserved.",
//
// The license under which this Custom Data Source may be used.
// The license under which this Processing Source may be used.
//
LicenseInfo = new LicenseInfo
{
@ -68,7 +68,7 @@ namespace SampleCustomDataSource
},
//
// A collection of the people or entities that own this Custom Data Source.
// A collection of the people or entities that own this Processing Source.
//
Owners = new[]
{
@ -91,11 +91,11 @@ namespace SampleCustomDataSource
},
//
// Any additional information you wish your users to know about this Custom Data Source.
// Any additional information you wish your users to know about this Processing Source.
//
AdditionalInformation = new[]
{
"This Custom Data Source is a sample showcasing the Performance Toolkit SDK.",
"This Processing Source is a sample showcasing the Performance Toolkit SDK.",
}
};
}
@ -121,24 +121,22 @@ namespace SampleCustomDataSource
{
//
// Create a new instance of a class implementing ICustomDataProcessor here to process the specified data sources.
// Note that you can have more advanced logic here to create different processors if you would like based on the file, or any other criteria.
// Note that you can have more advanced logic here to create different processors if you would like based on the source, or any other criteria.
// You are not restricted to always returning the same type from this method.
//
return new SimpleCustomDataProcessor(
dataSources.Select(x => x.GetUri().LocalPath).ToArray(),
dataSources.Select(x => x.Uri.LocalPath).ToArray(),
options,
this.applicationEnvironment,
processorEnvironment,
this.AllTables,
this.MetadataTables);
processorEnvironment);
}
protected override bool IsFileSupportedCore(string path)
protected override bool IsDataSourceSupportedCore(IDataSource source)
{
//
// This method is called for every file whose filetype matches the one declared in the FileDataSource attribute. It may be useful
// to peek inside the file to truly determine if you can support it, especially if your CDS supports a common
// This method is called for every data source which matches the one declared in the DataSource attribute. It may be useful
// to peek inside the source to truly determine if you can support it, especially if your data processor supports a common
// filetype like .txt or .csv.
// For this sample, we'll always return true for simplicity.
//

Просмотреть файл

@ -119,7 +119,6 @@ namespace SampleCustomDataSource.Tables
TableConfiguration.GraphColumn,
TimeColumn,
},
Layout = TableLayoutStyle.GraphAndTable,
};
//

Просмотреть файл

@ -2,7 +2,6 @@
// Licensed under the MIT License.
using Microsoft.Performance.SDK;
using Microsoft.Performance.SDK.Extensibility;
using Microsoft.Performance.SDK.Processing;
using System;
using System.Collections.Generic;
@ -16,11 +15,11 @@ using System.Xml;
namespace SqlPlugin
{
public class SqlCustomDataProcessor
: CustomDataProcessorBase
: CustomDataProcessor
{
// XML file to be parsed. For this demo, we assume we only have one data source.
// For a full implementation, this should be a collection of all file paths given
// to the Custom Data Source
// to the Processing Source
private readonly string filePath;
// Information about this data source the SDK requires for building tables
@ -38,10 +37,8 @@ namespace SqlPlugin
public SqlCustomDataProcessor(string filePath,
ProcessorOptions options,
IApplicationEnvironment applicationEnvironment,
IProcessorEnvironment processorEnvironment,
IReadOnlyDictionary<TableDescriptor, Action<ITableBuilder, IDataExtensionRetrieval>> allTablesMapping,
IEnumerable<TableDescriptor> metadataTables)
: base(options, applicationEnvironment, processorEnvironment, allTablesMapping, metadataTables)
IProcessorEnvironment processorEnvironment)
: base(options, applicationEnvironment, processorEnvironment)
{
this.filePath = filePath;
}
@ -218,9 +215,7 @@ namespace SqlPlugin
return sqlEvents;
}
protected override void BuildTableCore(TableDescriptor tableDescriptor,
Action<ITableBuilder, IDataExtensionRetrieval> createTable,
ITableBuilder tableBuilder)
protected override void BuildTableCore(TableDescriptor tableDescriptor, ITableBuilder tableBuilder)
{
//
// Normally, we would use the TableDescriptor to figure out which Table needs to be created.

Просмотреть файл

@ -6,7 +6,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Performance.SDK" Version="0.108.2" />
<PackageReference Include="Microsoft.Performance.SDK" Version="1.0.14-rc1" />
</ItemGroup>
</Project>

Просмотреть файл

@ -8,18 +8,18 @@ using System.Linq;
namespace SqlPlugin
{
[CustomDataSource("7309FAED-6A34-4FD1-8551-7AEB5006C71E",
[ProcessingSource("7309FAED-6A34-4FD1-8551-7AEB5006C71E",
"SQL Trace Data Source",
"Processes SQL trace files exported as XML.")]
[FileDataSource(".xml", "XML files exported from TRC files")]
public class SqlCustomDataSource
: CustomDataSourceBase
public class SqlProcessingSource
: ProcessingSource
{
private IApplicationEnvironment applicationEnvironment;
public override CustomDataSourceInfo GetAboutInfo()
public override ProcessingSourceInfo GetAboutInfo()
{
return new CustomDataSourceInfo
return new ProcessingSourceInfo
{
CopyrightNotice = "Copyright 2021 Microsoft Corporation. All Rights Reserved.",
LicenseInfo = new LicenseInfo
@ -56,35 +56,38 @@ namespace SqlPlugin
// plugin, every data source should be used.
//
var filePath = dataSources.First().GetUri().LocalPath;
var filePath = dataSources.First().Uri.LocalPath;
return new SqlCustomDataProcessor(filePath,
options,
this.applicationEnvironment,
processorEnvironment,
this.AllTables,
this.MetadataTables);
processorEnvironment);
}
protected override bool IsFileSupportedCore(string path)
protected override bool IsDataSourceSupportedCore(IDataSource source)
{
// Peek inside the XML and make sure our XML namespace is declared and used
using (var reader = new StreamReader(path))
if (source is FileDataSource fileDataSource)
{
// Skip first line since namespace should be on second
reader.ReadLine();
// Peek inside the XML and make sure our XML namespace is declared and used
var line = reader.ReadLine();
using (var reader = new StreamReader(fileDataSource.FullPath))
{
// Skip first line since namespace should be on second
reader.ReadLine();
if (line != null)
{
return line.Contains(SqlPluginConstants.SqlXmlNamespace);
}
else
{
return false;
var line = reader.ReadLine();
if (line != null)
{
return line.Contains(SqlPluginConstants.SqlXmlNamespace);
}
else
{
return false;
}
}
}
return false;
}
protected override void SetApplicationEnvironmentCore(IApplicationEnvironment applicationEnvironment)

Просмотреть файл

@ -162,8 +162,7 @@ namespace SqlPlugin
TableConfiguration.RightFreezeColumn,
TableConfiguration.GraphColumn,
RelativeTimestampColumn
},
Layout = TableLayoutStyle.GraphAndTable
}
};
//

Просмотреть файл

@ -1,11 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using Microsoft.Performance.SDK.Extensibility;
using Microsoft.Performance.SDK.Extensibility.SourceParsing;
using Microsoft.Performance.SDK.Processing;
using System;
using System.Collections.Generic;
namespace SqlPluginWithProcessingPipeline
{
@ -16,16 +13,14 @@ namespace SqlPluginWithProcessingPipeline
/// gets built.
/// </summary>
public class SqlCustomDataProcessorWithSourceParser
: CustomDataProcessorBaseWithSourceParser<SqlEvent, SqlSourceParser, string>
: CustomDataProcessorWithSourceParser<SqlEvent, SqlSourceParser, string>
{
internal SqlCustomDataProcessorWithSourceParser(
ISourceParser<SqlEvent, SqlSourceParser, string> sourceParser,
ProcessorOptions options,
IApplicationEnvironment applicationEnvironment,
IProcessorEnvironment processorEnvironment,
IReadOnlyDictionary<TableDescriptor, Action<ITableBuilder, IDataExtensionRetrieval>> allTablesMapping,
IEnumerable<TableDescriptor> metadataTables)
: base(sourceParser, options, applicationEnvironment, processorEnvironment, allTablesMapping, metadataTables)
IProcessorEnvironment processorEnvironment)
: base(sourceParser, options, applicationEnvironment, processorEnvironment)
{
}
}

Просмотреть файл

@ -12,7 +12,7 @@ using System.Threading;
namespace SqlPluginWithProcessingPipeline
{
public class SqlDataCooker
: BaseSourceDataCooker<SqlEvent, SqlSourceParser, string>
: SourceDataCooker<SqlEvent, SqlSourceParser, string>
{
// Backing field for this cooker's DataOutput
private readonly List<SqlEventWithRelativeTimestamp> sqlEventsWithRelativeTimestamps;

Просмотреть файл

@ -21,6 +21,6 @@ namespace SqlPluginWithProcessingPipeline
// and can be created by external binaries by just knowing the
// parser and cooker IDs defined above
public static readonly DataCookerPath CookerPath =
new DataCookerPath(SqlPluginConstants.ParserId, SqlPluginConstants.CookerId);
DataCookerPath.ForSource(SqlPluginConstants.ParserId, SqlPluginConstants.CookerId);
}
}

Просмотреть файл

@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Performance.SDK" Version="0.108.2" />
<PackageReference Include="Microsoft.Performance.SDK" Version="1.0.14-rc1" />
</ItemGroup>
</Project>

Просмотреть файл

@ -8,18 +8,18 @@ using System.Linq;
namespace SqlPluginWithProcessingPipeline
{
[CustomDataSource("D075CBD0-EAB5-41CD-81FF-66FF590D5089",
[ProcessingSource("D075CBD0-EAB5-41CD-81FF-66FF590D5089",
"SQL Trace Data Source With Data Cookers",
"Processes SQL trace files exported as XML.")]
[FileDataSource(".xml", "XML files exported from TRC files")]
public class SqlCustomDataSourceWithSourceParser
: CustomDataSourceBase
public class SqlProcessingSourceWithSourceParser
: ProcessingSource
{
private IApplicationEnvironment applicationEnvironment;
public override CustomDataSourceInfo GetAboutInfo()
public override ProcessingSourceInfo GetAboutInfo()
{
return new CustomDataSourceInfo
return new ProcessingSourceInfo
{
CopyrightNotice = "Copyright 2021 Microsoft Corporation. All Rights Reserved.",
LicenseInfo = new LicenseInfo
@ -56,36 +56,39 @@ namespace SqlPluginWithProcessingPipeline
// plugin, every data source should be used.
//
var filePath = dataSources.First().GetUri().LocalPath;
var filePath = dataSources.First().Uri.LocalPath;
var parser = new SqlSourceParser(filePath);
return new SqlCustomDataProcessorWithSourceParser(parser,
options,
this.applicationEnvironment,
processorEnvironment,
this.AllTables,
this.MetadataTables);
processorEnvironment);
}
protected override bool IsFileSupportedCore(string path)
protected override bool IsDataSourceSupportedCore(IDataSource source)
{
// Peek inside the XML and make sure our XML namespace is declared and used
using (var reader = new StreamReader(path))
if (source is FileDataSource fileDataSource)
{
// Skip first line since namespace should be on second
reader.ReadLine();
// Peek inside the XML and make sure our XML namespace is declared and used
var line = reader.ReadLine();
using (var reader = new StreamReader(fileDataSource.FullPath))
{
// Skip first line since namespace should be on second
reader.ReadLine();
if (line != null)
{
return line.Contains(SqlPluginConstants.SqlXmlNamespace);
}
else
{
return false;
var line = reader.ReadLine();
if (line != null)
{
return line.Contains(SqlPluginConstants.SqlXmlNamespace);
}
else
{
return false;
}
}
}
return false;
}
protected override void SetApplicationEnvironmentCore(IApplicationEnvironment applicationEnvironment)

Просмотреть файл

@ -17,7 +17,7 @@ namespace SqlPluginWithProcessingPipeline
{
// XML file to be parsed. For this demo, we assume we only have one data source.
// For a full implementation, this should be a collection of all file paths given
// to the Custom Data Source
// to the Processing Source
private readonly string filePath;
// Information about this data source the SDK requires for building tables

Просмотреть файл

@ -64,8 +64,7 @@ namespace SqlPluginWithProcessingPipeline
TableConfiguration.GraphColumn,
TableConfiguration.RightFreezeColumn,
RelativeTimestampColumn
},
Layout = TableLayoutStyle.GraphAndTable
}
};
tableConfig.AddColumnRole(ColumnRole.StartTime, RelativeTimestampColumn.Metadata.Guid);