├── .gitignore ├── Go └── src │ ├── receive │ └── receive.go │ └── send │ └── send.go └── ServiceBusExamples ├── ApplicationInsights.DataGenerator ├── App.config ├── ApplicationInsights.DataGenerator.csproj ├── DataGenerator.cs ├── Program.cs └── Properties │ └── AssemblyInfo.cs ├── MichalBialecki.com.ConsoleAppMagic ├── MichalBialecki.com.ConsoleAppMagic.csproj ├── Program.cs └── larry3d.flf ├── MichalBialecki.com.Data.Dto ├── File.cs ├── Folder.cs ├── FoldersAndFilesProvider.cs ├── IFoldersAndFilesProvider.cs └── MichalBialecki.com.Data.Dto.csproj ├── MichalBialecki.com.Egnyte.Examples ├── App.config ├── Files │ └── CopyBigFiles.cs ├── MichalBialecki.com.Egnyte.Examples.csproj ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── MichalBialecki.com.Functions ├── Function1.cs ├── MichalBialecki.com.Functions.csproj ├── host.json └── local.settings.json ├── MichalBialecki.com.NetCore.Console ├── MichalBialecki.com.NetCore.Console.csproj ├── PriceComparer │ ├── Offer.cs │ ├── PriceComparerInit.cs │ ├── Product.cs │ ├── Seller.cs │ └── SellerOffer.cs ├── Program.cs └── Users │ ├── UserDto.cs │ ├── UsersClient.cs │ └── UsersService.cs ├── MichalBialecki.com.NetCore.Web ├── CacheHelper.cs ├── Connected Services │ └── Application Insights │ │ └── ConnectedService.json ├── CsvExport │ ├── Attributes │ │ ├── ExportAttribute.cs │ │ ├── ProductAnalyticsAttribute.cs │ │ └── ProductComparerExportAttribute.cs │ ├── CsvExportController.cs │ ├── Data │ │ ├── ExportProperty.cs │ │ ├── IProductGenerator.cs │ │ ├── ProductDto.cs │ │ └── ProductGenerator.cs │ ├── GenericExportService.cs │ ├── ICsvExport.cs │ ├── IProductAnalyticsExportService.cs │ ├── IProductComparerExportService.cs │ ├── ProductAnalyticsExportService.cs │ ├── ProductComparerExportService.cs │ └── SimpleCsvExport.cs ├── Documents │ ├── Document.cs │ └── DocumentsController.cs ├── MichalBialecki.com.NetCore.Web.csproj ├── Program.cs ├── Properties │ ├── PublishProfiles │ │ └── MichalBialeckicomNetCoreWeb20180417060938 - Web Deploy.pubxml │ └── launchSettings.json ├── Startup.cs ├── Users │ ├── IUserService.cs │ ├── IUsersRepository.cs │ ├── UserDto.cs │ ├── UserService.cs │ ├── UsersController.cs │ └── UsersRepository.cs ├── appsettings.Development.json └── appsettings.json ├── MichalBialecki.com.Odata.Web ├── App_Start │ ├── FilterConfig.cs │ ├── RouteConfig.cs │ └── WebApiConfig.cs ├── ApplicationInsights.config ├── Controllers │ ├── DocumentsController.cs │ ├── FoldersController.cs │ └── ValuesController.cs ├── Dtos │ └── Document.cs ├── Global.asax ├── Global.asax.cs ├── MichalBialecki.com.Odata.Web.csproj ├── Properties │ └── AssemblyInfo.cs ├── Web.Debug.config ├── Web.Release.config ├── Web.config ├── XmlHelper.cs └── packages.config ├── MichalBialecki.com.PriceComparer.Web ├── Controllers │ ├── ProductController.cs │ └── SellerController.cs ├── MichalBialecki.com.PriceComparer.Web.csproj ├── Offer.cs ├── Product.cs ├── Program.cs ├── Repositories │ ├── IProductRepository.cs │ ├── ISellerRepository.cs │ ├── ProductRepository.cs │ └── SellerRepository.cs ├── Seller.cs ├── SellerOffer.cs └── Startup.cs ├── MichalBialecki.com.ServiceBus.Examples ├── AccountEntity.cs ├── App.config ├── MessageReceiverOld.cs ├── MichalBialecki.com.ServiceBus.Examples.csproj ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── SimpleExamples.cs ├── TableStorageService.cs └── packages.config ├── MichalBialecki.com.ServiceBusCore.Examples ├── AccountTransfer │ ├── Account.cs │ ├── AccountTransferMessage.cs │ ├── AccountTransferService.cs │ ├── BalanceUpdateMessage.cs │ └── TableStorageService.cs ├── MessageReceiver.cs ├── MessageSender.cs ├── MichalBialecki.com.ServiceBusCore.Examples.csproj ├── ProductRatingUpdateMessage.cs ├── Program.cs ├── ServiceBusManager.cs └── appsettings.json ├── MichalBialecki.com.sln ├── ServiceBusExamples.Dto ├── ServiceBusExamples.Dto.csproj └── SimpleDto.cs └── ServiceBusExamples.MessagesSender.Web ├── ConfigurationHelper.cs ├── Connected Services └── Application Insights │ └── ConnectedService.json ├── Controllers ├── FoldersController.cs └── MessagesController.cs ├── DocumentDbService.cs ├── Dto ├── DocumentDto.cs └── ProductRatingUpdateMessage.cs ├── ProductRatingUpdatesGenerator.cs ├── Program.cs ├── Properties ├── PublishProfiles │ └── ServiceBusExamplesMessagesSenderWeb20171221111633 - Web Deploy.pubxml └── launchSettings.json ├── SendMessageDto.cs ├── ServiceBusExamples.MessagesSender.NetCore.Web.csproj ├── Services ├── SimpleBufferMessagesService.cs └── TimerBufferMessagesService.cs ├── Startup.cs ├── appsettings.Development.json └── appsettings.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Download this file using PowerShell v3 under Windows with the following comand: 2 | # Invoke-WebRequest https://gist.githubusercontent.com/kmorcinek/2710267/raw/ -OutFile .gitignore 3 | # or wget: 4 | # wget --no-check-certificate http://gist.githubusercontent.com/kmorcinek/2710267/raw/.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.sln.docstates 10 | 11 | # Build results 12 | 13 | [Dd]ebug/ 14 | [Rr]elease/ 15 | x64/ 16 | build/ 17 | [Bb]in/ 18 | [Oo]bj/ 19 | 20 | # NuGet Packages 21 | *.nupkg 22 | # The packages folder can be ignored because of Package Restore 23 | **/packages/* 24 | # except build/, which is used as an MSBuild target. 25 | !**/packages/build/ 26 | # Uncomment if necessary however generally it will be regenerated when needed 27 | #!**/packages/repositories.config 28 | 29 | # MSTest test Results 30 | [Tt]est[Rr]esult*/ 31 | [Bb]uild[Ll]og.* 32 | 33 | *_i.c 34 | *_p.c 35 | *.ilk 36 | *.meta 37 | *.obj 38 | *.pch 39 | *.pdb 40 | *.pgc 41 | *.pgd 42 | *.rsp 43 | *.sbr 44 | *.tlb 45 | *.tli 46 | *.tlh 47 | *.tmp 48 | *.tmp_proj 49 | *.log 50 | *.vspscc 51 | *.vssscc 52 | .builds 53 | *.pidb 54 | *.log 55 | *.scc 56 | 57 | # OS generated files # 58 | .DS_Store* 59 | Icon? 60 | 61 | # Visual C++ cache files 62 | ipch/ 63 | *.aps 64 | *.ncb 65 | *.opensdf 66 | *.sdf 67 | *.cachefile 68 | 69 | # Visual Studio profiler 70 | *.psess 71 | *.vsp 72 | *.vspx 73 | 74 | # Guidance Automation Toolkit 75 | *.gpState 76 | 77 | # ReSharper is a .NET coding add-in 78 | _ReSharper*/ 79 | *.[Rr]e[Ss]harper 80 | 81 | # TeamCity is a build add-in 82 | _TeamCity* 83 | 84 | # DotCover is a Code Coverage Tool 85 | *.dotCover 86 | 87 | # NCrunch 88 | *.ncrunch* 89 | .*crunch*.local.xml 90 | 91 | # Installshield output folder 92 | [Ee]xpress/ 93 | 94 | # DocProject is a documentation generator add-in 95 | DocProject/buildhelp/ 96 | DocProject/Help/*.HxT 97 | DocProject/Help/*.HxC 98 | DocProject/Help/*.hhc 99 | DocProject/Help/*.hhk 100 | DocProject/Help/*.hhp 101 | DocProject/Help/Html2 102 | DocProject/Help/html 103 | 104 | # Click-Once directory 105 | publish/ 106 | 107 | # Publish Web Output 108 | *.Publish.xml 109 | 110 | # Windows Azure Build Output 111 | csx 112 | *.build.csdef 113 | 114 | # Windows Store app package directory 115 | AppPackages/ 116 | 117 | # Others 118 | *.Cache 119 | ClientBin/ 120 | [Ss]tyle[Cc]op.* 121 | ~$* 122 | *~ 123 | *.dbmdl 124 | *.[Pp]ublish.xml 125 | *.pfx 126 | *.publishsettings 127 | modulesbin/ 128 | tempbin/ 129 | 130 | # EPiServer Site file (VPP) 131 | AppData/ 132 | 133 | # RIA/Silverlight projects 134 | Generated_Code/ 135 | 136 | # Backup & report files from converting an old project file to a newer 137 | # Visual Studio version. Backup files are not needed, because we have git ;-) 138 | _UpgradeReport_Files/ 139 | Backup*/ 140 | UpgradeLog*.XML 141 | UpgradeLog*.htm 142 | 143 | # vim 144 | *.txt~ 145 | *.swp 146 | *.swo 147 | 148 | # svn 149 | .svn 150 | 151 | # Remainings from resolvings conflicts in Source Control 152 | *.orig 153 | 154 | # SQL Server files 155 | **/App_Data/*.mdf 156 | **/App_Data/*.ldf 157 | **/App_Data/*.sdf 158 | 159 | 160 | #LightSwitch generated files 161 | GeneratedArtifacts/ 162 | _Pvt_Extensions/ 163 | ModelManifest.xml 164 | 165 | # ========================= 166 | # Windows detritus 167 | # ========================= 168 | 169 | # Windows image file caches 170 | Thumbs.db 171 | ehthumbs.db 172 | 173 | # Folder config file 174 | Desktop.ini 175 | 176 | # Recycle Bin used on file shares 177 | $RECYCLE.BIN/ 178 | 179 | # Mac desktop service store files 180 | .DS_Store 181 | 182 | # SASS Compiler cache 183 | .sass-cache 184 | 185 | # Visual Studio 2014 CTP 186 | **/*.sln.ide 187 | 188 | # Visual Studio temp something 189 | .vs/ 190 | 191 | # VS 2015+ 192 | *.vc.vc.opendb 193 | *.vc.db 194 | 195 | **/node_modules/* 196 | 197 | ##### 198 | # End of core ignore list, below put you custom 'per project' settings (patterns or path) 199 | ##### 200 | 201 | **/*.json 202 | -------------------------------------------------------------------------------- /Go/src/receive/receive.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/mikuam/asbclient" 7 | ) 8 | 9 | func main() { 10 | 11 | namespace := "bialecki" 12 | keyname := "RootManageSharedAccessKey" 13 | keyvalue := "39cH/mE4siF49REMd9xtjVlUwoc0yPJNz9J8isRc9vY=" 14 | 15 | client := asbclient.New(asbclient.Queue, namespace, keyname, keyvalue) 16 | log.Printf("Peeking...") 17 | 18 | for { 19 | msg, err := client.PeekLockMessage("go_testing", 30) 20 | 21 | if err != nil { 22 | log.Printf("Peek error: %s", err) 23 | } else { 24 | log.Printf("Peeked message: '%s'", string(msg.Body)) 25 | err = client.DeleteMessage(msg) 26 | if err != nil { 27 | log.Printf("Delete error: %s", err) 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Go/src/send/send.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | 7 | "github.com/michaelbironneau/asbclient" 8 | ) 9 | 10 | func main() { 11 | 12 | for i := 0; i <= 1000; i++ { 13 | namespace := "bialecki" 14 | keyname := "RootManageSharedAccessKey" 15 | keyvalue := "39cH/mE4siF49REMd9xtjVlUwoc0yPJNz9J8isRc9vY=" 16 | 17 | client := asbclient.New(asbclient.Topic, namespace, keyname, keyvalue) 18 | 19 | err := client.Send("go_testing", &asbclient.Message{ 20 | Body: []byte(fmt.Sprintf("message %d", i)), 21 | }) 22 | 23 | if err != nil { 24 | log.Printf("Send error: %s", err) 25 | } else { 26 | log.Printf("Sent: %d", i) 27 | } 28 | } 29 | 30 | log.Printf("Done") 31 | } 32 | -------------------------------------------------------------------------------- /ServiceBusExamples/ApplicationInsights.DataGenerator/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ServiceBusExamples/ApplicationInsights.DataGenerator/ApplicationInsights.DataGenerator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3204B00D-378E-4484-B9D6-70A59A78C54C} 8 | Exe 9 | ApplicationInsights 10 | ApplicationInsights 11 | v4.5.2 12 | 512 13 | true 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /ServiceBusExamples/ApplicationInsights.DataGenerator/DataGenerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace ApplicationInsights.DataGenerator 5 | { 6 | public class DataGenerator 7 | { 8 | public List GenerateStockData(string productId, DateTimeOffset from, DateTimeOffset to, int itemsPerHour = 180) 9 | { 10 | var result = new List(); 11 | var actualTime = from; 12 | var deltaInSeconds = 3600 / itemsPerHour; 13 | var lastStockValue = 112; 14 | var rand = new Random(); 15 | while (actualTime < to) 16 | { 17 | lastStockValue += rand.Next(-4, 5); 18 | var json = "{\"ProductId\": \"" + productId + "\", \"Stock\": \"" + lastStockValue 19 | + "\", \"UpdatedAt\": \"" + actualTime.ToString("yyyy-MM-ddTHH:mm:ssZ") + "\"}"; 20 | result.Add(json); 21 | 22 | actualTime += TimeSpan.FromSeconds(deltaInSeconds); 23 | } 24 | 25 | return result; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ServiceBusExamples/ApplicationInsights.DataGenerator/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace ApplicationInsights.DataGenerator 5 | { 6 | class Program 7 | { 8 | static void Main(string[] args) 9 | { 10 | var filePath = "C:/Mik/stockData.json"; 11 | var from = DateTimeOffset.Now - TimeSpan.FromHours(48); 12 | 13 | var generator = new DataGenerator(); 14 | var dataP1 = generator.GenerateStockData("P1", from, DateTimeOffset.Now); 15 | var dataP2 = generator.GenerateStockData("P2", from, DateTimeOffset.Now); 16 | var dataP3 = generator.GenerateStockData("P3", from, DateTimeOffset.Now); 17 | var dataP4 = generator.GenerateStockData("P4", from, DateTimeOffset.Now); 18 | var dataP5 = generator.GenerateStockData("P5", from, DateTimeOffset.Now); 19 | var dataP6 = generator.GenerateStockData("P6", from, DateTimeOffset.Now); 20 | File.AppendAllLines(filePath, dataP1); 21 | File.AppendAllLines(filePath, dataP2); 22 | File.AppendAllLines(filePath, dataP3); 23 | File.AppendAllLines(filePath, dataP4); 24 | File.AppendAllLines(filePath, dataP5); 25 | File.AppendAllLines(filePath, dataP6); 26 | 27 | var numberOfLines = dataP1.Count + dataP2.Count + dataP3.Count + dataP4.Count + dataP5.Count + dataP6.Count; 28 | Console.WriteLine($"Successfuly wrote {numberOfLines} lines to file {filePath}."); 29 | Console.ReadKey(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ServiceBusExamples/ApplicationInsights.DataGenerator/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ApplicationInsights")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ApplicationInsights")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("3204b00d-378e-4484-b9d6-70a59a78c54c")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ConsoleAppMagic/MichalBialecki.com.ConsoleAppMagic.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | PreserveNewest 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ConsoleAppMagic/Program.cs: -------------------------------------------------------------------------------- 1 | using Colorful; 2 | using System.Drawing; 3 | using System.Threading; 4 | using Console = Colorful.Console; 5 | 6 | namespace MichalBialecki.com.ConsoleAppMagic 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | // Console.WriteLine("Hello World!"); 13 | Console.ReadKey(); 14 | 15 | // ShowSimplePercentage(); 16 | // ShowSpinner(); 17 | // MultiLineAnimation(); 18 | // ColorfulText(); 19 | // ColorfulAnimation(); 20 | AsciiText(); 21 | 22 | Console.ReadKey(); 23 | } 24 | 25 | static void ShowSimplePercentage() 26 | { 27 | for (int i = 0; i <= 100; i++) 28 | { 29 | Console.Write($"\rProgress: {i}% "); 30 | Thread.Sleep(25); 31 | } 32 | 33 | Console.Write("\rDone! "); 34 | } 35 | 36 | static void ShowSpinner() 37 | { 38 | var counter = 0; 39 | for (int i = 0; i < 50; i++) 40 | { 41 | switch (counter % 4) 42 | { 43 | case 0: Console.Write("/"); break; 44 | case 1: Console.Write("-"); break; 45 | case 2: Console.Write("\\"); break; 46 | case 3: Console.Write("|"); break; 47 | } 48 | Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop); 49 | counter++; 50 | Thread.Sleep(100); 51 | } 52 | } 53 | 54 | static void MultiLineAnimation() 55 | { 56 | var counter = 0; 57 | for (int i = 0; i < 30; i++) 58 | { 59 | Console.Clear(); 60 | 61 | switch (counter % 4) 62 | { 63 | case 0: 64 | { 65 | Console.WriteLine("╔════╤╤╤╤════╗"); 66 | Console.WriteLine("║ │││ \\ ║"); 67 | Console.WriteLine("║ │││ O ║"); 68 | Console.WriteLine("║ OOO ║"); 69 | break; 70 | }; 71 | case 1: 72 | { 73 | Console.WriteLine("╔════╤╤╤╤════╗"); 74 | Console.WriteLine("║ ││││ ║"); 75 | Console.WriteLine("║ ││││ ║"); 76 | Console.WriteLine("║ OOOO ║"); 77 | break; 78 | }; 79 | case 2: 80 | { 81 | Console.WriteLine("╔════╤╤╤╤════╗"); 82 | Console.WriteLine("║ / │││ ║"); 83 | Console.WriteLine("║ O │││ ║"); 84 | Console.WriteLine("║ OOO ║"); 85 | break; 86 | }; 87 | case 3: 88 | { 89 | Console.WriteLine("╔════╤╤╤╤════╗"); 90 | Console.WriteLine("║ ││││ ║"); 91 | Console.WriteLine("║ ││││ ║"); 92 | Console.WriteLine("║ OOOO ║"); 93 | break; 94 | }; 95 | } 96 | 97 | counter++; 98 | Thread.Sleep(200); 99 | } 100 | } 101 | 102 | static void ColorfulText() 103 | { 104 | Console.WriteLine("This is a standard info message"); 105 | Console.WriteLine("This is an error!", Color.Red); 106 | } 107 | 108 | static void ColorfulAnimation() 109 | { 110 | for (int i = 0; i < 5; i++) 111 | { 112 | for (int j = 0; j < 30; j++) 113 | { 114 | Console.Clear(); 115 | 116 | // steam 117 | Console.Write(" . . . . o o o o o o", Color.LightGray); 118 | for (int s = 0; s < j / 2; s++) 119 | { 120 | Console.Write(" o", Color.LightGray); 121 | } 122 | Console.WriteLine(); 123 | 124 | var margin = "".PadLeft(j); 125 | Console.WriteLine(margin + " _____ o", Color.LightGray); 126 | Console.WriteLine(margin + " ____==== ]OO|_n_n__][.", Color.DeepSkyBlue); 127 | Console.WriteLine(margin + " [________]_|__|________)< ", Color.DeepSkyBlue); 128 | Console.WriteLine(margin + " oo oo 'oo OOOO-| oo\\_", Color.Blue); 129 | Console.WriteLine(" +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+", Color.Silver); 130 | 131 | Thread.Sleep(200); 132 | } 133 | } 134 | } 135 | 136 | static void AsciiText() 137 | { 138 | Console.WriteAscii("MichalBialecki.com", Color.FromArgb(131, 184, 214)); 139 | 140 | Console.WriteLine(); 141 | 142 | var font = FigletFont.Load("larry3d.flf"); 143 | Figlet figlet = new Figlet(font); 144 | Console.WriteLine(figlet.ToAscii("MichalBialecki.com"), Color.FromArgb(67, 144, 198)); 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Data.Dto/File.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.Data.Dto 2 | { 3 | public class File 4 | { 5 | public string Id { get; set; } 6 | 7 | public string Name { get; set; } 8 | 9 | public float Size { get; set; } 10 | 11 | public bool Hidden { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Data.Dto/Folder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MichalBialecki.com.Data.Dto 4 | { 5 | public class Folder 6 | { 7 | public Folder() 8 | { 9 | Folders = new List(); 10 | Files = new List(); 11 | } 12 | 13 | public string Id { get; set; } 14 | 15 | public string Name { get; set; } 16 | 17 | public float Size { get; set; } 18 | 19 | public bool Hidden { get; set; } 20 | 21 | public List Folders { get; set; } 22 | 23 | public List Files { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Data.Dto/FoldersAndFilesProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace MichalBialecki.com.Data.Dto 5 | { 6 | public class FoldersAndFilesProvider : IFoldersAndFilesProvider 7 | { 8 | Random random = new Random(); 9 | private IEnumerable folders; 10 | 11 | public IEnumerable GetFolders(int numberOfFilesOrFolders = 20, int structureDepth = 3) 12 | { 13 | if (folders == null) 14 | { 15 | folders = GetTreeStructure(numberOfFilesOrFolders, structureDepth).Folders; 16 | } 17 | 18 | return folders; 19 | } 20 | 21 | public Folder GetTreeStructure(int numberOfFilesOrFolders, int structureDepth) 22 | { 23 | var id = Guid.NewGuid().ToString(); 24 | 25 | return new Folder 26 | { 27 | Id = "folder_" + id, 28 | Name = "folderName_" + id, 29 | Size = random.Next(1, 200000), 30 | Hidden = false, 31 | Folders = GetFoldersRecursive(structureDepth, numberOfFilesOrFolders), 32 | Files = GetFiles(numberOfFilesOrFolders) 33 | }; 34 | } 35 | 36 | private List GetFoldersRecursive(int structureDepth, int numberOfFilesOrFolders) 37 | { 38 | var folders = new List(); 39 | 40 | if (structureDepth == 0) 41 | { 42 | return folders; 43 | } 44 | 45 | for (int i = 0; i < numberOfFilesOrFolders; i++) 46 | { 47 | var id = Guid.NewGuid().ToString(); 48 | 49 | folders.Add(new Folder 50 | { 51 | Id = "folder_" + id, 52 | Name = "folderName_" + id, 53 | Size = random.Next(1, 200000), 54 | Hidden = random.Next(0, 100) > 50, 55 | Folders = GetFoldersRecursive(structureDepth - 1, (numberOfFilesOrFolders) / 2), 56 | Files = GetFiles(random.Next(0, numberOfFilesOrFolders / 2)) 57 | }); 58 | } 59 | 60 | return folders; 61 | } 62 | 63 | private List GetFiles(int numberOfFilesOrFolders) 64 | { 65 | var files = new List(); 66 | 67 | if (numberOfFilesOrFolders == 0) 68 | { 69 | return files; 70 | } 71 | 72 | for (int i = 0; i < numberOfFilesOrFolders; i++) 73 | { 74 | var id = Guid.NewGuid().ToString(); 75 | 76 | files.Add(new File 77 | { 78 | Id = "file_" + id, 79 | Name = "fileName_" + id, 80 | Size = random.Next(1, 200000), 81 | Hidden = random.Next(0, 100) > 50 82 | }); 83 | } 84 | 85 | return files; 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Data.Dto/IFoldersAndFilesProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MichalBialecki.com.Data.Dto 4 | { 5 | public interface IFoldersAndFilesProvider 6 | { 7 | IEnumerable GetFolders(int numberOfFilesOrFolders = 20, int structureDepth = 3); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Data.Dto/MichalBialecki.com.Data.Dto.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | pdbonly 9 | True 10 | 11 | 12 | 13 | pdbonly 14 | True 15 | 16 | 17 | 18 | 19 | ..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile259\System.Collections.dll 20 | 21 | 22 | ..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile259\System.Runtime.Extensions.dll 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Egnyte.Examples/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Egnyte.Examples/Files/CopyBigFiles.cs: -------------------------------------------------------------------------------- 1 | using Egnyte.Api; 2 | using Egnyte.Api.Files; 3 | using NUnit.Framework; 4 | using System; 5 | using System.IO; 6 | using System.Threading.Tasks; 7 | 8 | namespace MichalBialecki.com.Egnyte.Examples.Files 9 | { 10 | [TestFixture] 11 | class CopyBigFiles 12 | { 13 | private const string Domain = "yourdomain"; 14 | 15 | private const string Token = ""; 16 | 17 | [Test] 18 | public async Task UploadBigFile() 19 | { 20 | var client = new EgnyteClient(Token, Domain); 21 | 22 | var fileStream = new MemoryStream(File.ReadAllBytes("c:/test/big-file.zip")); 23 | var response = await ChunkUploadFile(client, "Shared/MikTests/Blog/big-file.zip", fileStream); 24 | 25 | Assert.Pass(); 26 | } 27 | 28 | [Test] 29 | public async Task DownloadBigFile() 30 | { 31 | var client = new EgnyteClient(Token, Domain); 32 | 33 | var responseStream = await client.Files.DownloadFileAsStream("Shared/MikTests/Blog/big-file.zip"); 34 | 35 | using (FileStream file = new FileStream("C:/test/big-file01.zip", FileMode.OpenOrCreate, FileAccess.Write)) 36 | { 37 | CopyStream(responseStream.Data, file); 38 | } 39 | 40 | Assert.Pass(); 41 | } 42 | 43 | private async Task ChunkUploadFile( 44 | EgnyteClient client, 45 | string serverFilePath, 46 | MemoryStream fileStream) 47 | { 48 | // first chunk 49 | var defaultChunkLength = 10485760; 50 | var firstChunkLength = defaultChunkLength; 51 | if (fileStream.Length < firstChunkLength) 52 | { 53 | firstChunkLength = (int)fileStream.Length; 54 | } 55 | 56 | var bytesRead = firstChunkLength; 57 | var buffer = new byte[firstChunkLength]; 58 | fileStream.Read(buffer, 0, firstChunkLength); 59 | 60 | var response = await client.Files.ChunkedUploadFirstChunk(serverFilePath, new MemoryStream(buffer)) 61 | .ConfigureAwait(false); 62 | int number = 2; 63 | 64 | while (bytesRead < fileStream.Length) 65 | { 66 | var nextChunkLength = defaultChunkLength; 67 | bool isLastChunk = false; 68 | if (bytesRead + nextChunkLength >= fileStream.Length) 69 | { 70 | nextChunkLength = (int)fileStream.Length - bytesRead; 71 | isLastChunk = true; 72 | } 73 | 74 | buffer = new byte[nextChunkLength]; 75 | fileStream.Read(buffer, 0, nextChunkLength); 76 | 77 | if (!isLastChunk) 78 | { 79 | await client.Files.ChunkedUploadNextChunk( 80 | serverFilePath, 81 | number, 82 | response.UploadId, 83 | new MemoryStream(buffer)).ConfigureAwait(false); 84 | } 85 | else 86 | { 87 | return await client.Files.ChunkedUploadLastChunk( 88 | serverFilePath, 89 | number, 90 | response.UploadId, 91 | new MemoryStream(buffer)).ConfigureAwait(false); 92 | } 93 | number++; 94 | bytesRead += nextChunkLength; 95 | } 96 | 97 | throw new Exception("Something went wrong - unable to enumerate to next chunk."); 98 | } 99 | 100 | /// 101 | /// Copies the contents of input to output. Doesn't close either stream. 102 | /// 103 | public static void CopyStream(Stream input, Stream output) 104 | { 105 | byte[] buffer = new byte[8 * 1024]; 106 | int len; 107 | while ((len = input.Read(buffer, 0, buffer.Length)) > 0) 108 | { 109 | output.Write(buffer, 0, len); 110 | } 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Egnyte.Examples/MichalBialecki.com.Egnyte.Examples.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | {8206601C-F9F6-4E27-8911-1696CCB02B81} 9 | Library 10 | MichalBialecki.com.Egnyte.ConsoleExamples 11 | MichalBialecki.com.Egnyte.Examples 12 | v4.6.1 13 | 512 14 | true 15 | 16 | 17 | 18 | 19 | AnyCPU 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | ..\packages\Egnyte.Api.0.1.11\lib\portable-net45+sl50+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\Egnyte.Api.dll 43 | 44 | 45 | ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll 46 | 47 | 48 | ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll 49 | 50 | 51 | ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll 52 | 53 | 54 | ..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll 55 | 56 | 57 | ..\packages\NUnit.3.9.0\lib\net45\nunit.framework.dll 58 | 59 | 60 | 61 | 62 | 63 | ..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll 64 | 65 | 66 | ..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Egnyte.Examples/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MichalBialecki.com.Egnyte.ConsoleExamples")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MichalBialecki.com.Egnyte.ConsoleExamples")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8206601c-f9f6-4e27-8911-1696ccb02b81")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Egnyte.Examples/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Functions/Function1.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.WebJobs; 2 | using Microsoft.Azure.WebJobs.Host; 3 | 4 | namespace MichalBialecki.com.Functions 5 | { 6 | public static class Function1 7 | { 8 | [FunctionName("Function1")] 9 | public static void Run([ServiceBusTrigger("function_testing", Connection = "Endpoint=sb://bialecki.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=39cH/mE4siF49REMd9xtjVlUwoc0yPJNz9J8isRc9vY=")]string myQueueItem, TraceWriter log) 10 | { 11 | log.Info($"C# ServiceBus queue trigger function processed message: {myQueueItem}"); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Functions/MichalBialecki.com.Functions.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | netstandard2.0 4 | v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | PreserveNewest 13 | 14 | 15 | PreserveNewest 16 | Never 17 | 18 | 19 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Functions/host.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Functions/local.settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "IsEncrypted": false, 3 | "Values": { 4 | "AzureWebJobsStorage": "UseDevelopmentStorage=true", 5 | "AzureWebJobsDashboard": "UseDevelopmentStorage=true" 6 | } 7 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Console/MichalBialecki.com.NetCore.Console.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Console/PriceComparer/Offer.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.NetCore.Console.PriceComparer 2 | { 3 | public class Offer 4 | { 5 | public string ProductId { get; set; } 6 | 7 | public decimal Price { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Console/PriceComparer/PriceComparerInit.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net.Http; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using Bogus; 9 | using Newtonsoft.Json; 10 | 11 | namespace MichalBialecki.com.NetCore.Console.PriceComparer 12 | { 13 | public class PriceComparerInit 14 | { 15 | private HttpClient httpClient; 16 | private Faker faker; 17 | 18 | //private const string ServiceUrl = "http://fab-cl-fv80j72.fabres.local:8505"; 19 | private const string ServiceUrl = "http://localhost:60102"; 20 | 21 | public void Init(int numberOfSellers, int numberOfProducts) 22 | { 23 | httpClient = new HttpClient(); 24 | faker = new Faker(); 25 | 26 | System.Console.WriteLine($"Generating sellers at: {DateTime.Now}"); 27 | var sellers = GenerateSellers(numberOfSellers, numberOfProducts); 28 | System.Console.WriteLine("Generating products"); 29 | var products = GenerateProducts(numberOfProducts, sellers); 30 | 31 | System.Console.WriteLine("Init sellers started"); 32 | 33 | SendBatch($"{ServiceUrl}/api/seller", sellers); 34 | 35 | System.Console.WriteLine($"{sellers.Count} sellers initialized"); 36 | 37 | System.Console.WriteLine("Init products started"); 38 | 39 | SendBatch($"{ServiceUrl}/api/product", products); 40 | 41 | System.Console.WriteLine($"{products.Count} products initialized at {DateTime.Now}"); 42 | 43 | System.Console.WriteLine("Done"); 44 | } 45 | 46 | private List GenerateProducts(int numberOfProducts, List sellers) 47 | { 48 | var products = new List(); 49 | for (int i = 1; i <= numberOfProducts; i++) 50 | { 51 | products.Add(new Product 52 | { 53 | Id = i.ToString(), 54 | Name = faker.Commerce.Product() 55 | }); 56 | } 57 | 58 | var productsDict = products.ToDictionary(p => p.Id); 59 | 60 | foreach (var seller in sellers) 61 | { 62 | foreach (var sellerOffer in seller.Offers) 63 | { 64 | productsDict[sellerOffer.ProductId].Offers.Add(new SellerOffer 65 | { 66 | ProductId = productsDict[sellerOffer.ProductId].Id, 67 | Price = sellerOffer.Price, 68 | SellerId = seller.Id, 69 | SellerName = seller.Name, 70 | SellerRating = seller.Rating 71 | }); 72 | } 73 | } 74 | 75 | products = productsDict.Values.ToList(); 76 | foreach (var product in products) 77 | { 78 | product.Offers = product.Offers.OrderByDescending(o => o.SellerRating).ToList(); 79 | } 80 | 81 | return products; 82 | } 83 | 84 | private List GenerateSellers(int numberOfSellers, int numberOfProducts) 85 | { 86 | var random = new Random(); 87 | var sellers = new List(); 88 | for (int i = 1; i <= numberOfSellers; i++) 89 | { 90 | var numberOfMarks = random.Next(1, 5); 91 | var marksSum = Math.Round(random.NextDouble() * 5 * numberOfMarks); 92 | 93 | var seller = new Seller 94 | { 95 | Id = i.ToString(), 96 | Name = faker.Company.CompanyName(), 97 | MarksCount = numberOfMarks, 98 | MarksSum = (decimal)marksSum 99 | }; 100 | 101 | var numberOfOffers = 100; 102 | for (int j = 1; j <= numberOfOffers; j++) 103 | { 104 | var productId = random.Next(1, numberOfProducts); 105 | seller.Offers.Add(new Offer{ ProductId = productId.ToString(), Price = decimal.Parse(faker.Commerce.Price()) }); 106 | } 107 | 108 | sellers.Add(seller); 109 | } 110 | 111 | return sellers; 112 | } 113 | 114 | private StringContent GetJson(object o) 115 | { 116 | return new StringContent(JsonConvert.SerializeObject(o), Encoding.UTF8, "application/json"); 117 | } 118 | 119 | private void SendBatch(string url, List objects) 120 | { 121 | var batchSize = 100; 122 | var sendProducts = 0; 123 | while (sendProducts < objects.Count) 124 | { 125 | var productsToSend = objects.Skip(sendProducts).Take(batchSize); 126 | 127 | var productTasks = productsToSend.Select(o => httpClient.PostAsync(url, GetJson(o))); 128 | Task.WaitAll(productTasks.ToArray()); 129 | 130 | sendProducts += batchSize; 131 | System.Console.WriteLine($"{sendProducts}/{objects.Count} sent"); 132 | } 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Console/PriceComparer/Product.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MichalBialecki.com.NetCore.Console.PriceComparer 4 | { 5 | public class Product 6 | { 7 | public Product() 8 | { 9 | Offers = new List(); 10 | } 11 | 12 | public string Id { get; set; } 13 | 14 | public string Name { get; set; } 15 | 16 | public List Offers { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Console/PriceComparer/Seller.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace MichalBialecki.com.NetCore.Console.PriceComparer 5 | { 6 | public class Seller 7 | { 8 | public Seller() 9 | { 10 | Offers = new List(); 11 | } 12 | 13 | public string Id { get; set; } 14 | 15 | public string Name { get; set; } 16 | 17 | public int MarksCount { get; set; } 18 | 19 | public decimal MarksSum { get; set; } 20 | 21 | public decimal Rating => Math.Round(MarksSum / (MarksCount == 0 ? 1 : MarksCount), 2); 22 | 23 | public List Offers { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Console/PriceComparer/SellerOffer.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.NetCore.Console.PriceComparer 2 | { 3 | public class SellerOffer 4 | { 5 | public string ProductId { get; set; } 6 | 7 | public decimal Price { get; set; } 8 | 9 | public string SellerId { get; set; } 10 | 11 | public string SellerName { get; set; } 12 | 13 | public decimal SellerRating { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Console/Program.cs: -------------------------------------------------------------------------------- 1 | using MichalBialecki.com.NetCore.Console.Users; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Threading.Tasks; 5 | using MichalBialecki.com.NetCore.Console.PriceComparer; 6 | 7 | namespace MichalBialecki.com.NetCore.Console 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | //Task.Run(async () => await Measure()); 14 | 15 | var priceComparer = new PriceComparerInit(); 16 | priceComparer.Init(1000, 10000); 17 | 18 | System.Console.ReadKey(); 19 | } 20 | 21 | private static async Task Measure() 22 | { 23 | var services = new UsersService(); 24 | var stopper = new Stopwatch(); 25 | var userIds = GetUserIds(1000); 26 | 27 | stopper.Start(); 28 | await services.GetUsersSynchrnously(userIds); 29 | System.Console.WriteLine("Synchronous: " + stopper.Elapsed); 30 | 31 | stopper.Restart(); 32 | await services.GetUsersInParallel(userIds); 33 | System.Console.WriteLine("In paralell: " + stopper.Elapsed); 34 | 35 | stopper.Restart(); 36 | await services.GetUsersInParallelFixed(userIds); 37 | System.Console.WriteLine("In paralell fixed: " + stopper.Elapsed); 38 | 39 | stopper.Restart(); 40 | await services.GetUsersInParallelInWithBatches(userIds); 41 | System.Console.WriteLine("In paralell with batches: " + stopper.Elapsed); 42 | } 43 | 44 | private static IEnumerable GetUserIds(int numberOfIds) 45 | { 46 | for (int i = 1; i <= numberOfIds; i++) 47 | { 48 | yield return i; 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Console/Users/UserDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MichalBialecki.com.NetCore.Console.Users 4 | { 5 | public class UserDto 6 | { 7 | public int Id { get; set; } 8 | 9 | public string Name { get; set; } 10 | 11 | public DateTime LastModified { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Console/Users/UsersClient.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | using System.Net.Http; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MichalBialecki.com.NetCore.Console.Users 8 | { 9 | using System; 10 | 11 | public class UsersClient 12 | { 13 | private HttpClient client; 14 | 15 | public UsersClient() 16 | { 17 | client = new HttpClient(); 18 | } 19 | 20 | public async Task GetUser(int id) 21 | { 22 | var response = await client.GetAsync("localhost:49532/api/users/" + id).ConfigureAwait(false); 23 | var user = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); 24 | 25 | return user; 26 | } 27 | 28 | public async Task> GetUsers(IEnumerable ids) 29 | { 30 | var response = await client 31 | //.PostAsync("http://localhost:49532/api/Users/GetMany", new StringContent(JsonConvert.SerializeObject(ids), Encoding.UTF8, "application/json")) 32 | .PostAsync( 33 | "http://michalbialeckicomnetcoreweb20180417060938.azurewebsites.net/api/users/GetMany", 34 | new StringContent(JsonConvert.SerializeObject(ids), Encoding.UTF8, "application/json")) 35 | .ConfigureAwait(false); 36 | 37 | var users = JsonConvert.DeserializeObject>(await response.Content.ReadAsStringAsync()); 38 | 39 | return users; 40 | } 41 | 42 | public async Task InsertUser() 43 | { 44 | try 45 | { 46 | // async stuff here 47 | 48 | var response = await client.PostAsync("http://localhost:49532/api/users/InsertMany", null).ConfigureAwait(false); 49 | response.EnsureSuccessStatusCode(); 50 | 51 | // more async cally 52 | } 53 | catch (Exception e) 54 | { 55 | Console.WriteLine(e); 56 | throw; 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Console/Users/UsersService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MichalBialecki.com.NetCore.Console.Users 7 | { 8 | public class UsersService 9 | { 10 | private UsersClient client; 11 | 12 | public UsersService() 13 | { 14 | client = new UsersClient(); 15 | } 16 | 17 | public async Task> GetUsersSynchrnously(IEnumerable userIds) 18 | { 19 | var users = new List(); 20 | foreach (var id in userIds) 21 | { 22 | users.Add(await client.GetUser(id)); 23 | } 24 | 25 | return users; 26 | } 27 | 28 | public async Task> GetUsersInParallel(IEnumerable userIds) 29 | { 30 | var tasks = userIds.Select(id => client.GetUser(id)); 31 | var users = await Task.WhenAll(tasks); 32 | 33 | return users; 34 | } 35 | 36 | public async Task> GetUsersInParallelFixed(IEnumerable userIds) 37 | { 38 | var users = new List(); 39 | var batchSize = 100; 40 | int numberOfBatches = (int)Math.Ceiling((double)userIds.Count() / batchSize); 41 | 42 | for(int i = 0; i < numberOfBatches; i++) 43 | { 44 | var currentIds = userIds.Skip(i * batchSize).Take(batchSize); 45 | var tasks = currentIds.Select(id => client.GetUser(id)); 46 | users.AddRange(await Task.WhenAll(tasks)); 47 | } 48 | 49 | return users; 50 | } 51 | 52 | public async Task> GetUsersInParallelInWithBatches(IEnumerable userIds) 53 | { 54 | var tasks = new List>>(); 55 | var batchSize = 100; 56 | int numberOfBatches = (int)Math.Ceiling((double)userIds.Count() / batchSize); 57 | 58 | for (int i = 0; i < numberOfBatches; i++) 59 | { 60 | var currentIds = userIds.Skip(i * batchSize).Take(batchSize); 61 | tasks.Add(client.GetUsers(currentIds)); 62 | } 63 | 64 | return (await Task.WhenAll(tasks)).SelectMany(u => u); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CacheHelper.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.NetCore.Web 2 | { 3 | using System.IO; 4 | using System.Runtime.Serialization; 5 | using System.Runtime.Serialization.Formatters.Binary; 6 | 7 | public static class CacheHelper 8 | { 9 | public static T Deserialize(byte[] param) 10 | { 11 | using (var ms = new MemoryStream(param)) 12 | { 13 | IFormatter br = new BinaryFormatter(); 14 | return (T)br.Deserialize(ms); 15 | } 16 | } 17 | 18 | public static byte[] Serialize(object obj) 19 | { 20 | if (obj == null) 21 | { 22 | return null; 23 | } 24 | 25 | var bf = new BinaryFormatter(); 26 | using (var ms = new MemoryStream()) 27 | { 28 | bf.Serialize(ms, obj); 29 | return ms.ToArray(); 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/Connected Services/Application Insights/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", 3 | "Version": "8.10.1106.1", 4 | "GettingStartedDocument": { 5 | "Uri": "https://go.microsoft.com/fwlink/?LinkID=798432" 6 | } 7 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CsvExport/Attributes/ExportAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.NetCore.Web.CsvExport.Attributes 2 | { 3 | using System; 4 | 5 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, AllowMultiple = false)] 6 | public abstract class ExportAttribute : Attribute 7 | { 8 | public string ExportName { get; set; } 9 | 10 | public string Format { get; set; } 11 | 12 | public int Order { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CsvExport/Attributes/ProductAnalyticsAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.NetCore.Web.CsvExport.Attributes 2 | { 3 | public class ProductAnalyticsAttribute : ExportAttribute 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CsvExport/Attributes/ProductComparerExportAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.NetCore.Web.CsvExport.Attributes 2 | { 3 | public class ProductComparerExportAttribute : ExportAttribute 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CsvExport/CsvExportController.cs: -------------------------------------------------------------------------------- 1 | using MichalBialecki.com.NetCore.Web.CsvExport.Attributes; 2 | using MichalBialecki.com.NetCore.Web.CsvExport.Data; 3 | using Microsoft.AspNetCore.Mvc; 4 | using System; 5 | using System.IO; 6 | using System.Net; 7 | using System.Net.Http; 8 | using System.Text; 9 | 10 | namespace MichalBialecki.com.NetCore.Web.CsvExport 11 | { 12 | [Route("api/Export")] 13 | public class CsvExportController : Controller 14 | { 15 | private readonly IProductGenerator _productGenerator; 16 | 17 | private readonly ICsvExport _csvExport; 18 | 19 | private readonly IProductComparerExportService _productComparerExportService; 20 | 21 | private readonly IProductAnalyticsExportService _productAnalyticsExportService; 22 | 23 | public CsvExportController( 24 | IProductGenerator productGenerator, 25 | ICsvExport csvExport, 26 | IProductComparerExportService productComparerExportService, 27 | IProductAnalyticsExportService productAnalyticsExportService) 28 | { 29 | _productGenerator = productGenerator; 30 | _csvExport = csvExport; 31 | _productComparerExportService = productComparerExportService; 32 | _productAnalyticsExportService = productAnalyticsExportService; 33 | } 34 | 35 | [Route("Products")] 36 | [HttpGet] 37 | public IActionResult Products() 38 | { 39 | var products = _productGenerator.GenerateProducts(100); 40 | var data = _csvExport.ReturnData(products); 41 | 42 | var stream = new MemoryStream(Encoding.UTF8.GetBytes(data)); 43 | var result = new FileStreamResult(stream, "text/plain"); 44 | result.FileDownloadName = "export_" + DateTime.Now + ".csv"; 45 | 46 | return result; 47 | } 48 | 49 | [Route("ProductComparerExport")] 50 | [HttpGet] 51 | public IActionResult ProductComparerExport() 52 | { 53 | var products = _productGenerator.GenerateProducts(100); 54 | var data = _productComparerExportService.Export(products); 55 | 56 | var stream = new MemoryStream(Encoding.UTF8.GetBytes(data)); 57 | var result = new FileStreamResult(stream, "text/plain"); 58 | result.FileDownloadName = "export_" + DateTime.Now + ".csv"; 59 | 60 | return result; 61 | } 62 | 63 | [Route("ProductAnalyticsExport")] 64 | [HttpGet] 65 | public IActionResult ProductAnalyticsExport() 66 | { 67 | var products = _productGenerator.GenerateProducts(100); 68 | var data = _productAnalyticsExportService.Export(products); 69 | 70 | var stream = new MemoryStream(Encoding.UTF8.GetBytes(data)); 71 | var result = new FileStreamResult(stream, "text/plain"); 72 | result.FileDownloadName = "export_" + DateTime.Now + ".csv"; 73 | 74 | return result; 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CsvExport/Data/ExportProperty.cs: -------------------------------------------------------------------------------- 1 | using MichalBialecki.com.NetCore.Web.CsvExport.Attributes; 2 | using System.Reflection; 3 | 4 | namespace MichalBialecki.com.NetCore.Web.CsvExport.Data 5 | { 6 | public class ExportProperty 7 | { 8 | public PropertyInfo PropertyInfo { get; set; } 9 | 10 | public ExportAttribute ExportAttribute { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CsvExport/Data/IProductGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MichalBialecki.com.NetCore.Web.CsvExport.Data 4 | { 5 | public interface IProductGenerator 6 | { 7 | List GenerateProducts(int count); 8 | } 9 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CsvExport/Data/ProductDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MichalBialecki.com.NetCore.Web.CsvExport.Attributes; 3 | 4 | namespace MichalBialecki.com.NetCore.Web.CsvExport.Data 5 | { 6 | public class ProductDto 7 | { 8 | [ProductComparerExport(ExportName = "InternalId")] 9 | [ProductAnalytics(Order = 1)] 10 | public string Id { get; set; } 11 | 12 | [ProductAnalytics(Order = 3)] 13 | public string Name { get; set; } 14 | 15 | [ProductComparerExport(ExportName = "Id")] 16 | [ProductAnalytics(Order = 2)] 17 | public string ReferenceNumber { get; set; } 18 | 19 | [ProductComparerExport] 20 | [ProductAnalytics(Order = 4)] 21 | public string ProducerName { get; set; } 22 | 23 | [ProductAnalytics(Order = 5)] 24 | public int QuantityAvailable { get; set; } 25 | 26 | [ProductAnalytics(Order = 6)] 27 | public int QuantitySoldLastMonth { get; set; } 28 | 29 | [ProductComparerExport(Format = "0.0")] 30 | public decimal Weight { get; set; } 31 | 32 | [ProductComparerExport(Format = "0.00")] 33 | [ProductAnalytics(Order = 7, Format = "0.00")] 34 | public decimal Price { get; set; } 35 | 36 | [ProductComparerExport(ExportName = "OrderDate", Format = "yyyy-MM-dd")] 37 | [ProductAnalytics(Order = 8, Format = "MM-dd-yyyy")] 38 | public DateTime LastOrderDate { get; set; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CsvExport/Data/ProductGenerator.cs: -------------------------------------------------------------------------------- 1 | using Bogus; 2 | using System; 3 | using System.Collections.Generic; 4 | 5 | namespace MichalBialecki.com.NetCore.Web.CsvExport.Data 6 | { 7 | public class ProductGenerator : IProductGenerator 8 | { 9 | public List GenerateProducts(int count) 10 | { 11 | var productGenerator = new Faker() 12 | .RuleFor(p => p.Id, v => Guid.NewGuid().ToString()) 13 | .RuleFor(p => p.Name, v => v.Commerce.ProductName()) 14 | .RuleFor(p => p.ReferenceNumber, v => v.IndexGlobal.ToString()) 15 | .RuleFor(p => p.ProducerName, v => v.Company.CompanyName()) 16 | .RuleFor(p => p.QuantityAvailable, v => v.Random.Number(0, 100)) 17 | .RuleFor(p => p.QuantitySoldLastMonth, v => v.Random.Number(0, 20)) 18 | .RuleFor(p => p.Weight, v => Math.Round(v.Random.Decimal(0.1m, 50), 2)) 19 | .RuleFor(p => p.Price, v => Math.Round(v.Random.Decimal(1, 10000), 2)) 20 | .RuleFor(p => p.LastOrderDate, v => v.Date.Recent()); 21 | 22 | return productGenerator.Generate(count); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CsvExport/GenericExportService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Text; 8 | using MichalBialecki.com.NetCore.Web.CsvExport.Attributes; 9 | using MichalBialecki.com.NetCore.Web.CsvExport.Data; 10 | 11 | namespace MichalBialecki.com.NetCore.Web.CsvExport 12 | { 13 | public abstract class GenericExportService 14 | { 15 | private const string CsvDelimeter = ";"; 16 | 17 | protected string Export(IEnumerable products) 18 | where TAttribute : ExportAttribute 19 | { 20 | using (var exportStream = (MemoryStream)GetStream(products)) 21 | { 22 | var encoding = new UTF8Encoding(false); 23 | return encoding.GetString(exportStream.ToArray()); 24 | } 25 | } 26 | 27 | private Stream GetStream(IEnumerable objectList) 28 | where TAttribute : ExportAttribute 29 | { 30 | var stream = new MemoryStream(); 31 | var streamWriter = new StreamWriter(stream, new UTF8Encoding(false)); 32 | 33 | var columns = GetColumns().OrderBy(o => o.ExportAttribute.Order); 34 | var columnNames = columns.Select(c => c.ExportAttribute.ExportName != null 35 | ? c.ExportAttribute.ExportName 36 | : c.PropertyInfo.Name); 37 | streamWriter.WriteLine(string.Join(CsvDelimeter, columnNames)); 38 | 39 | foreach (var item in objectList) 40 | { 41 | var values = GetProductValues(item, columns); 42 | streamWriter.WriteLine(string.Join(CsvDelimeter, values)); 43 | } 44 | 45 | streamWriter.Flush(); 46 | stream.Seek(0, SeekOrigin.Begin); 47 | return stream; 48 | } 49 | 50 | private IEnumerable GetColumns() 51 | where TAttribute : ExportAttribute 52 | { 53 | return typeof(ProductDto).GetProperties().Select( 54 | property => { 55 | var exportAttribute = ((TAttribute)property.GetCustomAttributes(typeof(TAttribute), false).FirstOrDefault()); 56 | return exportAttribute == null 57 | ? null 58 | : new ExportProperty { PropertyInfo = property, ExportAttribute = exportAttribute }; 59 | }).Where(p => p != null); 60 | } 61 | 62 | private List GetProductValues(ProductDto product, IEnumerable columns) 63 | where TAttribute : ExportAttribute 64 | { 65 | var propertyValues = new List(); 66 | foreach (var column in columns) 67 | { 68 | propertyValues.Add(GetAttributeValue(product, column.PropertyInfo, column.ExportAttribute)); 69 | } 70 | 71 | return propertyValues; 72 | } 73 | 74 | private string GetAttributeValue(ProductDto product, PropertyInfo propertyInfo, TAttribute attribute) 75 | where TAttribute : ExportAttribute 76 | { 77 | object value = propertyInfo.GetValue(product); 78 | 79 | if (value == null || attribute == null) 80 | { 81 | return string.Empty; 82 | } 83 | 84 | if (!string.IsNullOrWhiteSpace(attribute.Format) && value is IFormattable) 85 | { 86 | return (value as IFormattable).ToString(attribute.Format, CultureInfo.CurrentCulture); 87 | } 88 | 89 | if (!string.IsNullOrWhiteSpace(attribute.Format)) 90 | { 91 | return string.Format(attribute.Format, value); 92 | } 93 | 94 | return propertyInfo.GetValue(product).ToString(); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CsvExport/ICsvExport.cs: -------------------------------------------------------------------------------- 1 | using MichalBialecki.com.NetCore.Web.CsvExport.Data; 2 | using System.Collections.Generic; 3 | 4 | namespace MichalBialecki.com.NetCore.Web.CsvExport 5 | { 6 | public interface ICsvExport 7 | { 8 | string ReturnData(IList products); 9 | } 10 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CsvExport/IProductAnalyticsExportService.cs: -------------------------------------------------------------------------------- 1 | using MichalBialecki.com.NetCore.Web.CsvExport.Data; 2 | using System.Collections.Generic; 3 | 4 | namespace MichalBialecki.com.NetCore.Web.CsvExport 5 | { 6 | public interface IProductAnalyticsExportService 7 | { 8 | string Export(IList products); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CsvExport/IProductComparerExportService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using MichalBialecki.com.NetCore.Web.CsvExport.Data; 3 | 4 | namespace MichalBialecki.com.NetCore.Web.CsvExport 5 | { 6 | public interface IProductComparerExportService 7 | { 8 | string Export(IList products); 9 | } 10 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CsvExport/ProductAnalyticsExportService.cs: -------------------------------------------------------------------------------- 1 | using MichalBialecki.com.NetCore.Web.CsvExport.Attributes; 2 | using MichalBialecki.com.NetCore.Web.CsvExport.Data; 3 | using System.Collections.Generic; 4 | 5 | namespace MichalBialecki.com.NetCore.Web.CsvExport 6 | { 7 | public class ProductAnalyticsExportService : GenericExportService, IProductAnalyticsExportService 8 | { 9 | public string Export(IList products) 10 | { 11 | var result = Export(products); 12 | 13 | return result; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CsvExport/ProductComparerExportService.cs: -------------------------------------------------------------------------------- 1 | using MichalBialecki.com.NetCore.Web.CsvExport.Attributes; 2 | using MichalBialecki.com.NetCore.Web.CsvExport.Data; 3 | using System.Collections.Generic; 4 | 5 | namespace MichalBialecki.com.NetCore.Web.CsvExport 6 | { 7 | public class ProductComparerExportService : GenericExportService, IProductComparerExportService 8 | { 9 | public string Export(IList products) 10 | { 11 | var result = Export(products); 12 | 13 | return result; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/CsvExport/SimpleCsvExport.cs: -------------------------------------------------------------------------------- 1 | using MichalBialecki.com.NetCore.Web.CsvExport.Data; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace MichalBialecki.com.NetCore.Web.CsvExport 7 | { 8 | public class SimpleCsvExport : ICsvExport 9 | { 10 | public string ReturnData(IList products) 11 | { 12 | var columnNames = GetColumnNames(); 13 | var builder = new StringBuilder(); 14 | 15 | builder.AppendJoin(";", columnNames); 16 | builder.AppendLine(); 17 | 18 | foreach (var product in products) 19 | { 20 | var values = GetValues(product); 21 | builder.AppendJoin(";", values); 22 | builder.AppendLine(); 23 | } 24 | 25 | return builder.ToString(); 26 | } 27 | 28 | private string[] GetColumnNames() 29 | { 30 | return new[] { 31 | "Id", 32 | "Name", 33 | "ReferenceNumber", 34 | "ProducerName", 35 | "QuantityAvailable", 36 | "QuantitySoldLastMonth", 37 | "Weight", 38 | "Price", 39 | "LastOrderDate"}; 40 | } 41 | 42 | private string[] GetValues(ProductDto product) 43 | { 44 | return new[] 45 | { 46 | product.Id, 47 | product.Name, 48 | product.ReferenceNumber, 49 | product.ProducerName, 50 | product.QuantityAvailable.ToString(), 51 | product.QuantitySoldLastMonth.ToString(), 52 | product.Weight.ToString(), 53 | product.Price.ToString(), 54 | product.LastOrderDate.ToString() 55 | }; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/Documents/Document.cs: -------------------------------------------------------------------------------- 1 | using System.Xml.Serialization; 2 | 3 | namespace MichalBialecki.com.NetCore.Web.Documents 4 | { 5 | [XmlRoot(ElementName = "document", Namespace = "")] 6 | public class DocumentDto 7 | { 8 | [XmlElement(DataType = "string", ElementName = "id")] 9 | public string Id { get; set; } 10 | 11 | [XmlElement(DataType = "string", ElementName = "content")] 12 | public string Content { get; set; } 13 | 14 | [XmlElement(DataType = "string", ElementName = "author")] 15 | public string Author { get; set; } 16 | 17 | [XmlElement(ElementName = "links")] 18 | public LinkDto Links { get; set; } 19 | } 20 | 21 | public class LinkDto 22 | { 23 | [XmlElement(ElementName = "link")] 24 | public string[] Link { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/Documents/DocumentsController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace MichalBialecki.com.NetCore.Web.Documents 4 | { 5 | /* 6 | Sample XML file: 7 | 8 | 123456 9 | This is document that I posted... 10 | Michał Białecki 11 | 12 | 2345 13 | 5678 14 | 15 | 16 | 17 | and add header: Content-Type: text/xml 18 | 19 | Sample Json file: 20 | { 21 | id: "1234", 22 | content: "This is document that I posted...", 23 | author: "Michał Białecki", 24 | links: { 25 | link: ["1234", "5678"] 26 | } 27 | } 28 | 29 | and add header: Content-Type: application/json 30 | */ 31 | 32 | [Route("api/Documents")] 33 | public class DocumentsController : Controller 34 | { 35 | [Route("SendDocument")] 36 | [HttpPost] 37 | public ActionResult SendDocument([FromBody]DocumentDto document) 38 | { 39 | return Ok(); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/MichalBialecki.com.NetCore.Web.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | /subscriptions/9179e872-53da-40e1-a26e-90ef82ddf188/resourcegroups/home/providers/microsoft.insights/components/MichalBialeckicomNetCoreWeb20180417060938 6 | /subscriptions/9179e872-53da-40e1-a26e-90ef82ddf188/resourcegroups/home/providers/microsoft.insights/components/MichalBialeckicomNetCoreWeb20180417060938 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace MichalBialecki.com.NetCore.Web 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | BuildWebHost(args).Run(); 11 | } 12 | 13 | public static IWebHost BuildWebHost(string[] args) => 14 | WebHost.CreateDefaultBuilder(args) 15 | .UseApplicationInsights() 16 | .UseStartup() 17 | .Build(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/Properties/PublishProfiles/MichalBialeckicomNetCoreWeb20180417060938 - Web Deploy.pubxml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | MSDeploy 9 | /subscriptions/9179e872-53da-40e1-a26e-90ef82ddf188/resourcegroups/home/providers/Microsoft.Web/sites/MichalBialeckicomNetCoreWeb20180417060938 10 | home 11 | AzureWebSite 12 | Debug 13 | Any CPU 14 | http://michalbialeckicomnetcoreweb20180417060938.azurewebsites.net 15 | True 16 | False 17 | 654a48ab-d935-4990-9646-9a1eaa1c6ce5 18 | michalbialeckicomnetcoreweb20180417060938.scm.azurewebsites.net:443 19 | MichalBialeckicomNetCoreWeb20180417060938 20 | 21 | True 22 | WMSVC 23 | True 24 | $MichalBialeckicomNetCoreWeb20180417060938 25 | <_SavePWD>True 26 | <_DestinationType>AzureWebSite 27 | netcoreapp2.0 28 | 29 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:49532/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "swagger", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "MichalBialecki.com.NetCore.Web": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "launchUrl": "api/values", 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | }, 26 | "applicationUrl": "http://localhost:49533/" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/Startup.cs: -------------------------------------------------------------------------------- 1 | using MichalBialecki.com.NetCore.Web.CsvExport; 2 | using MichalBialecki.com.NetCore.Web.CsvExport.Data; 3 | using MichalBialecki.com.NetCore.Web.Users; 4 | using Microsoft.AspNetCore.Builder; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.DependencyInjection; 8 | using Swashbuckle.AspNetCore.Swagger; 9 | 10 | namespace MichalBialecki.com.NetCore.Web 11 | { 12 | public class Startup 13 | { 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | 19 | public IConfiguration Configuration { get; } 20 | 21 | // This method gets called by the runtime. Use this method to add services to the container. 22 | public void ConfigureServices(IServiceCollection services) 23 | { 24 | services 25 | .AddDistributedMemoryCache() 26 | .AddMvc() 27 | .AddXmlSerializerFormatters(); 28 | 29 | services.AddTransient(); 30 | services.AddTransient(); 31 | services.AddTransient(); 32 | services.AddTransient(); 33 | services.AddTransient(); 34 | services.AddTransient(); 35 | 36 | services.AddSwaggerGen(c => 37 | { 38 | c.SwaggerDoc("v1", new Info 39 | { 40 | Version = "v1", 41 | Title = "My API", 42 | Description = "My First ASP.NET Core Web API", 43 | TermsOfService = "None", 44 | Contact = new Contact() { Name = "Michał Białecki", Email = "mik.bialecki@gmail.com", Url = "http://michalbialecki.com" } 45 | }); 46 | }); 47 | } 48 | 49 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 50 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 51 | { 52 | if (env.IsDevelopment()) 53 | { 54 | app.UseDeveloperExceptionPage(); 55 | } 56 | 57 | app.UseMvc(); 58 | 59 | 60 | app.UseSwagger(); 61 | app.UseSwaggerUI(c => 62 | { 63 | c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); 64 | }); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/Users/IUserService.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.NetCore.Web.Users 2 | { 3 | using System.Threading.Tasks; 4 | 5 | public interface IUserService 6 | { 7 | Task ExportUsersToExternalSystem(); 8 | } 9 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/Users/IUsersRepository.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.NetCore.Web.Users 2 | { 3 | using System.Collections.Generic; 4 | using System.Threading.Tasks; 5 | 6 | public interface IUsersRepository 7 | { 8 | Task GetUserById(int userId); 9 | 10 | Task> GetUsersById(IEnumerable userIds); 11 | 12 | Task AddUser(string name); 13 | 14 | Task> GetCountByCountryCode(string countryCode); 15 | 16 | Task> GetCountByCountryCodeAsAnsi(string countryCode); 17 | 18 | Task InsertMany(IEnumerable userNames); 19 | 20 | Task SafeInsertMany(IEnumerable userNames); 21 | 22 | Task InsertInBulk(IList userNames); 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/Users/UserDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MichalBialecki.com.NetCore.Web.Users 4 | { 5 | [Serializable] 6 | public class UserDto 7 | { 8 | public int Id { get; set; } 9 | 10 | public string Name { get; set; } 11 | 12 | public string CountryCode { get; set; } 13 | 14 | public DateTime LastModified { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/Users/UserService.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.NetCore.Web.Users 2 | { 3 | using System.Threading.Tasks; 4 | 5 | public class UserService : IUserService 6 | { 7 | public async Task ExportUsersToExternalSystem() 8 | { 9 | return await Task.FromResult(true); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/Users/UsersController.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.NetCore.Web.Users 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Diagnostics; 6 | using System.Linq; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | 10 | using Microsoft.AspNetCore.Mvc; 11 | using Microsoft.Extensions.Caching.Distributed; 12 | using Microsoft.Extensions.Caching.Memory; 13 | 14 | [Route("api/[controller]")] 15 | public class UsersController : Controller 16 | { 17 | private static Random random = new Random(); 18 | 19 | private readonly IUsersRepository _usersRepository; 20 | 21 | private readonly IDistributedCache _distributedCache; 22 | 23 | private readonly IUserService _userService; 24 | 25 | public UsersController(IUsersRepository usersRepository, IUserService userService, IDistributedCache distributedCache) 26 | { 27 | _usersRepository = usersRepository; 28 | _userService = userService; 29 | _distributedCache = distributedCache; 30 | } 31 | 32 | [HttpGet("{id}")] 33 | public async Task Get(int id) 34 | { 35 | var cacheKey = $"User_{id}"; 36 | UserDto user; 37 | var userBytes = await _distributedCache.GetAsync(cacheKey); 38 | if (userBytes == null) 39 | { 40 | user = await _usersRepository.GetUserById(id); 41 | userBytes = CacheHelper.Serialize(user); 42 | await _distributedCache.SetAsync( 43 | cacheKey, 44 | userBytes, 45 | new DistributedCacheEntryOptions { SlidingExpiration = TimeSpan.FromMinutes(5) }); 46 | } 47 | 48 | user = CacheHelper.Deserialize(userBytes); 49 | return Json(user); 50 | } 51 | 52 | [HttpPost("GetMany")] 53 | public async Task GetMany([FromBody]IEnumerable ids) 54 | { 55 | var users = await _usersRepository.GetUsersById(ids); 56 | return Json(users); 57 | } 58 | 59 | [HttpPost("InsertMany")] 60 | public async Task InsertMany(int? number = 100) 61 | { 62 | var userNames = new List(); 63 | for (int i = 0; i < number; i++) 64 | { 65 | userNames.Add(RandomString(10)); 66 | } 67 | 68 | var stopwatch = new Stopwatch(); 69 | stopwatch.Start(); 70 | 71 | await _usersRepository.InsertMany(userNames); 72 | 73 | stopwatch.Stop(); 74 | return Json( 75 | new { 76 | users = number, 77 | time = stopwatch.Elapsed 78 | }); 79 | } 80 | 81 | [HttpPost("SafeInsertMany")] 82 | public async Task SafeInsertMany(int? number = 100) 83 | { 84 | var userNames = new List(); 85 | for (int i = 0; i < number; i++) 86 | { 87 | userNames.Add(RandomString(10)); 88 | } 89 | 90 | var stopwatch = new Stopwatch(); 91 | stopwatch.Start(); 92 | 93 | await _usersRepository.SafeInsertMany(userNames); 94 | 95 | stopwatch.Stop(); 96 | return Json( 97 | new 98 | { 99 | users = number, 100 | time = stopwatch.Elapsed 101 | }); 102 | } 103 | 104 | [HttpPost("InsertInBulk")] 105 | public async Task InsertInBulk(int? number = 100) 106 | { 107 | var userNames = new List(); 108 | for (int i = 0; i < number; i++) 109 | { 110 | userNames.Add(RandomString(10)); 111 | } 112 | 113 | var stopwatch = new Stopwatch(); 114 | stopwatch.Start(); 115 | 116 | await _usersRepository.InsertInBulk(userNames); 117 | 118 | stopwatch.Stop(); 119 | return Json( 120 | new 121 | { 122 | users = number, 123 | time = stopwatch.Elapsed 124 | }); 125 | } 126 | 127 | [HttpGet("GetCountByCountryCode")] 128 | public async Task GetTop100ByCountryCode() 129 | { 130 | var watch = new Stopwatch(); 131 | watch.Start(); 132 | 133 | var count1 = await _usersRepository.GetCountByCountryCode("PL"); 134 | watch.Stop(); 135 | var elapsedCount1 = watch.Elapsed; 136 | watch.Reset(); 137 | watch.Start(); 138 | 139 | var count2 = await _usersRepository.GetCountByCountryCodeAsAnsi("PL"); 140 | watch.Stop(); 141 | 142 | return Json(new { TimeElapsed = elapsedCount1, TimeElaspedWitAnsi = watch.Elapsed }); 143 | } 144 | 145 | [HttpPost("ExportUsers")] 146 | public IActionResult ExportUsers() 147 | { 148 | var thread = new Thread(async () => 149 | { 150 | var result = await _userService.ExportUsersToExternalSystem(); 151 | if (!result) 152 | { 153 | // log error 154 | } 155 | }) 156 | { 157 | IsBackground = true 158 | }; 159 | thread.Start(); 160 | 161 | return Ok(); 162 | } 163 | 164 | private static string RandomString(int length) 165 | { 166 | const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 167 | return new string(Enumerable.Repeat(chars, length) 168 | .Select(s => s[random.Next(s.Length)]).ToArray()); 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/Users/UsersRepository.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.NetCore.Web.Users 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Data; 6 | using System.Data.SqlClient; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | using Dapper; 11 | 12 | public class UsersRepository : IUsersRepository 13 | { 14 | private const string ConnectionString = "Data Source=localhost;Initial Catalog=Blog;Integrated Security=True"; 15 | private readonly Random random = new Random(); 16 | 17 | public async Task GetUserById(int userId) 18 | { 19 | using (var connection = new SqlConnection(ConnectionString)) 20 | { 21 | return await connection.QueryFirstOrDefaultAsync( 22 | "SELECT [Id], [Name], [LastUpdatedAt] FROM [Users] WHERE Id = @Id", 23 | new { Id = userId }).ConfigureAwait(false); 24 | } 25 | } 26 | 27 | public async Task> GetUsersById(IEnumerable userIds) 28 | { 29 | using (var connection = new SqlConnection(ConnectionString)) 30 | { 31 | return await connection.QueryAsync( 32 | "SELECT [Id], [Name], [LastUpdatedAt] FROM [Users] WHERE Id IN @Ids", 33 | new { Ids = userIds }).ConfigureAwait(false); 34 | } 35 | } 36 | 37 | public async Task AddUser(string name) 38 | { 39 | var countryCode = random.NextDouble() > 0.5 ? "US" : "PL"; 40 | using (var connection = new SqlConnection(ConnectionString)) 41 | { 42 | await connection.ExecuteAsync( 43 | "INSERT INTO [Users] (Name, CountryCode, LastUpdatedAt) VALUES (@Name, @countryCode, getdate())", 44 | new { name, countryCode }).ConfigureAwait(false); 45 | } 46 | } 47 | 48 | public async Task> GetCountByCountryCode(string countryCode) 49 | { 50 | using (var connection = new SqlConnection(ConnectionString)) 51 | { 52 | return await connection.QueryAsync( 53 | "SELECT count(*) FROM [Users] WHERE CountryCode = @CountryCode", 54 | new { CountryCode = countryCode }).ConfigureAwait(false); 55 | } 56 | } 57 | 58 | public async Task> GetCountByCountryCodeAsAnsi(string countryCode) 59 | { 60 | using (var connection = new SqlConnection(ConnectionString)) 61 | { 62 | return await connection.QueryAsync( 63 | "SELECT count(*) FROM [Users] WHERE CountryCode = @CountryCode", 64 | new { CountryCode = new DbString() { Value = countryCode, IsAnsi = true, Length = 2 } }) 65 | .ConfigureAwait(false); 66 | } 67 | } 68 | 69 | public async Task InsertMany(IEnumerable userNames) 70 | { 71 | using (var connection = new SqlConnection(ConnectionString)) 72 | { 73 | await connection.ExecuteAsync( 74 | "INSERT INTO [Users] (Name, LastUpdatedAt) VALUES (@Name, getdate())", 75 | userNames.Select(u => new { Name = u })).ConfigureAwait(false); 76 | } 77 | } 78 | 79 | public async Task SafeInsertMany(IEnumerable userNames) 80 | { 81 | using (var connection = new SqlConnection(ConnectionString)) 82 | { 83 | var parameters = userNames.Select(u => 84 | { 85 | var tempParams = new DynamicParameters(); 86 | tempParams.Add("@Name", u, DbType.String, ParameterDirection.Input); 87 | return tempParams; 88 | }); 89 | 90 | await connection.ExecuteAsync( 91 | "INSERT INTO [Users] (Name, LastUpdatedAt) VALUES (@Name, getdate())", 92 | parameters).ConfigureAwait(false); 93 | } 94 | } 95 | 96 | public async Task InsertInBulk(IList userNames) 97 | { 98 | var sqls = GetSqlsInBatches(userNames); 99 | using (var connection = new SqlConnection(ConnectionString)) 100 | { 101 | foreach (var sql in sqls) 102 | { 103 | await connection.ExecuteAsync(sql); 104 | } 105 | } 106 | } 107 | 108 | private IList GetSqlsInBatches(IList userNames) 109 | { 110 | var insertSql = "INSERT INTO [Users] (Name, LastUpdatedAt) VALUES "; 111 | var valuesSql = "('{0}', getdate())"; 112 | var batchSize = 1000; 113 | 114 | var sqlsToExecute = new List(); 115 | var numberOfBatches = (int)Math.Ceiling((double)userNames.Count / batchSize); 116 | 117 | for (int i = 0; i < numberOfBatches; i++) 118 | { 119 | var userToInsert = userNames.Skip(i * batchSize).Take(batchSize); 120 | var valuesToInsert = userToInsert.Select(u => string.Format(valuesSql, u)); 121 | sqlsToExecute.Add(insertSql + string.Join(',', valuesToInsert)); 122 | } 123 | 124 | return sqlsToExecute; 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.NetCore.Web/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "Debug": { 5 | "LogLevel": { 6 | "Default": "Warning" 7 | } 8 | }, 9 | "Console": { 10 | "LogLevel": { 11 | "Default": "Warning" 12 | } 13 | } 14 | }, 15 | "ApplicationInsights": { 16 | "InstrumentationKey": "61794031-0be5-4391-9a5c-2acbd58978af" 17 | } 18 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/App_Start/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | 4 | namespace Bialecki.com.Odata.Web 5 | { 6 | public class FilterConfig 7 | { 8 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 9 | { 10 | filters.Add(new HandleErrorAttribute()); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using System.Web.Routing; 3 | 4 | namespace Bialecki.com.Odata.Web 5 | { 6 | public class RouteConfig 7 | { 8 | public static void RegisterRoutes(RouteCollection routes) 9 | { 10 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 11 | 12 | routes.MapRoute( 13 | name: "Default", 14 | url: "{controller}/{action}/{id}", 15 | defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 16 | ); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Http; 2 | 3 | namespace Bialecki.com.Odata.Web 4 | { 5 | public static class WebApiConfig 6 | { 7 | public static void Register(HttpConfiguration config) 8 | { 9 | config.MapHttpAttributeRoutes(); 10 | 11 | config.Routes.MapHttpRoute( 12 | name: "DefaultApi", 13 | routeTemplate: "api/{controller}/{id}", 14 | defaults: new { id = RouteParameter.Optional } 15 | ); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/ApplicationInsights.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 12 | search|spider|crawl|Bot|Monitor|AlwaysOn 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 54 | System.Web.Handlers.TransferRequestHandler 55 | Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.RequestDataHttpHandler 56 | System.Web.StaticFileHandler 57 | System.Web.Handlers.AssemblyResourceLoader 58 | System.Web.Optimization.BundleHandler 59 | System.Web.Script.Services.ScriptHandlerFactory 60 | System.Web.Handlers.TraceHandler 61 | System.Web.Services.Discovery.DiscoveryRequestHandler 62 | System.Web.HttpDebugHandler 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 5 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/Controllers/DocumentsController.cs: -------------------------------------------------------------------------------- 1 | using Bialecki.com.Odata.Web.Dtos; 2 | using System.IO; 3 | using System.Net; 4 | using System.Text; 5 | using System.Web.Mvc; 6 | 7 | namespace Bialecki.com.Odata.Web.Controllers 8 | { 9 | public class DocumentsController : Controller 10 | { 11 | // documents/sendDocument 12 | [HttpPost] 13 | public ActionResult SendDocument() 14 | { 15 | try 16 | { 17 | var requestContent = GetRequestContentAsString(); 18 | var document = XmlHelper.XmlDeserializeFromString(requestContent); 19 | 20 | return new HttpStatusCodeResult(HttpStatusCode.OK); 21 | } 22 | catch (System.Exception) 23 | { 24 | // logging 25 | return new HttpStatusCodeResult(HttpStatusCode.InternalServerError); 26 | } 27 | } 28 | 29 | private string GetRequestContentAsString() 30 | { 31 | using (var receiveStream = Request.InputStream) 32 | { 33 | using (var readStream = new StreamReader(receiveStream, Encoding.UTF8)) 34 | { 35 | return readStream.ReadToEnd(); 36 | } 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/Controllers/FoldersController.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Net; 3 | using System.Web.Http; 4 | using System.Web.Http.OData; 5 | using System.Web.Http.OData.Query; 6 | using MichalBialecki.com.Data.Dto; 7 | using Microsoft.Data.OData; 8 | 9 | namespace Bialecki.com.Odata.Web.Controllers 10 | { 11 | public class FoldersController : ApiController 12 | { 13 | private IFoldersAndFilesProvider _provider; 14 | 15 | private ODataValidationSettings _validationSettings; 16 | 17 | public FoldersController(IFoldersAndFilesProvider provider) 18 | { 19 | _provider = provider; 20 | _validationSettings = new ODataValidationSettings(); 21 | } 22 | 23 | [Route("odata/Folders")] 24 | [EnableQuery] 25 | public IQueryable GetFolders() 26 | { 27 | var folders = _provider.GetFolders(); 28 | return folders.AsQueryable(); 29 | } 30 | 31 | // GET: odata/Folders(5) 32 | public IHttpActionResult GetFolder([FromODataUri] string key, ODataQueryOptions queryOptions) 33 | { 34 | try 35 | { 36 | queryOptions.Validate(_validationSettings); 37 | } 38 | catch (ODataException ex) 39 | { 40 | return BadRequest(ex.Message); 41 | } 42 | 43 | return Ok(_provider.GetFolders().FirstOrDefault(f => f.Name.Contains(key))); 44 | } 45 | 46 | // PUT: odata/Folders(5) 47 | public IHttpActionResult Put([FromODataUri] string key, Delta delta) 48 | { 49 | Validate(delta.GetEntity()); 50 | 51 | if (!ModelState.IsValid) 52 | { 53 | return BadRequest(ModelState); 54 | } 55 | 56 | // TODO: Get the entity here. 57 | 58 | // delta.Put(folder); 59 | 60 | // TODO: Save the patched entity. 61 | 62 | // return Updated(folder); 63 | return StatusCode(HttpStatusCode.NotImplemented); 64 | } 65 | 66 | // POST: odata/Folders 67 | public IHttpActionResult Post(Folder folder) 68 | { 69 | if (!ModelState.IsValid) 70 | { 71 | return BadRequest(ModelState); 72 | } 73 | 74 | // TODO: Add create logic here. 75 | 76 | // return Created(folder); 77 | return StatusCode(HttpStatusCode.NotImplemented); 78 | } 79 | 80 | // PATCH: odata/Folders(5) 81 | [AcceptVerbs("PATCH", "MERGE")] 82 | public IHttpActionResult Patch([FromODataUri] string key, Delta delta) 83 | { 84 | Validate(delta.GetEntity()); 85 | 86 | if (!ModelState.IsValid) 87 | { 88 | return BadRequest(ModelState); 89 | } 90 | 91 | // TODO: Get the entity here. 92 | 93 | // delta.Patch(folder); 94 | 95 | // TODO: Save the patched entity. 96 | 97 | // return Updated(folder); 98 | return StatusCode(HttpStatusCode.NotImplemented); 99 | } 100 | 101 | // DELETE: odata/Folders(5) 102 | public IHttpActionResult Delete([FromODataUri] string key) 103 | { 104 | // TODO: Add delete logic here. 105 | 106 | // return StatusCode(HttpStatusCode.NoContent); 107 | return StatusCode(HttpStatusCode.NotImplemented); 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/Controllers/ValuesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Net.Http; 6 | using System.Web.Http; 7 | 8 | namespace Bialecki.com.Odata.Web.Controllers 9 | { 10 | public class ValuesController : ApiController 11 | { 12 | // GET api/values 13 | public IEnumerable Get() 14 | { 15 | return new string[] { "value1", "value2" }; 16 | } 17 | 18 | // GET api/values/5 19 | public string Get(int id) 20 | { 21 | return "value"; 22 | } 23 | 24 | // POST api/values 25 | public void Post([FromBody]string value) 26 | { 27 | } 28 | 29 | // PUT api/values/5 30 | public void Put(int id, [FromBody]string value) 31 | { 32 | } 33 | 34 | // DELETE api/values/5 35 | public void Delete(int id) 36 | { 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/Dtos/Document.cs: -------------------------------------------------------------------------------- 1 | using System.Xml.Serialization; 2 | 3 | namespace Bialecki.com.Odata.Web.Dtos 4 | { 5 | [XmlRoot(ElementName = "document", Namespace = "")] 6 | public class DocumentDto 7 | { 8 | [XmlElement(DataType = "string", ElementName = "id")] 9 | public string Id { get; set; } 10 | 11 | [XmlElement(DataType = "string", ElementName = "content")] 12 | public string Content { get; set; } 13 | 14 | [XmlElement(DataType = "string", ElementName = "author")] 15 | public string Author { get; set; } 16 | 17 | [XmlElement(ElementName = "links")] 18 | public LinkDto Links { get; set; } 19 | } 20 | 21 | public class LinkDto 22 | { 23 | [XmlElement(ElementName = "link")] 24 | public string[] Link { get; set; } 25 | } 26 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="Bialecki.com.Odata.Web.WebApiApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Http; 2 | using System.Web.Mvc; 3 | using System.Web.Routing; 4 | using MichalBialecki.com.Data.Dto; 5 | using SimpleInjector; 6 | using SimpleInjector.Integration.WebApi; 7 | 8 | namespace Bialecki.com.Odata.Web 9 | { 10 | public class WebApiApplication : System.Web.HttpApplication 11 | { 12 | protected void Application_Start() 13 | { 14 | AreaRegistration.RegisterAllAreas(); 15 | GlobalConfiguration.Configure(WebApiConfig.Register); 16 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 17 | RouteConfig.RegisterRoutes(RouteTable.Routes); 18 | 19 | var container = new Container(); 20 | 21 | container.Register(Lifestyle.Singleton); 22 | container.RegisterWebApiControllers(GlobalConfiguration.Configuration); 23 | 24 | container.Verify(); 25 | 26 | GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Bialecki.com.Odata.Web")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Bialecki.com.Odata.Web")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("2ba3ff2e-036b-4f79-bf12-9f99be8e9f06")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/Web.Debug.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/Web.Release.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/XmlHelper.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Xml.Serialization; 3 | 4 | namespace Bialecki.com.Odata.Web 5 | { 6 | public static class XmlHelper 7 | { 8 | public static T XmlDeserializeFromString(string objectData) 9 | { 10 | var serializer = new XmlSerializer(typeof(T)); 11 | 12 | using (var reader = new StringReader(objectData)) 13 | { 14 | return (T)serializer.Deserialize(reader); 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.Odata.Web/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.PriceComparer.Web/Controllers/ProductController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using MichalBialecki.com.PriceComparer.Web.Repositories; 4 | using Microsoft.AspNetCore.Mvc; 5 | 6 | namespace MichalBialecki.com.PriceComparer.Web.Controllers 7 | { 8 | [Route("api/[controller]")] 9 | [ApiController] 10 | public class ProductController : ControllerBase 11 | { 12 | private readonly IProductRepository _productRepository; 13 | 14 | public ProductController(IProductRepository productRepository) 15 | { 16 | _productRepository = productRepository; 17 | } 18 | 19 | [HttpGet("{id}")] 20 | public async Task> Get(string id) 21 | { 22 | try 23 | { 24 | var product = await _productRepository.Get(id); 25 | return new JsonResult(product); 26 | } 27 | catch (Exception e) 28 | { 29 | Console.WriteLine(e); 30 | throw; 31 | } 32 | } 33 | 34 | [HttpPost] 35 | public async Task Post([FromBody] Product product) 36 | { 37 | try 38 | { 39 | await _productRepository.Save(product); 40 | } 41 | catch (Exception e) 42 | { 43 | Console.WriteLine(e); 44 | throw; 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.PriceComparer.Web/Controllers/SellerController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using MichalBialecki.com.PriceComparer.Web.Repositories; 4 | using Microsoft.AspNetCore.Mvc; 5 | 6 | namespace MichalBialecki.com.PriceComparer.Web.Controllers 7 | { 8 | [Route("api/[controller]")] 9 | [ApiController] 10 | public class SellerController : ControllerBase 11 | { 12 | private readonly ISellerRepository _sellerRepository; 13 | 14 | public SellerController(ISellerRepository sellerRepository) 15 | { 16 | _sellerRepository = sellerRepository; 17 | } 18 | 19 | [HttpGet("{id}")] 20 | public async Task> Get(string id) 21 | { 22 | try 23 | { 24 | var seller = await _sellerRepository.Get(id); 25 | return new JsonResult(seller); 26 | } 27 | catch (Exception e) 28 | { 29 | Console.WriteLine(e); 30 | throw; 31 | } 32 | } 33 | 34 | [HttpPost] 35 | public async Task Post([FromBody] Seller seller) 36 | { 37 | try 38 | { 39 | await _sellerRepository.Save(seller); 40 | } 41 | catch (Exception e) 42 | { 43 | Console.WriteLine(e); 44 | throw; 45 | } 46 | } 47 | 48 | [HttpPost("{id}/mark/{mark}")] 49 | public async Task AddMark(string id, decimal mark) 50 | { 51 | try 52 | { 53 | var seller = await _sellerRepository.Get(id); 54 | if (seller == null) 55 | { 56 | return; 57 | } 58 | 59 | seller.MarksCount += 1; 60 | seller.MarksSum += mark; 61 | 62 | await _sellerRepository.Update(seller); 63 | } 64 | catch (Exception e) 65 | { 66 | Console.WriteLine(e); 67 | throw; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.PriceComparer.Web/MichalBialecki.com.PriceComparer.Web.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.PriceComparer.Web/Offer.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.PriceComparer.Web 2 | { 3 | public class Offer 4 | { 5 | public string ProductId { get; set; } 6 | 7 | public decimal Price { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.PriceComparer.Web/Product.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MichalBialecki.com.PriceComparer.Web 4 | { 5 | public class Product 6 | { 7 | public Product() 8 | { 9 | Offers = new List(); 10 | } 11 | 12 | public string Id { get; set; } 13 | 14 | public string Name { get; set; } 15 | 16 | public List Offers { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.PriceComparer.Web/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace MichalBialecki.com.PriceComparer.Web 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | CreateWebHostBuilder(args).Build().Run(); 11 | } 12 | 13 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 14 | WebHost.CreateDefaultBuilder(args) 15 | .UseStartup(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.PriceComparer.Web/Repositories/IProductRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace MichalBialecki.com.PriceComparer.Web.Repositories 4 | { 5 | public interface IProductRepository 6 | { 7 | Task Get(string id); 8 | Task Save(Product product); 9 | } 10 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.PriceComparer.Web/Repositories/ISellerRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace MichalBialecki.com.PriceComparer.Web.Repositories 4 | { 5 | public interface ISellerRepository 6 | { 7 | Task Get(string id); 8 | Task Save(Seller seller); 9 | Task Update(Seller seller); 10 | } 11 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.PriceComparer.Web/Repositories/ProductRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Data.SqlClient; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using Dapper; 5 | using Microsoft.Extensions.Configuration; 6 | 7 | namespace MichalBialecki.com.PriceComparer.Web.Repositories 8 | { 9 | public class ProductRepository : IProductRepository 10 | { 11 | private const string RemoveProduct = @"DELETE FROM Product WHERE Id = @Id"; 12 | 13 | private const string RemoveProductOffers = @"DELETE FROM ProductOffer WHERE ProductId = @Id"; 14 | 15 | private const string InsertProduct = @"INSERT INTO Product (Id, Name) VALUES (@Id, @Name)"; 16 | 17 | private const string InsertProductOffer = @"INSERT INTO ProductOffer (ProductId, Price, SellerId) VALUES (@ProductId, @Price, @SellerId)"; 18 | 19 | private const string GetProduct = @"SELECT Id, Name FROM Product WHERE Id = @id"; 20 | 21 | private const string GetProductOffers = @" 22 | SELECT p.ProductId, p.Price, s.Id, s.Name, s.MarksSum / (CASE WHEN s.MarksCount = 0 THEN 1 ELSE 1 END) as SellerRating 23 | FROM ProductOffer p JOIN Seller s on p.SellerId = s.Id 24 | WHERE ProductId = @id"; 25 | 26 | private readonly IConfigurationRoot _configuration; 27 | 28 | public ProductRepository(IConfigurationRoot configuration) 29 | { 30 | _configuration = configuration; 31 | } 32 | 33 | public async Task Save(Product product) 34 | { 35 | using (var connection = new SqlConnection(_configuration.GetConnectionString("DbConnectionString"))) 36 | { 37 | await connection.ExecuteAsync(RemoveProduct, new { product.Id }); 38 | await connection.ExecuteAsync(RemoveProductOffers, new { product.Id }); 39 | 40 | await connection.ExecuteAsync(InsertProduct, product); 41 | await connection.ExecuteAsync(InsertProductOffer, product.Offers); 42 | } 43 | } 44 | 45 | public async Task Get(string id) 46 | { 47 | using (var connection = new SqlConnection(_configuration.GetConnectionString("DbConnectionString"))) 48 | { 49 | var product = await connection.QuerySingleOrDefaultAsync(GetProduct, new { id }); 50 | if (product == null) 51 | { 52 | return null; 53 | } 54 | 55 | var productOffers = await connection.QueryAsync(GetProductOffers, new { id }); 56 | 57 | product.Offers = productOffers.OrderByDescending(o => o.SellerRating).ToList(); 58 | return product; 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.PriceComparer.Web/Repositories/SellerRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Data.SqlClient; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using Dapper; 5 | using Microsoft.Extensions.Configuration; 6 | 7 | namespace MichalBialecki.com.PriceComparer.Web.Repositories 8 | { 9 | public class SellerRepository : ISellerRepository 10 | { 11 | private const string RemoveSeller = @"DELETE FROM Seller WHERE Id = @Id"; 12 | 13 | private const string InsertSeller = @"INSERT INTO Seller (Id, Name, MarksCount, MarksSum) VALUES (@Id, @Name, @MarksCount, @MarksSum)"; 14 | 15 | private const string UpdateSellerRating = @"UPDATE Seller SET MarksCount = @MarksCount, MarksSum = @MarksSum WHERE Id = @Id"; 16 | 17 | private const string GetSeller = @"SELECT Id, Name, MarksCount, MarksSum FROM Seller WHERE Id = @id"; 18 | 19 | private const string GetSellerOffers = @"SELECT ProductId, Price FROM ProductOffer WHERE SellerId = @id"; 20 | 21 | private readonly IConfigurationRoot _configuration; 22 | 23 | public SellerRepository(IConfigurationRoot configuration) 24 | { 25 | _configuration = configuration; 26 | } 27 | 28 | public async Task Save(Seller seller) 29 | { 30 | using (var connection = new SqlConnection(_configuration.GetConnectionString("DbConnectionString"))) 31 | { 32 | await connection.ExecuteAsync(RemoveSeller, new { seller.Id }); 33 | 34 | await connection.ExecuteAsync(InsertSeller, seller); 35 | } 36 | } 37 | 38 | public async Task Get(string id) 39 | { 40 | using (var connection = new SqlConnection(_configuration.GetConnectionString("DbConnectionString"))) 41 | { 42 | var sellerOffers = await connection.QueryAsync(GetSellerOffers, new { id }); 43 | var seller = await connection.QuerySingleAsync(GetSeller, new { id }); 44 | 45 | seller.Offers = sellerOffers.ToList(); 46 | 47 | return seller; 48 | } 49 | } 50 | 51 | public async Task Update(Seller seller) 52 | { 53 | using (var connection = new SqlConnection(_configuration.GetConnectionString("DbConnectionString"))) 54 | { 55 | await connection.ExecuteAsync(UpdateSellerRating, seller); 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.PriceComparer.Web/Seller.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace MichalBialecki.com.PriceComparer.Web 5 | { 6 | public class Seller 7 | { 8 | public Seller() 9 | { 10 | Offers = new List(); 11 | } 12 | 13 | public string Id { get; set; } 14 | 15 | public string Name { get; set; } 16 | 17 | public int MarksCount { get; set; } 18 | 19 | public decimal MarksSum { get; set; } 20 | 21 | public decimal Rating => Math.Round(MarksSum / (MarksCount == 0 ? 1 : MarksCount), 2); 22 | 23 | public List Offers { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.PriceComparer.Web/SellerOffer.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.PriceComparer.Web 2 | { 3 | public class SellerOffer 4 | { 5 | public string ProductId { get; set; } 6 | 7 | public decimal Price { get; set; } 8 | 9 | public string SellerId { get; set; } 10 | 11 | public string SellerName { get; set; } 12 | 13 | public decimal SellerRating { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.PriceComparer.Web/Startup.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using MichalBialecki.com.PriceComparer.Web.Repositories; 3 | using Microsoft.AspNetCore.Builder; 4 | using Microsoft.AspNetCore.Hosting; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.DependencyInjection; 8 | using Newtonsoft.Json; 9 | using Newtonsoft.Json.Converters; 10 | using Newtonsoft.Json.Serialization; 11 | 12 | namespace MichalBialecki.com.PriceComparer.Web 13 | { 14 | public class Startup 15 | { 16 | private IConfigurationRoot configuration; 17 | 18 | public Startup(IConfiguration configuration) 19 | { 20 | Configuration = configuration; 21 | } 22 | 23 | public IConfiguration Configuration { get; } 24 | 25 | // This method gets called by the runtime. Use this method to add services to the container. 26 | public void ConfigureServices(IServiceCollection services) 27 | { 28 | var builder = new ConfigurationBuilder() 29 | .SetBasePath(Directory.GetCurrentDirectory()) 30 | .AddJsonFile("appsettings.json"); 31 | 32 | configuration = builder.Build(); 33 | 34 | services 35 | .AddMvc() 36 | .SetCompatibilityVersion(CompatibilityVersion.Version_2_1) 37 | .AddJsonOptions(options => 38 | { 39 | options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 40 | options.SerializerSettings.Converters.Add(new StringEnumConverter()); 41 | options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; 42 | }); 43 | 44 | services.AddSwaggerGen(p => 45 | { 46 | p.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info { Title = "PriceComparer.Api", Version = "v1" }); 47 | }); 48 | 49 | services.AddSingleton(configuration); 50 | services.AddSingleton(); 51 | services.AddSingleton(); 52 | } 53 | 54 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 55 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 56 | { 57 | if (env.IsDevelopment()) 58 | { 59 | app.UseDeveloperExceptionPage(); 60 | } 61 | 62 | app.UseSwagger(); 63 | 64 | app.UseSwaggerUI(options => 65 | { 66 | options.SwaggerEndpoint("/swagger/v1/swagger.json", "Komplett.ServicePartners.Info.Api"); 67 | }); 68 | 69 | app.UseMvc(routes => 70 | { 71 | routes.MapRoute( 72 | name: "default", 73 | template: "{controller=Home}/{action=Index}/{id?}"); 74 | }); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBus.Examples/AccountEntity.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.CosmosDB.Table; 2 | 3 | namespace ServiceBusExamples 4 | { 5 | public class AccountEntity : TableEntity 6 | { 7 | public AccountEntity() { } 8 | 9 | public AccountEntity(string partition, string accountNumber) 10 | { 11 | PartitionKey = partition; 12 | RowKey = accountNumber; 13 | } 14 | 15 | public double Balance { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBus.Examples/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBus.Examples/MessageReceiverOld.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Microsoft.ServiceBus.Messaging; 4 | 5 | namespace MichalBialecki.com.ServiceBus.Examples 6 | { 7 | public class MessageReceiverOld 8 | { 9 | private const string ServiceBusConnectionString = "Endpoint=sb://bialecki.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=39cH/mE4siF49REMd9xtjVlUwoc0yPJNz9J8isRc9vY="; 10 | 11 | public async Task ReceiveOne() 12 | { 13 | var queueClient = QueueClient.CreateFromConnectionString(ServiceBusConnectionString, "go_testing", ReceiveMode.PeekLock); 14 | 15 | var message = await queueClient.ReceiveAsync(); 16 | Console.WriteLine($"Received: {message.GetBody()}, time: {DateTime.Now}"); 17 | 18 | await message.CompleteAsync(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBus.Examples/MichalBialecki.com.ServiceBus.Examples.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {85C421AB-87A9-418C-B515-BF4BB0D17FA2} 8 | Exe 9 | Properties 10 | ServiceBusExamples 11 | ServiceBusExamples 12 | v4.5.2 13 | 512 14 | true 15 | 16 | 17 | 18 | 19 | AnyCPU 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | ..\packages\Microsoft.Azure.CosmosDB.Table.1.1.0\lib\net45\Microsoft.Azure.CosmosDB.Table.dll 40 | 41 | 42 | ..\packages\Microsoft.Azure.DocumentDB.1.19.0\lib\net45\Microsoft.Azure.Documents.Client.dll 43 | 44 | 45 | ..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll 46 | 47 | 48 | ..\packages\Microsoft.Azure.Storage.Common.8.6.0-preview\lib\net45\Microsoft.Azure.Storage.Common.dll 49 | 50 | 51 | ..\packages\Microsoft.Data.Edm.5.8.2\lib\net40\Microsoft.Data.Edm.dll 52 | 53 | 54 | ..\packages\Microsoft.Data.OData.5.8.2\lib\net40\Microsoft.Data.OData.dll 55 | 56 | 57 | ..\packages\Microsoft.Data.Services.Client.5.8.2\lib\net40\Microsoft.Data.Services.Client.dll 58 | 59 | 60 | ..\packages\Microsoft.OData.Core.7.2.0\lib\portable-net45+win8+wpa81\Microsoft.OData.Core.dll 61 | 62 | 63 | ..\packages\Microsoft.OData.Edm.7.2.0\lib\portable-net45+win8+wpa81\Microsoft.OData.Edm.dll 64 | 65 | 66 | ..\packages\WindowsAzure.ServiceBus.4.1.7\lib\net45\Microsoft.ServiceBus.dll 67 | 68 | 69 | ..\packages\Microsoft.Spatial.7.2.0\lib\portable-net45+win8+wpa81\Microsoft.Spatial.dll 70 | 71 | 72 | 73 | ..\packages\Newtonsoft.Json.11.0.1\lib\net45\Newtonsoft.Json.dll 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | ..\packages\System.Spatial.5.8.2\lib\net40\System.Spatial.dll 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 107 | 108 | 109 | 110 | 117 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBus.Examples/Program.cs: -------------------------------------------------------------------------------- 1 | using MichalBialecki.com.ServiceBus.Examples; 2 | 3 | namespace ServiceBusExamples 4 | { 5 | using System; 6 | 7 | class Program 8 | { 9 | static void Main(string[] args) 10 | { 11 | try 12 | { 13 | (new MessageReceiverOld().ReceiveOne()).GetAwaiter().GetResult(); 14 | //new AccountTransferExample().Process(); 15 | 16 | //SimpleExamples.SimpleAndSmartSendBatch(); 17 | } 18 | catch (Exception ex) 19 | { 20 | Console.WriteLine(ex.Message); 21 | } 22 | 23 | Console.ReadKey(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBus.Examples/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ServiceBusExamples")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ServiceBusExamples")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("85c421ab-87a9-418c-b515-bf4bb0d17fa2")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBus.Examples/TableStorageService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.CosmosDB.Table; 2 | using Microsoft.Azure.Storage; 3 | using System; 4 | 5 | namespace ServiceBusExamples 6 | { 7 | public class TableStorageService 8 | { 9 | private static readonly Lazy lazy = 10 | new Lazy(() => new TableStorageService()); 11 | private static readonly object _lock = new object(); 12 | 13 | private const string CosmosBDConnectionString = "DefaultEndpointsProtocol=https;AccountName=bialecki-t;AccountKey=lDRHuoOFmq3g91orbG1L68YOu7M5DXRgXG8DoHU771IVvNPaijdBEyBuuNh5YY9YkJQXhTU8AJIbEEseC8ZTHg==;TableEndpoint=https://bialecki-t.table.cosmosdb.azure.com:443/;"; 14 | private const string PartitionKey = "Partition1"; 15 | 16 | private CloudTable accountsTable; 17 | 18 | public static TableStorageService Instance { get { return lazy.Value; } } 19 | 20 | public TableStorageService() 21 | { 22 | var storageAccount = CloudStorageAccount.Parse(CosmosBDConnectionString); 23 | var tableClient = storageAccount.CreateCloudTableClient(); 24 | accountsTable = tableClient.GetTableReference("accounts"); 25 | } 26 | 27 | public double UpdateAccount(int accountNumber, double amount) 28 | { 29 | lock(_lock) 30 | { 31 | return UpdateAccountThreadSafe(accountNumber, amount); 32 | } 33 | } 34 | 35 | private double UpdateAccountThreadSafe(int accountNumber, double amount) 36 | { 37 | var getOperation = TableOperation.Retrieve(PartitionKey, accountNumber.ToString()); 38 | var result = accountsTable.Execute(getOperation); 39 | if (result.Result != null) 40 | { 41 | var account = result.Result as AccountEntity; 42 | account.Balance += amount; 43 | var replaceOperation = TableOperation.Replace(account); 44 | accountsTable.Execute(replaceOperation); 45 | 46 | return account.Balance; 47 | } 48 | else 49 | { 50 | var account = new AccountEntity 51 | { 52 | PartitionKey = PartitionKey, 53 | RowKey = accountNumber.ToString(), 54 | Balance = amount 55 | }; 56 | accountsTable.Execute(TableOperation.Insert(account)); 57 | 58 | return amount; 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBus.Examples/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBusCore.Examples/AccountTransfer/Account.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.ServiceBusCore.Examples.AccountTransfer 2 | { 3 | public class Account 4 | { 5 | public string Id { get; set; } 6 | 7 | public decimal Balance { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBusCore.Examples/AccountTransfer/AccountTransferMessage.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.ServiceBusCore.Examples.AccountTransfer 2 | { 3 | public class AccountTransferMessage 4 | { 5 | public int From { get; set; } 6 | 7 | public int To { get; set; } 8 | 9 | public decimal Amount { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBusCore.Examples/AccountTransfer/AccountTransferService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Threading.Tasks; 4 | using Microsoft.Azure.ServiceBus; 5 | using Microsoft.Extensions.Configuration; 6 | using Newtonsoft.Json; 7 | 8 | namespace MichalBialecki.com.ServiceBusCore.Examples.AccountTransfer 9 | { 10 | public class AccountTransferService 11 | { 12 | private const string ServiceBusKey = "ServiceBusConnectionString"; 13 | 14 | private readonly IConfigurationRoot _configuration; 15 | 16 | public AccountTransferService(IConfigurationRoot configuration) 17 | { 18 | _configuration = configuration; 19 | } 20 | 21 | public void Run() 22 | { 23 | var service = new TableStorageService(_configuration); 24 | 25 | try 26 | { 27 | var subscriptionClient = new SubscriptionClient( 28 | _configuration[ServiceBusKey], 29 | "accountTransferUpdates", 30 | "commonSubscription"); 31 | subscriptionClient.PrefetchCount = 1000; 32 | 33 | subscriptionClient.RegisterMessageHandler( 34 | async (message, token) => 35 | { 36 | var messageJson = Encoding.UTF8.GetString(message.Body); 37 | var updateMessage = JsonConvert.DeserializeObject(messageJson); 38 | 39 | await service.UpdateAccount(updateMessage.From, -updateMessage.Amount); 40 | await service.UpdateAccount(updateMessage.To, updateMessage.Amount); 41 | 42 | Console.WriteLine($"Processed a message from {updateMessage.From} to {updateMessage.To}"); 43 | }, 44 | new MessageHandlerOptions(OnException) 45 | { 46 | MaxAutoRenewDuration = TimeSpan.FromMinutes(60), 47 | MaxConcurrentCalls = 1, 48 | AutoComplete = true 49 | }); 50 | } 51 | catch (Exception e) 52 | { 53 | Console.WriteLine("Exception: " + e.Message); 54 | } 55 | } 56 | 57 | private Task OnException(ExceptionReceivedEventArgs args) 58 | { 59 | Console.WriteLine(args.Exception); 60 | 61 | return Task.CompletedTask; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBusCore.Examples/AccountTransfer/BalanceUpdateMessage.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.ServiceBusCore.Examples.AccountTransfer 2 | { 3 | public class BalanceUpdateMessage 4 | { 5 | public int AccountNumber { get; set; } 6 | 7 | public decimal Balance { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBusCore.Examples/AccountTransfer/TableStorageService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | using Microsoft.Azure.Documents; 6 | using Microsoft.Azure.Documents.Client; 7 | using Microsoft.Azure.ServiceBus; 8 | using Microsoft.Extensions.Configuration; 9 | using Newtonsoft.Json; 10 | 11 | namespace MichalBialecki.com.ServiceBusCore.Examples.AccountTransfer 12 | { 13 | public class TableStorageService 14 | { 15 | private const string EndpointUriKey = "CosmosDbEndpointUri"; 16 | private const string PrimaryKeyKey = "CosmosDbPrimaryKey"; 17 | private const string ServiceBusKey = "ServiceBusConnectionString"; 18 | 19 | private readonly DocumentClient client; 20 | private readonly TopicClient topic; 21 | 22 | public TableStorageService(IConfigurationRoot configuration) 23 | { 24 | client = new DocumentClient(new Uri(configuration[EndpointUriKey]), configuration[PrimaryKeyKey]); 25 | topic = new TopicClient(configuration[ServiceBusKey], "balanceUpdates"); 26 | } 27 | 28 | public async Task UpdateAccount(int accountNumber, decimal amount) 29 | { 30 | Account document; 31 | try 32 | { 33 | var response = await client.ReadDocumentAsync(accountNumber.ToString()); 34 | document = response.Document; 35 | document.Balance += amount; 36 | await client.ReplaceDocumentAsync(accountNumber.ToString(), document); 37 | } 38 | catch (DocumentClientException de) 39 | { 40 | if (de.StatusCode == HttpStatusCode.NotFound) 41 | { 42 | document = new Account { Id = accountNumber.ToString(), Balance = amount }; 43 | await client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri("bialecki", "accounts"), document); 44 | } 45 | else 46 | { 47 | throw; 48 | } 49 | } 50 | 51 | await NotifyBalanceUpdate(accountNumber, document.Balance); 52 | } 53 | 54 | private async Task NotifyBalanceUpdate(int accountNumber, decimal balance) 55 | { 56 | var balanceUpdate = new BalanceUpdateMessage 57 | { 58 | AccountNumber = accountNumber, 59 | Balance = balance 60 | }; 61 | 62 | var message = new Message(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(balanceUpdate))); 63 | await topic.SendAsync(message); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBusCore.Examples/MessageReceiver.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.ServiceBus; 2 | using Newtonsoft.Json; 3 | using System; 4 | using System.Text; 5 | 6 | namespace MichalBialecki.com.ServiceBusCore.Examples 7 | { 8 | public class MessageReceiver 9 | { 10 | private const string ServiceBusConnectionString = "Endpoint=sb://bialecki.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=39cH/mE4siF49REMd9xtjVlUwoc0yPJNz9J8isRc9vY="; 11 | 12 | public void Receive() 13 | { 14 | var subscriptionClient = new SubscriptionClient(ServiceBusConnectionString, "productRatingUpdates", "sampleSubscription"); 15 | 16 | try 17 | { 18 | subscriptionClient.RegisterMessageHandler( 19 | async (message, token) => 20 | { 21 | var messageJson = Encoding.UTF8.GetString(message.Body); 22 | var updateMessage = JsonConvert.DeserializeObject(messageJson); 23 | 24 | Console.WriteLine($"Received message with productId: {updateMessage.ProductId}"); 25 | 26 | await subscriptionClient.CompleteAsync(message.SystemProperties.LockToken); 27 | }, 28 | new MessageHandlerOptions(async args => Console.WriteLine(args.Exception)) 29 | { MaxConcurrentCalls = 1, AutoComplete = false }); 30 | } 31 | catch (Exception e) 32 | { 33 | Console.WriteLine("Exception: " + e.Message); 34 | } 35 | } 36 | 37 | public void ReceiveAll() 38 | { 39 | var queueClient = new QueueClient(ServiceBusConnectionString, "go_testing"); 40 | 41 | queueClient.RegisterMessageHandler( 42 | async (message, token) => 43 | { 44 | var messageBody = Encoding.UTF8.GetString(message.Body); 45 | 46 | Console.WriteLine($"Received: {messageBody}, time: {DateTime.Now}"); 47 | 48 | await queueClient.CompleteAsync(message.SystemProperties.LockToken); 49 | }, 50 | new MessageHandlerOptions(async args => Console.WriteLine(args.Exception)) 51 | { MaxConcurrentCalls = 1, AutoComplete = false }); 52 | } 53 | 54 | public void ReceiveOne() 55 | { 56 | var queueClient = new QueueClient(ServiceBusConnectionString, "go_testing"); 57 | 58 | queueClient.RegisterMessageHandler( 59 | async (message, token) => 60 | { 61 | var messageBody = Encoding.UTF8.GetString(message.Body); 62 | Console.WriteLine($"Received: {messageBody}, time: {DateTime.Now}"); 63 | await queueClient.CompleteAsync(message.SystemProperties.LockToken); 64 | 65 | await queueClient.CloseAsync(); 66 | }, 67 | new MessageHandlerOptions(async args => Console.WriteLine(args.Exception)) 68 | { MaxConcurrentCalls = 1, AutoComplete = false }); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBusCore.Examples/MessageSender.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.ServiceBus; 2 | using Newtonsoft.Json; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace MichalBialecki.com.ServiceBusCore.Examples 9 | { 10 | public class MessageSender 11 | { 12 | private const string ServiceBusConnectionString = "Endpoint=sb://bialecki.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=39cH/mE4siF49REMd9xtjVlUwoc0yPJNz9J8isRc9vY="; 13 | 14 | public async Task Send() 15 | { 16 | try 17 | { 18 | //var productRating = new ProductRatingUpdateMessage { ProductId = 123, RatingSum = 23 }; 19 | //var message = new Message(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(productRating))){ SessionId = "S1" }; 20 | 21 | var topicClient = new TopicClient(ServiceBusConnectionString, "accountTransferUpdates"); 22 | for (int i = 0; i < 10; i++) 23 | { 24 | await topicClient.SendAsync(GetMessages()); 25 | Console.WriteLine($"Sending message batch {i}"); 26 | } 27 | } 28 | catch (Exception e) 29 | { 30 | Console.WriteLine(e); 31 | } 32 | } 33 | 34 | private List GetMessages() 35 | { 36 | var rand = new Random(); 37 | var messages = new List(); 38 | for (int i = 0; i < 100; i++) 39 | { 40 | messages.Add(new Message(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject( 41 | new { From = rand.Next(1, 1000), To = rand.Next(1, 1000), Amount = rand.Next(20, 800) })))); 42 | } 43 | 44 | return messages; 45 | } 46 | 47 | public async Task Send1000() 48 | { 49 | var queueClient = new QueueClient(ServiceBusConnectionString, "go_testing"); 50 | for (int i = 0; i < 1000; i++) 51 | { 52 | await queueClient.SendAsync(new Message(Encoding.UTF8.GetBytes("Message number " + i))); 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBusCore.Examples/MichalBialecki.com.ServiceBusCore.Examples.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Always 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.extensions.configuration\2.0.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBusCore.Examples/ProductRatingUpdateMessage.cs: -------------------------------------------------------------------------------- 1 | namespace MichalBialecki.com.ServiceBusCore.Examples 2 | { 3 | public class ProductRatingUpdateMessage 4 | { 5 | public int ProductId { get; set; } 6 | 7 | public int SellerId { get; set; } 8 | 9 | public int RatingSum { get; set; } 10 | 11 | public int RatingCount { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBusCore.Examples/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using System; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using MichalBialecki.com.ServiceBusCore.Examples.AccountTransfer; 6 | 7 | namespace MichalBialecki.com.ServiceBusCore.Examples 8 | { 9 | class Program 10 | { 11 | private static IConfigurationRoot configuration; 12 | 13 | static void Main(string[] args) 14 | { 15 | var builder = new ConfigurationBuilder() 16 | .SetBasePath(Directory.GetCurrentDirectory()) 17 | .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); 18 | 19 | configuration = builder.Build(); 20 | 21 | var s = new Stopwatch(); 22 | s.Start(); 23 | 24 | var service = new AccountTransferService(configuration); 25 | 26 | Console.WriteLine("Starting..."); 27 | //service.Run(); 28 | /* 29 | var builder = new ConfigurationBuilder() 30 | .SetBasePath(Directory.GetCurrentDirectory()) 31 | .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); 32 | 33 | var configuration = builder.Build(); 34 | 35 | var manager = new ServiceBusManager(); 36 | 37 | manager.GetOrCreateTopicSubscription( 38 | configuration["ServiceBusConnectionString"], 39 | "balanceUpdates", 40 | "saveSubscription").GetAwaiter().GetResult(); 41 | */ 42 | (new MessageSender().Send()).GetAwaiter().GetResult(); 43 | 44 | //new MessageReceiver().Receive(); 45 | 46 | //new MessageProcessor().Process(); 47 | 48 | //(new MessageReceiver()).ReceiveAll(); 49 | 50 | //(new MessageSender()).Send1000().GetAwaiter().GetResult(); 51 | 52 | s.Stop(); 53 | 54 | //Console.WriteLine("Sent in: " + s.Elapsed); 55 | 56 | //Console.WriteLine("Done"); 57 | Console.ReadKey(); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBusCore.Examples/ServiceBusManager.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.ServiceBus; 2 | using Microsoft.Azure.ServiceBus.Management; 3 | using System.Threading.Tasks; 4 | 5 | namespace MichalBialecki.com.ServiceBusCore.Examples 6 | { 7 | public class ServiceBusManager 8 | { 9 | public async Task GetOrCreateQueue(string serviceBusConnectionString, string queueName) 10 | { 11 | var managementClient = new ManagementClient(serviceBusConnectionString); 12 | if (!(await managementClient.QueueExistsAsync(queueName))) 13 | { 14 | await managementClient.CreateQueueAsync(new QueueDescription(queueName)); 15 | } 16 | 17 | var queueClient = new QueueClient(serviceBusConnectionString, queueName); 18 | return queueClient; 19 | } 20 | 21 | public async Task GetOrCreateTopic(string serviceBusConnectionString, string topicPath) 22 | { 23 | var managementClient = new ManagementClient(serviceBusConnectionString); 24 | if (!(await managementClient.TopicExistsAsync(topicPath))) 25 | { 26 | await managementClient.CreateTopicAsync(new TopicDescription(topicPath)); 27 | } 28 | 29 | var topicClient = new TopicClient(serviceBusConnectionString, topicPath); 30 | return topicClient; 31 | } 32 | 33 | public async Task GetOrCreateTopicSubscription(string serviceBusConnectionString, string topicPath, string subscriptionName) 34 | { 35 | var managementClient = new ManagementClient(serviceBusConnectionString); 36 | #if DEBUG 37 | if (!(await managementClient.SubscriptionExistsAsync(topicPath, subscriptionName + "_MikTesting"))) 38 | { 39 | await managementClient.CreateSubscriptionAsync( 40 | new SubscriptionDescription(topicPath, subscriptionName + "_MikTesting") 41 | { 42 | EnableBatchedOperations = true, 43 | AutoDeleteOnIdle = System.TimeSpan.FromDays(100), 44 | EnableDeadLetteringOnMessageExpiration = true, 45 | DefaultMessageTimeToLive = System.TimeSpan.FromDays(2), 46 | MaxDeliveryCount = 5, 47 | LockDuration = System.TimeSpan.FromMinutes(5) 48 | }); 49 | } 50 | #else 51 | if (!(await managementClient.SubscriptionExistsAsync(topicPath, subscriptionName))) 52 | { 53 | await managementClient.CreateSubscriptionAsync( 54 | new SubscriptionDescription(topicPath, subscriptionName) 55 | { 56 | EnableBatchedOperations = true, 57 | AutoDeleteOnIdle = System.TimeSpan.FromDays(100), 58 | EnableDeadLetteringOnMessageExpiration = true, 59 | DefaultMessageTimeToLive = System.TimeSpan.FromDays(100), 60 | MaxDeliveryCount = 100, 61 | LockDuration = System.TimeSpan.FromMinutes(5) 62 | }); 63 | } 64 | #endif 65 | var subscriptionClient = new SubscriptionClient(serviceBusConnectionString, topicPath, subscriptionName); 66 | return subscriptionClient; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.ServiceBusCore.Examples/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ServiceBusConnectionString": "Endpoint=sb://bialecki.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=39cH/mE4siF49REMd9xtjVlUwoc0yPJNz9J8isRc9vY=" 3 | } -------------------------------------------------------------------------------- /ServiceBusExamples/MichalBialecki.com.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.27130.2027 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApplicationInsights.DataGenerator", "ApplicationInsights.DataGenerator\ApplicationInsights.DataGenerator.csproj", "{3204B00D-378E-4484-B9D6-70A59A78C54C}" 6 | EndProject 7 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceBusExamples.MessagesSender.NetCore.Web", "ServiceBusExamples.MessagesSender.Web\ServiceBusExamples.MessagesSender.NetCore.Web.csproj", "{3E724019-35C7-45F9-8DF2-B79917C274F2}" 8 | EndProject 9 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MichalBialecki.com.Odata.Web", "MichalBialecki.com.Odata.Web\MichalBialecki.com.Odata.Web.csproj", "{3A63F359-37C7-42E4-B230-757E57773B5B}" 10 | EndProject 11 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MichalBialecki.com.Data.Dto", "MichalBialecki.com.Data.Dto\MichalBialecki.com.Data.Dto.csproj", "{CA8AA267-2BE1-4139-B5FA-711C6D2FB0EA}" 12 | EndProject 13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MichalBialecki.com.Egnyte.Examples", "MichalBialecki.com.Egnyte.Examples\MichalBialecki.com.Egnyte.Examples.csproj", "{8206601C-F9F6-4E27-8911-1696CCB02B81}" 14 | EndProject 15 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MichalBialecki.com.ServiceBusCore.Examples", "MichalBialecki.com.ServiceBusCore.Examples\MichalBialecki.com.ServiceBusCore.Examples.csproj", "{8A9236CA-0C77-4ECA-949F-E19CEA99A1F6}" 16 | EndProject 17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MichalBialecki.com.ServiceBus.Examples", "MichalBialecki.com.ServiceBus.Examples\MichalBialecki.com.ServiceBus.Examples.csproj", "{85C421AB-87A9-418C-B515-BF4BB0D17FA2}" 18 | EndProject 19 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MichalBialecki.com.NetCore.Web", "MichalBialecki.com.NetCore.Web\MichalBialecki.com.NetCore.Web.csproj", "{654A48AB-D935-4990-9646-9A1EAA1C6CE5}" 20 | EndProject 21 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MichalBialecki.com.NetCore.Console", "MichalBialecki.com.NetCore.Console\MichalBialecki.com.NetCore.Console.csproj", "{9A2FD9CA-0A93-4524-87AB-4ED2A3682289}" 22 | EndProject 23 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MichalBialecki.com.ConsoleAppMagic", "MichalBialecki.com.ConsoleAppMagic\MichalBialecki.com.ConsoleAppMagic.csproj", "{EE9A1419-94BB-4B48-886F-EE5B32D577FB}" 24 | EndProject 25 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MichalBialecki.com.Functions", "MichalBialecki.com.Functions\MichalBialecki.com.Functions.csproj", "{0A12C040-E1DE-4D02-B8AF-12DBF023D0CB}" 26 | EndProject 27 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MichalBialecki.com.PriceComparer.Web", "MichalBialecki.com.PriceComparer.Web\MichalBialecki.com.PriceComparer.Web.csproj", "{2CC12B4F-5106-4F04-909B-FCD345EBCA1D}" 28 | EndProject 29 | Global 30 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 31 | Debug|Any CPU = Debug|Any CPU 32 | Release|Any CPU = Release|Any CPU 33 | EndGlobalSection 34 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 35 | {3204B00D-378E-4484-B9D6-70A59A78C54C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 36 | {3204B00D-378E-4484-B9D6-70A59A78C54C}.Debug|Any CPU.Build.0 = Debug|Any CPU 37 | {3204B00D-378E-4484-B9D6-70A59A78C54C}.Release|Any CPU.ActiveCfg = Release|Any CPU 38 | {3204B00D-378E-4484-B9D6-70A59A78C54C}.Release|Any CPU.Build.0 = Release|Any CPU 39 | {3E724019-35C7-45F9-8DF2-B79917C274F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 40 | {3E724019-35C7-45F9-8DF2-B79917C274F2}.Debug|Any CPU.Build.0 = Debug|Any CPU 41 | {3E724019-35C7-45F9-8DF2-B79917C274F2}.Release|Any CPU.ActiveCfg = Release|Any CPU 42 | {3E724019-35C7-45F9-8DF2-B79917C274F2}.Release|Any CPU.Build.0 = Release|Any CPU 43 | {3A63F359-37C7-42E4-B230-757E57773B5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 44 | {3A63F359-37C7-42E4-B230-757E57773B5B}.Debug|Any CPU.Build.0 = Debug|Any CPU 45 | {3A63F359-37C7-42E4-B230-757E57773B5B}.Release|Any CPU.ActiveCfg = Release|Any CPU 46 | {3A63F359-37C7-42E4-B230-757E57773B5B}.Release|Any CPU.Build.0 = Release|Any CPU 47 | {CA8AA267-2BE1-4139-B5FA-711C6D2FB0EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 48 | {CA8AA267-2BE1-4139-B5FA-711C6D2FB0EA}.Debug|Any CPU.Build.0 = Debug|Any CPU 49 | {CA8AA267-2BE1-4139-B5FA-711C6D2FB0EA}.Release|Any CPU.ActiveCfg = Release|Any CPU 50 | {CA8AA267-2BE1-4139-B5FA-711C6D2FB0EA}.Release|Any CPU.Build.0 = Release|Any CPU 51 | {8206601C-F9F6-4E27-8911-1696CCB02B81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 52 | {8206601C-F9F6-4E27-8911-1696CCB02B81}.Debug|Any CPU.Build.0 = Debug|Any CPU 53 | {8206601C-F9F6-4E27-8911-1696CCB02B81}.Release|Any CPU.ActiveCfg = Release|Any CPU 54 | {8206601C-F9F6-4E27-8911-1696CCB02B81}.Release|Any CPU.Build.0 = Release|Any CPU 55 | {8A9236CA-0C77-4ECA-949F-E19CEA99A1F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 56 | {8A9236CA-0C77-4ECA-949F-E19CEA99A1F6}.Debug|Any CPU.Build.0 = Debug|Any CPU 57 | {8A9236CA-0C77-4ECA-949F-E19CEA99A1F6}.Release|Any CPU.ActiveCfg = Release|Any CPU 58 | {8A9236CA-0C77-4ECA-949F-E19CEA99A1F6}.Release|Any CPU.Build.0 = Release|Any CPU 59 | {85C421AB-87A9-418C-B515-BF4BB0D17FA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 60 | {85C421AB-87A9-418C-B515-BF4BB0D17FA2}.Debug|Any CPU.Build.0 = Debug|Any CPU 61 | {85C421AB-87A9-418C-B515-BF4BB0D17FA2}.Release|Any CPU.ActiveCfg = Release|Any CPU 62 | {85C421AB-87A9-418C-B515-BF4BB0D17FA2}.Release|Any CPU.Build.0 = Release|Any CPU 63 | {654A48AB-D935-4990-9646-9A1EAA1C6CE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 64 | {654A48AB-D935-4990-9646-9A1EAA1C6CE5}.Debug|Any CPU.Build.0 = Debug|Any CPU 65 | {654A48AB-D935-4990-9646-9A1EAA1C6CE5}.Release|Any CPU.ActiveCfg = Release|Any CPU 66 | {654A48AB-D935-4990-9646-9A1EAA1C6CE5}.Release|Any CPU.Build.0 = Release|Any CPU 67 | {9A2FD9CA-0A93-4524-87AB-4ED2A3682289}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 68 | {9A2FD9CA-0A93-4524-87AB-4ED2A3682289}.Debug|Any CPU.Build.0 = Debug|Any CPU 69 | {9A2FD9CA-0A93-4524-87AB-4ED2A3682289}.Release|Any CPU.ActiveCfg = Release|Any CPU 70 | {9A2FD9CA-0A93-4524-87AB-4ED2A3682289}.Release|Any CPU.Build.0 = Release|Any CPU 71 | {EE9A1419-94BB-4B48-886F-EE5B32D577FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 72 | {EE9A1419-94BB-4B48-886F-EE5B32D577FB}.Debug|Any CPU.Build.0 = Debug|Any CPU 73 | {EE9A1419-94BB-4B48-886F-EE5B32D577FB}.Release|Any CPU.ActiveCfg = Release|Any CPU 74 | {EE9A1419-94BB-4B48-886F-EE5B32D577FB}.Release|Any CPU.Build.0 = Release|Any CPU 75 | {0A12C040-E1DE-4D02-B8AF-12DBF023D0CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 76 | {0A12C040-E1DE-4D02-B8AF-12DBF023D0CB}.Debug|Any CPU.Build.0 = Debug|Any CPU 77 | {0A12C040-E1DE-4D02-B8AF-12DBF023D0CB}.Release|Any CPU.ActiveCfg = Release|Any CPU 78 | {0A12C040-E1DE-4D02-B8AF-12DBF023D0CB}.Release|Any CPU.Build.0 = Release|Any CPU 79 | {2CC12B4F-5106-4F04-909B-FCD345EBCA1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 80 | {2CC12B4F-5106-4F04-909B-FCD345EBCA1D}.Debug|Any CPU.Build.0 = Debug|Any CPU 81 | {2CC12B4F-5106-4F04-909B-FCD345EBCA1D}.Release|Any CPU.ActiveCfg = Release|Any CPU 82 | {2CC12B4F-5106-4F04-909B-FCD345EBCA1D}.Release|Any CPU.Build.0 = Release|Any CPU 83 | EndGlobalSection 84 | GlobalSection(SolutionProperties) = preSolution 85 | HideSolutionNode = FALSE 86 | EndGlobalSection 87 | GlobalSection(ExtensibilityGlobals) = postSolution 88 | SolutionGuid = {C3373A55-770A-42BA-9879-7657C641E099} 89 | EndGlobalSection 90 | EndGlobal 91 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.Dto/ServiceBusExamples.Dto.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.Dto/SimpleDto.cs: -------------------------------------------------------------------------------- 1 | namespace ServiceBusExamples.Dto 2 | { 3 | public class SimpleDto 4 | { 5 | public string Id { get; set; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/ConfigurationHelper.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using Microsoft.Extensions.Configuration; 3 | 4 | namespace ServiceBusExamples.MessagesSender.NetCore.Web 5 | { 6 | public static class ConfigurationHelper 7 | { 8 | private static IConfigurationRoot configuration; 9 | 10 | public static string GetServiceBusConnectionString() 11 | { 12 | GetConfigurationIfNotExists(); 13 | 14 | return configuration.GetValue("ServiceBusConnectionString"); 15 | } 16 | 17 | public static string GetCosmosDbPrimaryKey() 18 | { 19 | GetConfigurationIfNotExists(); 20 | 21 | return configuration.GetValue("CosmosDBPrimaryKey"); 22 | } 23 | 24 | public static string GetCosmosDbEndpointUri() 25 | { 26 | GetConfigurationIfNotExists(); 27 | 28 | return configuration.GetValue("CosmosDbEndpointUri"); 29 | } 30 | 31 | private static void GetConfigurationIfNotExists() 32 | { 33 | if (configuration != null) 34 | { 35 | return; 36 | } 37 | 38 | var builder = new ConfigurationBuilder() 39 | .SetBasePath(Directory.GetCurrentDirectory()) 40 | .AddJsonFile("appsettings.json"); 41 | 42 | configuration = builder.Build(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/Connected Services/Application Insights/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", 3 | "Version": "8.9.809.2", 4 | "GettingStartedDocument": { 5 | "Uri": "https://go.microsoft.com/fwlink/?LinkID=798432" 6 | } 7 | } -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/Controllers/FoldersController.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using MichalBialecki.com.Data.Dto; 3 | using Microsoft.AspNet.OData; 4 | using Microsoft.AspNetCore.Mvc; 5 | 6 | namespace ServiceBusExamples.MessagesSender.NetCore.Web.Controllers 7 | { 8 | [Route("Folders")] 9 | public class FoldersController : ODataController 10 | { 11 | [HttpGet] 12 | [Produces("application/json")] 13 | [EnableQuery(AllowedQueryOptions = Microsoft.AspNet.OData.Query.AllowedQueryOptions.All)] 14 | public IQueryable Get() 15 | { 16 | var folder = new FoldersAndFilesProvider().GetTreeStructure(100, 4); 17 | 18 | return folder.Folders.AsQueryable(); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/Controllers/MessagesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Azure.ServiceBus; 7 | using Newtonsoft.Json; 8 | using ServiceBusExamples.MessagesSender.NetCore.Web.Dto; 9 | using ServiceBusExamples.MessagesSender.NetCore.Web.Services; 10 | 11 | namespace ServiceBusExamples.MessagesSender.NetCore.Web.Controllers 12 | { 13 | [Route("Messages")] 14 | public class MessagesController : Controller 15 | { 16 | private const string ServiceBusConnectionString = "Endpoint=sb://bialecki.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=39cH/mE4siF49REMd9xtjVlUwoc0yPJNz9J8isRc9vY="; 17 | 18 | private readonly TopicClient _topicClient; 19 | 20 | public MessagesController() 21 | { 22 | _topicClient = new TopicClient(ServiceBusConnectionString, "stockupdated"); 23 | } 24 | 25 | [Route("Send")] 26 | [HttpPost] 27 | public async Task Send([FromBody]SendMessageDto message) 28 | { 29 | try 30 | { 31 | var document = new DocumentDto 32 | { 33 | StockId = message.StockId, 34 | Name = message.Name, 35 | Price = message.Price, 36 | UpdatedAt = DateTime.UtcNow 37 | }; 38 | 39 | await _topicClient.SendAsync(new Message(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(document)))); 40 | 41 | return StatusCode(200); 42 | } 43 | catch (Exception e) 44 | { 45 | Console.WriteLine(e); 46 | return StatusCode(500, e.Message); 47 | } 48 | } 49 | 50 | [Route("Save")] 51 | [HttpPost] 52 | public async Task Save([FromBody]SendMessageDto message) 53 | { 54 | try 55 | { 56 | var document = new DocumentDto 57 | { 58 | StockId = message.StockId, 59 | Name = message.Name, 60 | Price = message.Price, 61 | UpdatedAt = DateTime.UtcNow 62 | }; 63 | 64 | await new DocumentDbService().SaveDocumentAsync(document); 65 | 66 | return StatusCode(200); 67 | } 68 | catch (Exception e) 69 | { 70 | Console.WriteLine(e); 71 | return StatusCode(500, e.Message); 72 | } 73 | } 74 | 75 | [Route("GetTenLatestUpdates")] 76 | [HttpGet] 77 | public IQueryable GetTenLatestUpdates() 78 | { 79 | try 80 | { 81 | var documents = new DocumentDbService().GetLatestDocuments(); 82 | 83 | return documents; 84 | } 85 | catch (Exception e) 86 | { 87 | Console.WriteLine(e); 88 | return null; 89 | } 90 | } 91 | 92 | [Route("SendProductRatingMessages")] 93 | [HttpPost] 94 | public async Task SendProductRatingMessages([FromQuery]int numberOfMessages) 95 | { 96 | try 97 | { 98 | var ratingUpdates = ProductRatingUpdatesGenerator.GetMessages(numberOfMessages); 99 | var messages = ratingUpdates 100 | .Select(m => new Message(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(m)))) 101 | .ToList(); 102 | 103 | await _topicClient.SendAsync(messages); 104 | 105 | return Ok(); 106 | } 107 | catch (Exception e) 108 | { 109 | Console.WriteLine(e); 110 | return StatusCode(500, e.Message); 111 | } 112 | } 113 | 114 | [Route("SendWithBuffering")] 115 | [HttpPost] 116 | public IActionResult SendWithBuffering() 117 | { 118 | try 119 | { 120 | /* 121 | var service = new SimpleBufferMessagesService(); 122 | await service.AddMessage("test message" + DateTime.Now); 123 | */ 124 | 125 | var service = new TimerBufferMessagesService(); 126 | service.AddMessage("test message" + DateTime.Now); 127 | 128 | return Ok(); 129 | } 130 | catch (Exception e) 131 | { 132 | Console.WriteLine(e); 133 | return StatusCode(500, e.Message); 134 | } 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/DocumentDbService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using Microsoft.Azure.Documents.Client; 5 | using ServiceBusExamples.MessagesSender.NetCore.Web.Dto; 6 | 7 | namespace ServiceBusExamples.MessagesSender.NetCore.Web 8 | { 9 | public class DocumentDbService 10 | { 11 | private const string DatabaseName = "Documents"; 12 | 13 | private const string CollectionName = "Messages"; 14 | 15 | public async Task SaveDocumentAsync(DocumentDto document) 16 | { 17 | try 18 | { 19 | var client = new DocumentClient(new Uri(ConfigurationHelper.GetCosmosDbEndpointUri()), ConfigurationHelper.GetCosmosDbPrimaryKey()); 20 | await client.UpsertDocumentAsync(UriFactory.CreateDocumentCollectionUri(DatabaseName, CollectionName), document); 21 | } 22 | catch (Exception e) 23 | { 24 | Console.WriteLine("Error: {0}, Message: {1}", e.Message, e.GetBaseException().Message); 25 | } 26 | } 27 | 28 | public IQueryable GetLatestDocuments() 29 | { 30 | try 31 | { 32 | var client = new DocumentClient(new Uri(ConfigurationHelper.GetCosmosDbEndpointUri()), ConfigurationHelper.GetCosmosDbPrimaryKey()); 33 | return client.CreateDocumentQuery( 34 | UriFactory.CreateDocumentCollectionUri(DatabaseName, CollectionName), 35 | "SELECT * FROM Messages ORDER BY Messages.UpdatedAt desc", 36 | new FeedOptions { MaxItemCount = 10 }); 37 | } 38 | catch (Exception e) 39 | { 40 | Console.WriteLine("Error: {0}, Message: {1}", e.Message, e.GetBaseException().Message); 41 | return null; 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/Dto/DocumentDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ServiceBusExamples.MessagesSender.NetCore.Web.Dto 4 | { 5 | public class DocumentDto 6 | { 7 | public string StockId { get; set; } 8 | 9 | public string Name { get; set; } 10 | 11 | public float Price { get; set; } 12 | 13 | public DateTime UpdatedAt { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/Dto/ProductRatingUpdateMessage.cs: -------------------------------------------------------------------------------- 1 | namespace ServiceBusExamples.MessagesSender.NetCore.Web.Dto 2 | { 3 | public class ProductRatingUpdateMessage 4 | { 5 | public int ProductId { get; set; } 6 | 7 | public int SellerId { get; set; } 8 | 9 | public int RatingSum { get; set; } 10 | 11 | public int RatingCount { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/ProductRatingUpdatesGenerator.cs: -------------------------------------------------------------------------------- 1 | using ServiceBusExamples.MessagesSender.NetCore.Web.Dto; 2 | using System; 3 | using System.Collections.Generic; 4 | 5 | namespace ServiceBusExamples.MessagesSender.NetCore.Web 6 | { 7 | public static class ProductRatingUpdatesGenerator 8 | { 9 | public static List GetMessages(int numberOfMessages) 10 | { 11 | var messages = new List(); 12 | var rand = new Random(); 13 | for (int i = 0; i < numberOfMessages; i++) 14 | { 15 | messages.Add(new ProductRatingUpdateMessage 16 | { 17 | ProductId = rand.Next(1, 50), 18 | SellerId = rand.Next(1, 5), 19 | RatingCount = 10, 20 | RatingSum = rand.Next(10, 50) 21 | }); 22 | } 23 | 24 | return messages; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace ServiceBusExamples.MessagesSender.NetCore.Web 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | BuildWebHost(args).Run(); 18 | } 19 | 20 | public static IWebHost BuildWebHost(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup() 23 | .Build(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/Properties/PublishProfiles/ServiceBusExamplesMessagesSenderWeb20171221111633 - Web Deploy.pubxml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | MSDeploy 9 | /subscriptions/9179e872-53da-40e1-a26e-90ef82ddf188/resourcegroups/home/providers/Microsoft.Web/sites/ServiceBusExamplesMessagesSenderWeb20171221111633 10 | home 11 | AzureWebSite 12 | Release 13 | Any CPU 14 | http://servicebusexamplesmessagessenderweb20171221111633.azurewebsites.net 15 | True 16 | False 17 | 3e724019-35c7-45f9-8df2-b79917c274f2 18 | servicebusexamplesmessagessenderweb20171221111633.scm.azurewebsites.net:443 19 | ServiceBusExamplesMessagesSenderWeb20171221111633 20 | 21 | True 22 | WMSVC 23 | True 24 | $ServiceBusExamplesMessagesSenderWeb20171221111633 25 | <_SavePWD>True 26 | <_DestinationType>AzureWebSite 27 | 28 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:52027/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "api/values", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "ServiceBusExamples.MessagesSender.Web": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "launchUrl": "api/values", 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | }, 26 | "applicationUrl": "http://localhost:52028/" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/SendMessageDto.cs: -------------------------------------------------------------------------------- 1 | namespace ServiceBusExamples.MessagesSender.NetCore.Web 2 | { 3 | public class SendMessageDto 4 | { 5 | public string StockId { get; set; } 6 | 7 | public string Name { get; set; } 8 | 9 | public float Price { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/ServiceBusExamples.MessagesSender.NetCore.Web.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | PreserveNewest 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/Services/SimpleBufferMessagesService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | using Microsoft.Azure.ServiceBus; 6 | 7 | namespace ServiceBusExamples.MessagesSender.NetCore.Web.Services 8 | { 9 | public class SimpleBufferMessagesService 10 | { 11 | private const string ServiceBusConnectionString = "Endpoint=sb://bialecki.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=39cH/mE4siF49REMd9xtjVlUwoc0yPJNz9J8isRc9vY="; 12 | 13 | private static readonly List _messages = new List(); 14 | 15 | private static DateTime _lastMessageSent = DateTime.Now; 16 | 17 | private readonly TopicClient _topicClient; 18 | 19 | public SimpleBufferMessagesService() 20 | { 21 | _topicClient = new TopicClient(ServiceBusConnectionString, "accountTransferUpdates"); 22 | } 23 | 24 | public async Task AddMessage(string message) 25 | { 26 | _messages.Add(new Message(Encoding.UTF8.GetBytes(message))); 27 | 28 | if (_messages.Count >= 10 29 | || DateTime.Now - _lastMessageSent > TimeSpan.FromSeconds(20)) 30 | { 31 | await SendMessages(_messages); 32 | _messages.Clear(); 33 | _lastMessageSent = DateTime.Now; 34 | } 35 | } 36 | 37 | private async Task SendMessages(List messages) 38 | { 39 | await _topicClient.SendAsync(messages); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/Services/TimerBufferMessagesService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | using Microsoft.Azure.ServiceBus; 6 | 7 | namespace ServiceBusExamples.MessagesSender.NetCore.Web.Services 8 | { 9 | public class TimerBufferMessagesService 10 | { 11 | private const string ServiceBusConnectionString = "Endpoint=sb://bialecki.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=39cH/mE4siF49REMd9xtjVlUwoc0yPJNz9J8isRc9vY="; 12 | 13 | private static readonly ICollection _messages = new List(); 14 | 15 | private readonly TopicClient _topicClient; 16 | 17 | public TimerBufferMessagesService() 18 | { 19 | _topicClient = new TopicClient(ServiceBusConnectionString, "accountTransferUpdates"); 20 | } 21 | 22 | public void AddMessage(string message) 23 | { 24 | lock (((ICollection) _messages).SyncRoot) 25 | { 26 | _messages.Add(new Message(Encoding.UTF8.GetBytes(message))); 27 | } 28 | } 29 | 30 | public void SendMessages() 31 | { 32 | if (_messages.Count == 0) 33 | { 34 | return; 35 | } 36 | 37 | List localMessages; 38 | lock (((ICollection)_messages).SyncRoot) 39 | { 40 | localMessages = new List(_messages); 41 | _messages.Clear(); 42 | } 43 | 44 | Task.Run(async () => { await _topicClient.SendAsync(localMessages); }); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using MichalBialecki.com.Data.Dto; 4 | using Microsoft.AspNet.OData.Builder; 5 | using Microsoft.AspNet.OData.Extensions; 6 | using Microsoft.AspNetCore.Builder; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.DependencyInjection; 10 | using Microsoft.OData.Edm; 11 | using ServiceBusExamples.MessagesSender.NetCore.Web.Services; 12 | using Swashbuckle.AspNetCore.Swagger; 13 | 14 | namespace ServiceBusExamples.MessagesSender.NetCore.Web 15 | { 16 | public class Startup 17 | { 18 | public Startup(IConfiguration configuration) 19 | { 20 | Configuration = configuration; 21 | } 22 | 23 | public IConfiguration Configuration { get; } 24 | 25 | // This method gets called by the runtime. Use this method to add services to the container. 26 | public void ConfigureServices(IServiceCollection services) 27 | { 28 | services.AddMvc(); 29 | services.AddOData(); 30 | 31 | services.AddSwaggerGen(c => 32 | { 33 | c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" }); 34 | }); 35 | } 36 | 37 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 38 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 39 | { 40 | app.UseSwagger(); 41 | 42 | app.UseSwaggerUI(c => 43 | { 44 | c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); 45 | }); 46 | 47 | if (env.IsDevelopment()) 48 | { 49 | app.UseDeveloperExceptionPage(); 50 | } 51 | 52 | IEdmModel model = GetEdmModel(app.ApplicationServices); 53 | 54 | app.UseMvc(routes => 55 | { 56 | routes.Count().Filter().OrderBy().Expand().Select().MaxTop(null); 57 | routes.EnableDependencyInjection(); 58 | routes.MapRoute("default", "api/{controller=Folders}/{action=Get}"); 59 | routes.MapODataServiceRoute("odata", "odata", model); 60 | }); 61 | 62 | const int timeoutInMiliseconds = 20000; 63 | var allTasksWaitHandle = new AutoResetEvent(true); 64 | 65 | ThreadPool.RegisterWaitForSingleObject( 66 | allTasksWaitHandle, 67 | (s, b) => 68 | { 69 | ServiceBusTimerCallback(); 70 | }, 71 | null, 72 | timeoutInMiliseconds, 73 | false); 74 | } 75 | 76 | private static void ServiceBusTimerCallback() 77 | { 78 | var bufferService = new TimerBufferMessagesService(); 79 | bufferService.SendMessages(); 80 | } 81 | 82 | private static IEdmModel GetEdmModel(IServiceProvider serviceProvider) 83 | { 84 | var builder = new ODataConventionModelBuilder(serviceProvider); 85 | builder 86 | .EntitySet("Folders") 87 | .EntityType.HasKey(s => s.Id) 88 | .Filter(Microsoft.AspNet.OData.Query.QueryOptionSetting.Allowed); 89 | 90 | return builder.GetEdmModel(); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ServiceBusExamples/ServiceBusExamples.MessagesSender.Web/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ServiceBusConnectionString": "Endpoint=sb://bialecki.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=39cH/mE4siF49REMd9xtjVlUwoc0yPJNz9J8isRc9vY=", 3 | "CosmosDBPrimaryKey": "6hP3HMQeuH2n1oN0cby3W7rt9uZexEGgj7TNHwLnFgQh7qKqTvmEUQPsgahpBHgXPS9W0jTLRjS4G3l2HEPsPQ==", 4 | "CosmosDbEndpointUri": "https://bialecki.documents.azure.com:443/" 5 | } --------------------------------------------------------------------------------