├── .gitignore ├── LICENSE ├── LICENSE-CODE ├── README.md ├── SECURITY.md ├── deployment └── azuredeploy.json └── src ├── after ├── DroneDelivery-after │ ├── Connected Services │ │ └── Application Insights │ │ │ └── ConnectedService.json │ ├── Controllers │ │ ├── DeliveriesController.cs │ │ ├── DeliveryRequestsController.cs │ │ └── HomeController.cs │ ├── DroneDelivery-after.csproj │ ├── Program.cs │ ├── Services │ │ └── PackageServiceCaller.cs │ ├── Startup.cs │ ├── Views │ │ └── Home │ │ │ ├── Index.cshtml │ │ │ └── SendRequests.cshtml │ ├── appsettings.Development.json │ └── appsettings.json ├── DroneDelivery.Common │ ├── DroneDelivery.Common.csproj │ ├── Models │ │ ├── ConfirmationRequired.cs │ │ ├── ConfirmationType.cs │ │ ├── ContainerSize.cs │ │ ├── Delivery.cs │ │ ├── DeliveryStage.cs │ │ ├── DeliveryStatus.cs │ │ ├── Location.cs │ │ ├── PackageGen.cs │ │ ├── PackageInfo.cs │ │ └── UserAccount.cs │ └── Services │ │ ├── DeliveryRepository.cs │ │ ├── DroneScheduler.cs │ │ ├── IDeliveryRepository.cs │ │ ├── IDroneScheduler.cs │ │ ├── IPackageProcessor.cs │ │ ├── IRequestProcessor.cs │ │ ├── RequestProcessor.cs │ │ └── Utility.cs ├── DroneDelivery.sln └── PackageService │ ├── .gitignore │ ├── PackageService.csproj │ ├── PackageServiceFunction.cs │ └── host.json └── before ├── DroneDelivery-before ├── Connected Services │ └── Application Insights │ │ └── ConnectedService.json ├── Controllers │ ├── DeliveriesController.cs │ ├── DeliveryRequestsController.cs │ └── HomeController.cs ├── DroneDelivery-before.csproj ├── Program.cs ├── Services │ └── PackageProcessor.cs ├── Startup.cs ├── Views │ └── Home │ │ ├── Index.cshtml │ │ └── SendRequests.cshtml ├── appsettings.Development.json └── appsettings.json ├── DroneDelivery.Common ├── DroneDelivery.Common.csproj ├── Models │ ├── ConfirmationRequired.cs │ ├── ConfirmationType.cs │ ├── ContainerSize.cs │ ├── Delivery.cs │ ├── DeliveryStage.cs │ ├── DeliveryStatus.cs │ ├── Location.cs │ ├── PackageGen.cs │ ├── PackageInfo.cs │ └── UserAccount.cs └── Services │ ├── DeliveryRepository.cs │ ├── DroneScheduler.cs │ ├── IDeliveryRepository.cs │ ├── IDroneScheduler.cs │ ├── IPackageProcessor.cs │ ├── IRequestProcessor.cs │ ├── RequestProcessor.cs │ └── Utility.cs └── DroneDelivery.sln /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | *.rptproj.bak 244 | 245 | # SQL Server files 246 | *.mdf 247 | *.ldf 248 | *.ndf 249 | 250 | # Business Intelligence projects 251 | *.rdl.data 252 | *.bim.layout 253 | *.bim_*.settings 254 | *.rptproj.rsuser 255 | 256 | # Microsoft Fakes 257 | FakesAssemblies/ 258 | 259 | # GhostDoc plugin setting file 260 | *.GhostDoc.xml 261 | 262 | # Node.js Tools for Visual Studio 263 | .ntvs_analysis.dat 264 | node_modules/ 265 | 266 | # Visual Studio 6 build log 267 | *.plg 268 | 269 | # Visual Studio 6 workspace options file 270 | *.opt 271 | 272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 273 | *.vbw 274 | 275 | # Visual Studio LightSwitch build output 276 | **/*.HTMLClient/GeneratedArtifacts 277 | **/*.DesktopClient/GeneratedArtifacts 278 | **/*.DesktopClient/ModelManifest.xml 279 | **/*.Server/GeneratedArtifacts 280 | **/*.Server/ModelManifest.xml 281 | _Pvt_Extensions 282 | 283 | # Paket dependency manager 284 | .paket/paket.exe 285 | paket-files/ 286 | 287 | # FAKE - F# Make 288 | .fake/ 289 | 290 | # JetBrains Rider 291 | .idea/ 292 | *.sln.iml 293 | 294 | # CodeRush 295 | .cr/ 296 | 297 | # Python Tools for Visual Studio (PTVS) 298 | __pycache__/ 299 | *.pyc 300 | 301 | # Cake - Uncomment if you are using it 302 | # tools/** 303 | # !tools/packages.config 304 | 305 | # Tabs Studio 306 | *.tss 307 | 308 | # Telerik's JustMock configuration file 309 | *.jmconfig 310 | 311 | # BizTalk build output 312 | *.btp.cs 313 | *.btm.cs 314 | *.odx.cs 315 | *.xsd.cs 316 | 317 | # OpenCover UI analysis results 318 | OpenCover/ 319 | 320 | # Azure Stream Analytics local run output 321 | ASALocalRun/ 322 | 323 | # MSBuild Binary and Structured Log 324 | *.binlog 325 | 326 | # NVidia Nsight GPU debugger configuration file 327 | *.nvuser 328 | 329 | # MFractors (Xamarin productivity tool) working folder 330 | .mfractor/ 331 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Attribution 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More_considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution 4.0 International Public License 58 | 59 | By exercising the Licensed Rights (defined below), You accept and agree 60 | to be bound by the terms and conditions of this Creative Commons 61 | Attribution 4.0 International Public License ("Public License"). To the 62 | extent this Public License may be interpreted as a contract, You are 63 | granted the Licensed Rights in consideration of Your acceptance of 64 | these terms and conditions, and the Licensor grants You such rights in 65 | consideration of benefits the Licensor receives from making the 66 | Licensed Material available under these terms and conditions. 67 | 68 | 69 | Section 1 -- Definitions. 70 | 71 | a. Adapted Material means material subject to Copyright and Similar 72 | Rights that is derived from or based upon the Licensed Material 73 | and in which the Licensed Material is translated, altered, 74 | arranged, transformed, or otherwise modified in a manner requiring 75 | permission under the Copyright and Similar Rights held by the 76 | Licensor. For purposes of this Public License, where the Licensed 77 | Material is a musical work, performance, or sound recording, 78 | Adapted Material is always produced where the Licensed Material is 79 | synched in timed relation with a moving image. 80 | 81 | b. Adapter's License means the license You apply to Your Copyright 82 | and Similar Rights in Your contributions to Adapted Material in 83 | accordance with the terms and conditions of this Public License. 84 | 85 | c. Copyright and Similar Rights means copyright and/or similar rights 86 | closely related to copyright including, without limitation, 87 | performance, broadcast, sound recording, and Sui Generis Database 88 | Rights, without regard to how the rights are labeled or 89 | categorized. For purposes of this Public License, the rights 90 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 91 | Rights. 92 | 93 | d. Effective Technological Measures means those measures that, in the 94 | absence of proper authority, may not be circumvented under laws 95 | fulfilling obligations under Article 11 of the WIPO Copyright 96 | Treaty adopted on December 20, 1996, and/or similar international 97 | agreements. 98 | 99 | e. Exceptions and Limitations means fair use, fair dealing, and/or 100 | any other exception or limitation to Copyright and Similar Rights 101 | that applies to Your use of the Licensed Material. 102 | 103 | f. Licensed Material means the artistic or literary work, database, 104 | or other material to which the Licensor applied this Public 105 | License. 106 | 107 | g. Licensed Rights means the rights granted to You subject to the 108 | terms and conditions of this Public License, which are limited to 109 | all Copyright and Similar Rights that apply to Your use of the 110 | Licensed Material and that the Licensor has authority to license. 111 | 112 | h. Licensor means the individual(s) or entity(ies) granting rights 113 | under this Public License. 114 | 115 | i. Share means to provide material to the public by any means or 116 | process that requires permission under the Licensed Rights, such 117 | as reproduction, public display, public performance, distribution, 118 | dissemination, communication, or importation, and to make material 119 | available to the public including in ways that members of the 120 | public may access the material from a place and at a time 121 | individually chosen by them. 122 | 123 | j. Sui Generis Database Rights means rights other than copyright 124 | resulting from Directive 96/9/EC of the European Parliament and of 125 | the Council of 11 March 1996 on the legal protection of databases, 126 | as amended and/or succeeded, as well as other essentially 127 | equivalent rights anywhere in the world. 128 | 129 | k. You means the individual or entity exercising the Licensed Rights 130 | under this Public License. Your has a corresponding meaning. 131 | 132 | 133 | Section 2 -- Scope. 134 | 135 | a. License grant. 136 | 137 | 1. Subject to the terms and conditions of this Public License, 138 | the Licensor hereby grants You a worldwide, royalty-free, 139 | non-sublicensable, non-exclusive, irrevocable license to 140 | exercise the Licensed Rights in the Licensed Material to: 141 | 142 | a. reproduce and Share the Licensed Material, in whole or 143 | in part; and 144 | 145 | b. produce, reproduce, and Share Adapted Material. 146 | 147 | 2. Exceptions and Limitations. For the avoidance of doubt, where 148 | Exceptions and Limitations apply to Your use, this Public 149 | License does not apply, and You do not need to comply with 150 | its terms and conditions. 151 | 152 | 3. Term. The term of this Public License is specified in Section 153 | 6(a). 154 | 155 | 4. Media and formats; technical modifications allowed. The 156 | Licensor authorizes You to exercise the Licensed Rights in 157 | all media and formats whether now known or hereafter created, 158 | and to make technical modifications necessary to do so. The 159 | Licensor waives and/or agrees not to assert any right or 160 | authority to forbid You from making technical modifications 161 | necessary to exercise the Licensed Rights, including 162 | technical modifications necessary to circumvent Effective 163 | Technological Measures. For purposes of this Public License, 164 | simply making modifications authorized by this Section 2(a) 165 | (4) never produces Adapted Material. 166 | 167 | 5. Downstream recipients. 168 | 169 | a. Offer from the Licensor -- Licensed Material. Every 170 | recipient of the Licensed Material automatically 171 | receives an offer from the Licensor to exercise the 172 | Licensed Rights under the terms and conditions of this 173 | Public License. 174 | 175 | b. No downstream restrictions. You may not offer or impose 176 | any additional or different terms or conditions on, or 177 | apply any Effective Technological Measures to, the 178 | Licensed Material if doing so restricts exercise of the 179 | Licensed Rights by any recipient of the Licensed 180 | Material. 181 | 182 | 6. No endorsement. Nothing in this Public License constitutes or 183 | may be construed as permission to assert or imply that You 184 | are, or that Your use of the Licensed Material is, connected 185 | with, or sponsored, endorsed, or granted official status by, 186 | the Licensor or others designated to receive attribution as 187 | provided in Section 3(a)(1)(A)(i). 188 | 189 | b. Other rights. 190 | 191 | 1. Moral rights, such as the right of integrity, are not 192 | licensed under this Public License, nor are publicity, 193 | privacy, and/or other similar personality rights; however, to 194 | the extent possible, the Licensor waives and/or agrees not to 195 | assert any such rights held by the Licensor to the limited 196 | extent necessary to allow You to exercise the Licensed 197 | Rights, but not otherwise. 198 | 199 | 2. Patent and trademark rights are not licensed under this 200 | Public License. 201 | 202 | 3. To the extent possible, the Licensor waives any right to 203 | collect royalties from You for the exercise of the Licensed 204 | Rights, whether directly or through a collecting society 205 | under any voluntary or waivable statutory or compulsory 206 | licensing scheme. In all other cases the Licensor expressly 207 | reserves any right to collect such royalties. 208 | 209 | 210 | Section 3 -- License Conditions. 211 | 212 | Your exercise of the Licensed Rights is expressly made subject to the 213 | following conditions. 214 | 215 | a. Attribution. 216 | 217 | 1. If You Share the Licensed Material (including in modified 218 | form), You must: 219 | 220 | a. retain the following if it is supplied by the Licensor 221 | with the Licensed Material: 222 | 223 | i. identification of the creator(s) of the Licensed 224 | Material and any others designated to receive 225 | attribution, in any reasonable manner requested by 226 | the Licensor (including by pseudonym if 227 | designated); 228 | 229 | ii. a copyright notice; 230 | 231 | iii. a notice that refers to this Public License; 232 | 233 | iv. a notice that refers to the disclaimer of 234 | warranties; 235 | 236 | v. a URI or hyperlink to the Licensed Material to the 237 | extent reasonably practicable; 238 | 239 | b. indicate if You modified the Licensed Material and 240 | retain an indication of any previous modifications; and 241 | 242 | c. indicate the Licensed Material is licensed under this 243 | Public License, and include the text of, or the URI or 244 | hyperlink to, this Public License. 245 | 246 | 2. You may satisfy the conditions in Section 3(a)(1) in any 247 | reasonable manner based on the medium, means, and context in 248 | which You Share the Licensed Material. For example, it may be 249 | reasonable to satisfy the conditions by providing a URI or 250 | hyperlink to a resource that includes the required 251 | information. 252 | 253 | 3. If requested by the Licensor, You must remove any of the 254 | information required by Section 3(a)(1)(A) to the extent 255 | reasonably practicable. 256 | 257 | 4. If You Share Adapted Material You produce, the Adapter's 258 | License You apply must not prevent recipients of the Adapted 259 | Material from complying with this Public License. 260 | 261 | 262 | Section 4 -- Sui Generis Database Rights. 263 | 264 | Where the Licensed Rights include Sui Generis Database Rights that 265 | apply to Your use of the Licensed Material: 266 | 267 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 268 | to extract, reuse, reproduce, and Share all or a substantial 269 | portion of the contents of the database; 270 | 271 | b. if You include all or a substantial portion of the database 272 | contents in a database in which You have Sui Generis Database 273 | Rights, then the database in which You have Sui Generis Database 274 | Rights (but not its individual contents) is Adapted Material; and 275 | 276 | c. You must comply with the conditions in Section 3(a) if You Share 277 | all or a substantial portion of the contents of the database. 278 | 279 | For the avoidance of doubt, this Section 4 supplements and does not 280 | replace Your obligations under this Public License where the Licensed 281 | Rights include other Copyright and Similar Rights. 282 | 283 | 284 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 285 | 286 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 287 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 288 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 289 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 290 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 291 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 292 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 293 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 294 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 295 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 296 | 297 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 298 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 299 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 300 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 301 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 302 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 303 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 304 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 305 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 306 | 307 | c. The disclaimer of warranties and limitation of liability provided 308 | above shall be interpreted in a manner that, to the extent 309 | possible, most closely approximates an absolute disclaimer and 310 | waiver of all liability. 311 | 312 | 313 | Section 6 -- Term and Termination. 314 | 315 | a. This Public License applies for the term of the Copyright and 316 | Similar Rights licensed here. However, if You fail to comply with 317 | this Public License, then Your rights under this Public License 318 | terminate automatically. 319 | 320 | b. Where Your right to use the Licensed Material has terminated under 321 | Section 6(a), it reinstates: 322 | 323 | 1. automatically as of the date the violation is cured, provided 324 | it is cured within 30 days of Your discovery of the 325 | violation; or 326 | 327 | 2. upon express reinstatement by the Licensor. 328 | 329 | For the avoidance of doubt, this Section 6(b) does not affect any 330 | right the Licensor may have to seek remedies for Your violations 331 | of this Public License. 332 | 333 | c. For the avoidance of doubt, the Licensor may also offer the 334 | Licensed Material under separate terms or conditions or stop 335 | distributing the Licensed Material at any time; however, doing so 336 | will not terminate this Public License. 337 | 338 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 339 | License. 340 | 341 | 342 | Section 7 -- Other Terms and Conditions. 343 | 344 | a. The Licensor shall not be bound by any additional or different 345 | terms or conditions communicated by You unless expressly agreed. 346 | 347 | b. Any arrangements, understandings, or agreements regarding the 348 | Licensed Material not stated herein are separate from and 349 | independent of the terms and conditions of this Public License. 350 | 351 | 352 | Section 8 -- Interpretation. 353 | 354 | a. For the avoidance of doubt, this Public License does not, and 355 | shall not be interpreted to, reduce, limit, restrict, or impose 356 | conditions on any use of the Licensed Material that could lawfully 357 | be made without permission under this Public License. 358 | 359 | b. To the extent possible, if any provision of this Public License is 360 | deemed unenforceable, it shall be automatically reformed to the 361 | minimum extent necessary to make it enforceable. If the provision 362 | cannot be reformed, it shall be severed from this Public License 363 | without affecting the enforceability of the remaining terms and 364 | conditions. 365 | 366 | c. No term or condition of this Public License will be waived and no 367 | failure to comply consented to unless expressly agreed to by the 368 | Licensor. 369 | 370 | d. Nothing in this Public License constitutes or may be interpreted 371 | as a limitation upon, or waiver of, any privileges and immunities 372 | that apply to the Licensor or You, including from the legal 373 | processes of any jurisdiction or authority. 374 | 375 | 376 | ======================================================================= 377 | 378 | Creative Commons is not a party to its public 379 | licenses. Notwithstanding, Creative Commons may elect to apply one of 380 | its public licenses to material it publishes and in those instances 381 | will be considered the “Licensor.” The text of the Creative Commons 382 | public licenses is dedicated to the public domain under the CC0 Public 383 | Domain Dedication. Except for the limited purpose of indicating that 384 | material is shared under a Creative Commons public license or as 385 | otherwise permitted by the Creative Commons policies published at 386 | creativecommons.org/policies, Creative Commons does not authorize the 387 | use of the trademark "Creative Commons" or any other trademark or logo 388 | of Creative Commons without its prior written consent including, 389 | without limitation, in connection with any unauthorized modifications 390 | to any of its public licenses or any other arrangements, 391 | understandings, or agreements concerning use of licensed material. For 392 | the avoidance of doubt, this paragraph does not form part of the 393 | public licenses. 394 | 395 | Creative Commons may be contacted at creativecommons.org. -------------------------------------------------------------------------------- /LICENSE-CODE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) Microsoft Corporation 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 5 | associated documentation files (the "Software"), to deal in the Software without restriction, 6 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all copies or substantial 11 | portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 14 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 15 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 16 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributing 3 | 4 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 5 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 6 | the rights to use your contribution. For details, visit https://cla.microsoft.com. 7 | 8 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide 9 | a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions 10 | provided by the bot. You will only need to do this once across all repos using our CLA. 11 | 12 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 13 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 14 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 15 | 16 | # Legal Notices 17 | 18 | Microsoft and any contributors grant you a license to the Microsoft documentation and other content 19 | in this repository under the [Creative Commons Attribution 4.0 International Public License](https://creativecommons.org/licenses/by/4.0/legalcode), 20 | see the [LICENSE](LICENSE) file, and grant you a license to any code in the repository under the [MIT License](https://opensource.org/licenses/MIT), see the 21 | [LICENSE-CODE](LICENSE-CODE) file. 22 | 23 | Microsoft, Windows, Microsoft Azure and/or other Microsoft products and services referenced in the documentation 24 | may be either trademarks or registered trademarks of Microsoft in the United States and/or other countries. 25 | The licenses for this project do not grant you rights to use any Microsoft names, logos, or trademarks. 26 | Microsoft's general trademark guidelines can be found at http://go.microsoft.com/fwlink/?LinkID=254653. 27 | 28 | Privacy information can be found at https://privacy.microsoft.com/en-us/ 29 | 30 | Microsoft and any contributors reserve all other rights, whether under their respective copyrights, patents, 31 | or trademarks, whether by implication, estoppel or otherwise. 32 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /deployment/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "applicationInsightsName": { 6 | "defaultValue": "[concat('AI-MicroservicesLearnModule-', substring(uniqueString(resourceGroup().id),0,6))]", 7 | "type": "String" 8 | }, 9 | "websiteName": { 10 | "defaultValue": "[concat('microserviceslearnmodule-', substring(uniqueString(resourceGroup().id),0,3))]", 11 | "type": "string" 12 | }, 13 | "location": { 14 | "defaultValue": "centralus", 15 | "type": "string" 16 | }, 17 | "hostingPlanName": { 18 | "defaultValue": "[concat('microserviceslearnmodule-ASP-', substring(uniqueString(resourceGroup().id),0,3))]", 19 | "type": "string" 20 | }, 21 | "alwaysOn": { 22 | "defaultValue": false, 23 | "type": "bool" 24 | }, 25 | "sku": { 26 | "defaultValue": "Free", 27 | "type": "string" 28 | }, 29 | "skuCode": { 30 | "defaultValue": "F1", 31 | "type": "string" 32 | }, 33 | "workerSize": { 34 | "defaultValue": "0", 35 | "type": "string" 36 | }, 37 | "workerSizeId": { 38 | "defaultValue": "0", 39 | "type": "string" 40 | }, 41 | "numberOfWorkers": { 42 | "defaultValue": "1", 43 | "type": "string" 44 | }, 45 | "currentStack": { 46 | "defaultValue": "dotnetcore", 47 | "type": "string" 48 | }, 49 | "functionName":{ 50 | "defaultValue": "[concat('packageservicefunction-', substring(uniqueString(resourceGroup().id),0,3))]", 51 | "type": "string" 52 | }, 53 | "storageName":{ 54 | "defaultValue": "[concat('packagesvcfunc', substring(uniqueString(resourceGroup().id),0,3))]", 55 | "type": "string" 56 | } 57 | }, 58 | 59 | "resources": [ 60 | { 61 | "apiVersion": "2018-02-01", 62 | "name": "[parameters('websiteName')]", 63 | "type": "Microsoft.Web/sites", 64 | "location": "[parameters('location')]", 65 | "tags": null, 66 | "dependsOn": [ 67 | "[concat('microsoft.insights/components/', parameters('applicationInsightsName'))]", 68 | "[concat('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]" 69 | ], 70 | "properties": { 71 | "name": "[parameters('websiteName')]", 72 | "siteConfig": { 73 | "appSettings": [ 74 | { 75 | "name": "APPINSIGHTS_INSTRUMENTATIONKEY", 76 | "value": "[reference(concat('microsoft.insights/components/', parameters('applicationInsightsName')), '2015-05-01').InstrumentationKey]" 77 | }, 78 | { 79 | "name": "ApplicationInsightsAgent_EXTENSION_VERSION", 80 | "value": "~2" 81 | }, 82 | { 83 | "name": "XDT_MicrosoftApplicationInsights_Mode", 84 | "value": "default" 85 | }, 86 | { 87 | "name": "DiagnosticServices_EXTENSION_VERSION", 88 | "value": "disabled" 89 | }, 90 | { 91 | "name": "APPINSIGHTS_PROFILERFEATURE_VERSION", 92 | "value": "disabled" 93 | }, 94 | { 95 | "name": "APPINSIGHTS_SNAPSHOTFEATURE_VERSION", 96 | "value": "disabled" 97 | }, 98 | { 99 | "name": "InstrumentationEngine_EXTENSION_VERSION", 100 | "value": "disabled" 101 | }, 102 | { 103 | "name": "SnapshotDebugger_EXTENSION_VERSION", 104 | "value": "disabled" 105 | }, 106 | { 107 | "name": "XDT_MicrosoftApplicationInsights_BaseExtensions", 108 | "value": "disabled" 109 | }, 110 | { 111 | "name": "PackageServiceUri", 112 | "value": "[concat('https://', parameters('functionName'), '.azurewebsites.net/api/packages/')]" 113 | }, 114 | { 115 | "name": "PackageServiceFunctionCode", 116 | "value": "Please put the code from accessing the PackageService Function here" 117 | } 118 | ], 119 | "metadata": [ 120 | { 121 | "name": "CURRENT_STACK", 122 | "value": "[parameters('currentStack')]" 123 | } 124 | ], 125 | "alwaysOn": "[parameters('alwaysOn')]" 126 | }, 127 | "serverFarmId": "[concat(resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]", 128 | "clientAffinityEnabled": true 129 | } 130 | }, 131 | { 132 | "apiVersion": "2018-02-01", 133 | "name": "[parameters('hostingPlanName')]", 134 | "type": "Microsoft.Web/serverfarms", 135 | "location": "[parameters('location')]", 136 | "kind": "", 137 | "tags": null, 138 | "properties": { 139 | "name": "[parameters('hostingPlanName')]", 140 | "workerSize": "[parameters('workerSize')]", 141 | "workerSizeId": "[parameters('workerSizeId')]", 142 | "numberOfWorkers": "[parameters('numberOfWorkers')]" 143 | }, 144 | "sku": { 145 | "Tier": "[parameters('sku')]", 146 | "Name": "[parameters('skuCode')]" 147 | } 148 | }, 149 | { 150 | "apiVersion": "2015-05-01", 151 | "name": "[parameters('applicationInsightsName')]", 152 | "type": "microsoft.insights/components", 153 | "location": "[parameters('location')]", 154 | "kind": "web", 155 | "properties": { 156 | "Application_Type": "web", 157 | "Request_Source": "IbizaWebAppExtensionCreate" 158 | } 159 | }, 160 | { 161 | "name": "[parameters('functionName')]", 162 | "type": "Microsoft.Web/sites", 163 | "properties": { 164 | "siteConfig": { 165 | "appSettings": [ 166 | { 167 | "name": "FUNCTIONS_WORKER_RUNTIME", 168 | "value": "dotnet" 169 | }, 170 | { 171 | "name": "AzureWebJobsStorage", 172 | "value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2015-05-01-preview').key1)]" 173 | }, 174 | { 175 | "name": "FUNCTIONS_EXTENSION_VERSION", 176 | "value": "~2" 177 | }, 178 | { 179 | "name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING", 180 | "value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2015-05-01-preview').key1)]" 181 | }, 182 | { 183 | "name": "WEBSITE_CONTENTSHARE", 184 | "value": "[concat(toLower(parameters('functionName')), substring(uniqueString(resourceGroup().id),0,3))]" 185 | }, 186 | { 187 | "name": "WEBSITE_NODE_DEFAULT_VERSION", 188 | "value": "10.14.1" 189 | }, 190 | { 191 | "name": "APPINSIGHTS_INSTRUMENTATIONKEY", 192 | "value": "[reference(concat('microsoft.insights/components/', parameters('applicationInsightsName')), '2015-05-01').InstrumentationKey]" 193 | } 194 | ] 195 | }, 196 | "name": "[parameters('functionName')]", 197 | "clientAffinityEnabled": false, 198 | "reserved": false 199 | }, 200 | "apiVersion": "2016-03-01", 201 | "dependsOn": [ 202 | "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageName'))]" 203 | ], 204 | "location": "[parameters('location')]", 205 | "kind": "functionapp" 206 | }, 207 | { 208 | "apiVersion": "2015-05-01-preview", 209 | "type": "Microsoft.Storage/storageAccounts", 210 | "name": "[parameters('storageName')]", 211 | "location": "[parameters('location')]", 212 | "properties": { 213 | "accountType": "Standard_LRS" 214 | } 215 | } 216 | ] 217 | } 218 | -------------------------------------------------------------------------------- /src/after/DroneDelivery-after/Connected Services/Application Insights/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", 3 | "Version": "8.14.20131.1", 4 | "GettingStartedDocument": { 5 | "Uri": "https://go.microsoft.com/fwlink/?LinkID=798432" 6 | } 7 | } -------------------------------------------------------------------------------- /src/after/DroneDelivery-after/Controllers/DeliveriesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.Extensions.Logging; 5 | using DroneDelivery.Common.Models; 6 | using DroneDelivery.Common.Services; 7 | 8 | namespace DroneDelivery_after.Controllers 9 | { 10 | [Route("api/[controller]")] 11 | [ApiController] 12 | public class DeliveriesController : ControllerBase 13 | { 14 | private readonly IDeliveryRepository deliveryRepository; 15 | private readonly ILogger logger; 16 | 17 | public DeliveriesController(IDeliveryRepository deliveryRepository, 18 | ILogger logger) 19 | { 20 | this.deliveryRepository = deliveryRepository; 21 | this.logger = logger; 22 | } 23 | 24 | // GET api/deliveries/5 25 | [Route("/api/[controller]/{id}", Name = "GetDelivery")] 26 | [HttpGet] 27 | [ProducesResponseType(typeof(Delivery), 200)] 28 | public async Task Get(string id) 29 | { 30 | logger.LogInformation("In Get action with id: {Id}", id); 31 | 32 | var delivery = await deliveryRepository.GetAsync(id); 33 | 34 | if (delivery == null) 35 | { 36 | logger.LogDebug("Delivery id: {Id} not found", id); 37 | return NotFound(); 38 | } 39 | 40 | return Ok(delivery); 41 | } 42 | 43 | 44 | // GET api/deliveries/5/status 45 | [Route("/api/[controller]/{id}/status")] 46 | [HttpGet] 47 | [ProducesResponseType(typeof(DeliveryStatus), 200)] 48 | public async Task GetStatus(string id) 49 | { 50 | logger.LogInformation("In GetStatus action with id: {Id}", id); 51 | 52 | var delivery = await deliveryRepository.GetAsync(id); 53 | if (delivery == null) 54 | { 55 | logger.LogDebug("Delivery id: {Id} not found", id); 56 | return NotFound(); 57 | } 58 | 59 | var status = new DeliveryStatus(DeliveryStage.HeadedToDropoff, new Location(0, 0, 0), DateTime.Now.AddMinutes(10).ToString(), DateTime.Now.AddHours(1).ToString()); 60 | return Ok(status); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/after/DroneDelivery-after/Controllers/DeliveryRequestsController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.Extensions.Logging; 4 | using DroneDelivery.Common.Models; 5 | using DroneDelivery.Common.Services; 6 | 7 | namespace DroneDelivery_after.Controllers 8 | { 9 | [Route("api/[controller]")] 10 | [ApiController] 11 | public class DeliveryRequestsController : ControllerBase 12 | { 13 | private readonly IRequestProcessor requestProcessor; 14 | private readonly ILogger logger; 15 | 16 | public DeliveryRequestsController(IRequestProcessor requestProcessor, 17 | ILogger logger) 18 | { 19 | this.requestProcessor = requestProcessor; 20 | this.logger = logger; 21 | } 22 | 23 | // POST api/deliveries 24 | [HttpPost()] 25 | [ProducesResponseType(typeof(Delivery), 201)] 26 | public async Task Post([FromBody]Delivery delivery) 27 | { 28 | logger.LogInformation("In Post action: {Delivery}", delivery); 29 | 30 | var success = await requestProcessor.ProcessDeliveryRequestAsync(delivery); 31 | 32 | return CreatedAtRoute("GetDelivery", new { id = delivery.DeliveryId }, delivery); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/after/DroneDelivery-after/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using System; 3 | using System.Diagnostics; 4 | using System.Net.Http; 5 | using System.Threading.Tasks; 6 | using DroneDelivery.Common.Models; 7 | using Newtonsoft.Json; 8 | 9 | namespace DroneDelivery_after.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | private const int RequestCount = 100; 14 | private readonly IHttpClientFactory httpClientFactory; 15 | private Delivery payload; 16 | 17 | public HomeController(IHttpClientFactory httpClientFactory) 18 | { 19 | this.httpClientFactory = httpClientFactory; 20 | 21 | this.payload = new Delivery() 22 | { 23 | DeliveryId = "delivery123", 24 | OwnerId = "owner123", 25 | PickupLocation = "pickup", 26 | DropoffLocation = "dropoff", 27 | PickupTime = DateTime.Now.AddDays(3), 28 | Deadline = "deadline", 29 | Expedited = true, 30 | ConfirmationRequired = ConfirmationRequired.None, 31 | PackageInfo = new PackageInfo() 32 | { 33 | PackageId = "package1234567", 34 | Size = ContainerSize.Small, 35 | Weight = 0, 36 | Tag = "tag" 37 | } 38 | }; 39 | } 40 | public IActionResult Index() 41 | { 42 | return View(); 43 | } 44 | 45 | [HttpPost()] 46 | [Route("/[controller]/SendRequests")] 47 | public IActionResult SendRequests() 48 | { 49 | var stopWatch = new Stopwatch(); 50 | stopWatch.Start(); 51 | 52 | var httpClient = httpClientFactory.CreateClient(); 53 | var urlBuilder = new UriBuilder(this.Request.Scheme, this.Request.Host.Host); 54 | httpClient.BaseAddress = urlBuilder.Uri; 55 | 56 | var tasks = new Task[RequestCount]; 57 | 58 | for (int i = 0; i < RequestCount; i++) 59 | { 60 | string jsonString = JsonConvert.SerializeObject(payload); 61 | 62 | var httpContent = new StringContent(jsonString, System.Text.Encoding.UTF8, "application/json"); 63 | 64 | tasks[i] = httpClient.PostAsync("/api/DeliveryRequests", httpContent); 65 | } 66 | 67 | Task.WaitAll(tasks); 68 | 69 | stopWatch.Stop(); 70 | ViewBag.Message = $"{RequestCount} messages sent in {stopWatch.Elapsed.Seconds} seconds"; 71 | return View(); 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /src/after/DroneDelivery-after/DroneDelivery-after.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/after/DroneDelivery-after/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Hosting; 3 | 4 | namespace DroneDelivery_after 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | CreateWebHostBuilder(args).Build().Run(); 11 | } 12 | 13 | public static IHostBuilder CreateWebHostBuilder(string[] args) => 14 | Host.CreateDefaultBuilder(args) 15 | .ConfigureWebHostDefaults(webBuilder => 16 | { 17 | webBuilder.UseStartup(); 18 | }); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/after/DroneDelivery-after/Services/PackageServiceCaller.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Http; 2 | using System.Threading.Tasks; 3 | using DroneDelivery.Common.Models; 4 | using DroneDelivery.Common.Services; 5 | using Newtonsoft.Json; 6 | 7 | namespace DroneDelivery_after.Services 8 | { 9 | public class PackageServiceCaller : IPackageProcessor 10 | { 11 | private readonly HttpClient httpClient; 12 | 13 | public static string FunctionCode { get; set; } 14 | 15 | public PackageServiceCaller(HttpClient httpClient) 16 | { 17 | this.httpClient = httpClient; 18 | } 19 | 20 | public async Task CreatePackageAsync(PackageInfo packageInfo) 21 | { 22 | string jsonString = JsonConvert.SerializeObject(packageInfo); 23 | 24 | var httpContent = new StringContent(jsonString, System.Text.Encoding.UTF8, "application/json"); 25 | 26 | var result = await httpClient.PostAsync($"{packageInfo.PackageId}?code={FunctionCode}", httpContent); 27 | result.EnsureSuccessStatusCode(); 28 | 29 | return new PackageGen { Id = packageInfo.PackageId }; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/after/DroneDelivery-after/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Swashbuckle.AspNetCore.Swagger; 6 | using DroneDelivery.Common.Services; 7 | using DroneDelivery_after.Services; 8 | using Microsoft.Extensions.Hosting; 9 | 10 | namespace DroneDelivery_after 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 | .AddHttpClient() 26 | .AddTransient() 27 | .AddTransient() 28 | .AddTransient() 29 | .AddTransient(); 30 | 31 | services 32 | .AddHttpClient(c => 33 | { 34 | c.BaseAddress = new System.Uri(Configuration["PackageServiceUri"]); 35 | }); 36 | 37 | PackageServiceCaller.FunctionCode = Configuration["PackageServiceFunctionCode"]; 38 | 39 | services.AddControllersWithViews(); 40 | 41 | // Enable swagger doc 42 | services.AddSwaggerGen(c => 43 | { 44 | c.SwaggerDoc("v1", new Info { Title = "DroneDelivery-after API", Version = "v1" }); 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, IWebHostEnvironment env) 51 | { 52 | if (env.IsDevelopment()) 53 | { 54 | app.UseDeveloperExceptionPage(); 55 | } 56 | else 57 | { 58 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 59 | app.UseHsts(); 60 | } 61 | 62 | // Enable middleware to serve generated Swagger as a JSON endpoint. 63 | app.UseSwagger(); 64 | 65 | // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), 66 | // specifying the Swagger JSON endpoint. 67 | app.UseSwaggerUI(c => 68 | { 69 | c.SwaggerEndpoint("/swagger/v1/swagger.json", "DroneDelivery-after (Microservice) API v1"); 70 | }); 71 | 72 | app.UseHttpsRedirection(); 73 | 74 | app.UseEndpoints(endpoints => 75 | { 76 | endpoints.MapControllerRoute( 77 | name: "default", 78 | pattern: "{controller=Home}/{action=Index}/{id?}"); 79 | }); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/after/DroneDelivery-after/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Drone Delivery - after (Microservice) 7 | 8 | 9 |

Drone Delivery - after (Microservice)

10 |
11 | 12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /src/after/DroneDelivery-after/Views/Home/SendRequests.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Drone Delivery - after (Microservice): Send Requests 7 | 8 | 9 |

Drone Delivery - after (Microservice): Send Requests

10 |

@ViewBag.Message

11 | 12 | 13 | -------------------------------------------------------------------------------- /src/after/DroneDelivery-after/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | }, 9 | "PackageServiceUri": "http://localhost:7071/api/packages/" 10 | } 11 | -------------------------------------------------------------------------------- /src/after/DroneDelivery-after/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*", 8 | "PackageServiceUri": "https://.azurewebsites.net/api/packages/", 9 | "PackageServiceFunctionCode": "" 10 | } 11 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/DroneDelivery.Common.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Models/ConfirmationRequired.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Models 2 | { 3 | public enum ConfirmationRequired 4 | { 5 | FingerPrint, 6 | Picture, 7 | Voice, 8 | None 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Models/ConfirmationType.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Models 2 | { 3 | public enum ConfirmationType 4 | { 5 | FingerPrint, 6 | Picture, 7 | Voice, 8 | None 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Models/ContainerSize.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Models 2 | { 3 | public enum ContainerSize 4 | { 5 | Small, Medium, Large 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Models/Delivery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DroneDelivery.Common.Models 4 | { 5 | public class Delivery 6 | { 7 | public string DeliveryId { get; set; } 8 | public string OwnerId { get; set; } 9 | public string PickupLocation { get; set; } 10 | public string DropoffLocation { get; set; } 11 | public string Deadline { get; set; } 12 | public bool Expedited { get; set; } 13 | public ConfirmationRequired ConfirmationRequired { get; set; } 14 | public DateTime PickupTime { get; set; } 15 | public PackageInfo PackageInfo { get; set; } 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Models/DeliveryStage.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Models 2 | { 3 | public enum DeliveryStage 4 | { 5 | Created, 6 | Rescheduled, 7 | HeadedToPickup, 8 | HeadedToDropoff, 9 | Completed, 10 | Cancelled 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Models/DeliveryStatus.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Models 2 | { 3 | public class DeliveryStatus 4 | { 5 | public DeliveryStatus(DeliveryStage deliveryStage, Location lastKnownLocation, string pickupeta, string deliveryeta) 6 | { 7 | Stage = deliveryStage; 8 | LastKnownLocation = lastKnownLocation; 9 | PickupETA = pickupeta; 10 | DeliveryETA = deliveryeta; 11 | } 12 | public DeliveryStage Stage { get; } 13 | public Location LastKnownLocation { get; } 14 | public string PickupETA { get; } 15 | public string DeliveryETA { get; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Models/Location.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Models 2 | { 3 | public class Location 4 | { 5 | public Location(double altitude, double latitude, double longitude) 6 | { 7 | Altitude = altitude; 8 | Latitude = latitude; 9 | Longitude = longitude; 10 | } 11 | public double Altitude { get; } 12 | public double Latitude { get; } 13 | public double Longitude { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Models/PackageGen.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | 4 | namespace DroneDelivery.Common.Models 5 | { 6 | public class PackageGen 7 | { 8 | [JsonProperty("id")] 9 | public string Id { get; set; } 10 | [JsonProperty("size")] 11 | [JsonConverter(typeof(StringEnumConverter))] 12 | public ContainerSize Size { get; set; } 13 | [JsonProperty("tag")] 14 | public string Tag { get; set; } 15 | [JsonProperty("weight")] 16 | public double Weight { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Models/PackageInfo.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | 4 | namespace DroneDelivery.Common.Models 5 | { 6 | public class PackageInfo 7 | { 8 | [JsonProperty("packageId")] 9 | public string PackageId { get; set; } 10 | [JsonProperty("size")] 11 | [JsonConverter(typeof(StringEnumConverter))] 12 | public ContainerSize Size { get; set; } 13 | [JsonProperty("weight")] 14 | public double Weight { get; set; } 15 | [JsonProperty("tag")] 16 | public string Tag { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Models/UserAccount.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Models 2 | { 3 | public class UserAccount 4 | { 5 | public UserAccount(string userid, string accountid) 6 | { 7 | UserId = userid; 8 | AccountId = accountid; 9 | } 10 | public string UserId { get; } 11 | public string AccountId { get; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Services/DeliveryRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using DroneDelivery.Common.Models; 4 | 5 | namespace DroneDelivery.Common.Services 6 | { 7 | public class DeliveryRepository : IDeliveryRepository 8 | { 9 | public Task GetAsync(string id) 10 | { 11 | throw new NotImplementedException(); 12 | } 13 | 14 | public Task ScheduleDeliveryAsync(Delivery deliveryRequest, string droneId) 15 | { 16 | //Access common datastore e.g. SQL Azure 17 | Utility.DoWork(50); 18 | return Task.FromResult(true); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Services/DroneScheduler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using DroneDelivery.Common.Models; 3 | 4 | namespace DroneDelivery.Common.Services 5 | { 6 | public class DroneScheduler : IDroneScheduler 7 | { 8 | public Task GetDroneIdAsync(Delivery deliveryRequest) 9 | { 10 | //Access common data store e.g. SQL Azure 11 | Utility.DoWork(50); 12 | return Task.FromResult("test-drone-id"); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Services/IDeliveryRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using DroneDelivery.Common.Models; 3 | 4 | namespace DroneDelivery.Common.Services 5 | { 6 | public interface IDeliveryRepository 7 | { 8 | Task GetAsync(string id); 9 | Task ScheduleDeliveryAsync(Delivery deliveryRequest, string droneId); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Services/IDroneScheduler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using DroneDelivery.Common.Models; 3 | 4 | namespace DroneDelivery.Common.Services 5 | { 6 | public interface IDroneScheduler 7 | { 8 | Task GetDroneIdAsync(Delivery deliveryRequest); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Services/IPackageProcessor.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using DroneDelivery.Common.Models; 3 | 4 | namespace DroneDelivery.Common.Services 5 | { 6 | public interface IPackageProcessor 7 | { 8 | Task CreatePackageAsync(PackageInfo packageInfo); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Services/IRequestProcessor.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using DroneDelivery.Common.Models; 3 | 4 | namespace DroneDelivery.Common.Services 5 | { 6 | public interface IRequestProcessor 7 | { 8 | Task ProcessDeliveryRequestAsync(Delivery deliveryRequest); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Services/RequestProcessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Microsoft.Extensions.Logging; 4 | using DroneDelivery.Common.Models; 5 | 6 | namespace DroneDelivery.Common.Services 7 | { 8 | public class RequestProcessor : IRequestProcessor 9 | { 10 | private readonly ILogger logger; 11 | private readonly IPackageProcessor packageProcessor; 12 | private readonly IDroneScheduler droneScheduler; 13 | private readonly IDeliveryRepository deliveryRepository; 14 | 15 | public RequestProcessor( 16 | ILogger logger, 17 | IPackageProcessor packageProcessor, 18 | IDroneScheduler droneScheduler, 19 | IDeliveryRepository deliveryRepository) 20 | { 21 | this.logger = logger; 22 | this.packageProcessor = packageProcessor; 23 | this.droneScheduler = droneScheduler; 24 | this.deliveryRepository = deliveryRepository; 25 | } 26 | 27 | public async Task ProcessDeliveryRequestAsync(Delivery deliveryRequest) 28 | { 29 | logger.LogInformation("Processing delivery request {deliveryId}", deliveryRequest.DeliveryId); 30 | 31 | try 32 | { 33 | var packageGen = await packageProcessor.CreatePackageAsync(deliveryRequest.PackageInfo).ConfigureAwait(false); 34 | if (packageGen != null) 35 | { 36 | logger.LogInformation("Generated package {packageId} for delivery {deliveryId}", packageGen.Id, deliveryRequest.DeliveryId); 37 | 38 | var droneId = await droneScheduler.GetDroneIdAsync(deliveryRequest).ConfigureAwait(false); 39 | if (droneId != null) 40 | { 41 | logger.LogInformation("Assigned drone {droneId} for delivery {deliveryId}", droneId, deliveryRequest.DeliveryId); 42 | 43 | var success = await deliveryRepository.ScheduleDeliveryAsync(deliveryRequest, droneId).ConfigureAwait(false); 44 | if (success) 45 | { 46 | logger.LogInformation("Completed delivery {deliveryId}", deliveryRequest.DeliveryId); 47 | return true; 48 | } 49 | else 50 | { 51 | logger.LogError("Failed delivery for request {deliveryId}", deliveryRequest.DeliveryId); 52 | } 53 | } 54 | } 55 | } 56 | catch (Exception e) 57 | { 58 | logger.LogError(e, "Error processing delivery request {deliveryId}", deliveryRequest.DeliveryId); 59 | throw; 60 | } 61 | 62 | return false; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.Common/Services/Utility.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Services 2 | { 3 | public class Utility 4 | { 5 | public static long DoWork(int permutations) 6 | { 7 | long count = 0; 8 | 9 | for (int i = 0; i < permutations; i++) 10 | { 11 | for (int j = 0; j < permutations; j++) 12 | { 13 | for (int k = 0; k < permutations; k++) 14 | { 15 | for (int l = 0; l < permutations; l++) 16 | { 17 | 18 | } 19 | count++; 20 | } 21 | } 22 | } 23 | 24 | return count; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/after/DroneDelivery.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29123.88 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{96975B09-2DA2-4E2A-A97A-C17A4B39B4C5}" 7 | ProjectSection(SolutionItems) = preProject 8 | Local.testsettings = Local.testsettings 9 | EndProjectSection 10 | EndProject 11 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DroneDelivery-after", "DroneDelivery-after\DroneDelivery-after.csproj", "{ED1CA726-3504-400D-A864-9AE21ABE5E80}" 12 | EndProject 13 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DroneDelivery.Common", "DroneDelivery.Common\DroneDelivery.Common.csproj", "{4E11CAF6-3BBC-4D3A-B5B3-D319B920ACB9}" 14 | EndProject 15 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageService", "PackageService\PackageService.csproj", "{5DE567FC-935C-45CD-9D64-1D49B89E9CC2}" 16 | EndProject 17 | Global 18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 19 | Debug|Any CPU = Debug|Any CPU 20 | Release|Any CPU = Release|Any CPU 21 | EndGlobalSection 22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 23 | {ED1CA726-3504-400D-A864-9AE21ABE5E80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {ED1CA726-3504-400D-A864-9AE21ABE5E80}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {ED1CA726-3504-400D-A864-9AE21ABE5E80}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {ED1CA726-3504-400D-A864-9AE21ABE5E80}.Release|Any CPU.Build.0 = Release|Any CPU 27 | {4E11CAF6-3BBC-4D3A-B5B3-D319B920ACB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 28 | {4E11CAF6-3BBC-4D3A-B5B3-D319B920ACB9}.Debug|Any CPU.Build.0 = Debug|Any CPU 29 | {4E11CAF6-3BBC-4D3A-B5B3-D319B920ACB9}.Release|Any CPU.ActiveCfg = Release|Any CPU 30 | {4E11CAF6-3BBC-4D3A-B5B3-D319B920ACB9}.Release|Any CPU.Build.0 = Release|Any CPU 31 | {5DE567FC-935C-45CD-9D64-1D49B89E9CC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 32 | {5DE567FC-935C-45CD-9D64-1D49B89E9CC2}.Debug|Any CPU.Build.0 = Debug|Any CPU 33 | {5DE567FC-935C-45CD-9D64-1D49B89E9CC2}.Release|Any CPU.ActiveCfg = Release|Any CPU 34 | {5DE567FC-935C-45CD-9D64-1D49B89E9CC2}.Release|Any CPU.Build.0 = Release|Any CPU 35 | EndGlobalSection 36 | GlobalSection(SolutionProperties) = preSolution 37 | HideSolutionNode = FALSE 38 | EndGlobalSection 39 | GlobalSection(ExtensibilityGlobals) = postSolution 40 | SolutionGuid = {2389C4E8-6EFD-40DE-96FD-65E2B85DC651} 41 | EndGlobalSection 42 | EndGlobal 43 | -------------------------------------------------------------------------------- /src/after/PackageService/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # Azure Functions localsettings file 5 | local.settings.json 6 | 7 | # User-specific files 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | [Ll]og/ 27 | 28 | # Visual Studio 2015 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # MSTest test Results 34 | [Tt]est[Rr]esult*/ 35 | [Bb]uild[Ll]og.* 36 | 37 | # NUNIT 38 | *.VisualState.xml 39 | TestResult.xml 40 | 41 | # Build Results of an ATL Project 42 | [Dd]ebugPS/ 43 | [Rr]eleasePS/ 44 | dlldata.c 45 | 46 | # DNX 47 | project.lock.json 48 | project.fragment.lock.json 49 | artifacts/ 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # NCrunch 117 | _NCrunch_* 118 | .*crunch*.local.xml 119 | nCrunchTemp_* 120 | 121 | # MightyMoose 122 | *.mm.* 123 | AutoTest.Net/ 124 | 125 | # Web workbench (sass) 126 | .sass-cache/ 127 | 128 | # Installshield output folder 129 | [Ee]xpress/ 130 | 131 | # DocProject is a documentation generator add-in 132 | DocProject/buildhelp/ 133 | DocProject/Help/*.HxT 134 | DocProject/Help/*.HxC 135 | DocProject/Help/*.hhc 136 | DocProject/Help/*.hhk 137 | DocProject/Help/*.hhp 138 | DocProject/Help/Html2 139 | DocProject/Help/html 140 | 141 | # Click-Once directory 142 | publish/ 143 | 144 | # Publish Web Output 145 | *.[Pp]ublish.xml 146 | *.azurePubxml 147 | # TODO: Comment the next line if you want to checkin your web deploy settings 148 | # but database connection strings (with potential passwords) will be unencrypted 149 | #*.pubxml 150 | *.publishproj 151 | 152 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 153 | # checkin your Azure Web App publish settings, but sensitive information contained 154 | # in these scripts will be unencrypted 155 | PublishScripts/ 156 | 157 | # NuGet Packages 158 | *.nupkg 159 | # The packages folder can be ignored because of Package Restore 160 | **/packages/* 161 | # except build/, which is used as an MSBuild target. 162 | !**/packages/build/ 163 | # Uncomment if necessary however generally it will be regenerated when needed 164 | #!**/packages/repositories.config 165 | # NuGet v3's project.json files produces more ignoreable files 166 | *.nuget.props 167 | *.nuget.targets 168 | 169 | # Microsoft Azure Build Output 170 | csx/ 171 | *.build.csdef 172 | 173 | # Microsoft Azure Emulator 174 | ecf/ 175 | rcf/ 176 | 177 | # Windows Store app package directories and files 178 | AppPackages/ 179 | BundleArtifacts/ 180 | Package.StoreAssociation.xml 181 | _pkginfo.txt 182 | 183 | # Visual Studio cache files 184 | # files ending in .cache can be ignored 185 | *.[Cc]ache 186 | # but keep track of directories ending in .cache 187 | !*.[Cc]ache/ 188 | 189 | # Others 190 | ClientBin/ 191 | ~$* 192 | *~ 193 | *.dbmdl 194 | *.dbproj.schemaview 195 | *.jfm 196 | *.pfx 197 | *.publishsettings 198 | node_modules/ 199 | orleans.codegen.cs 200 | 201 | # Since there are multiple workflows, uncomment next line to ignore bower_components 202 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 203 | #bower_components/ 204 | 205 | # RIA/Silverlight projects 206 | Generated_Code/ 207 | 208 | # Backup & report files from converting an old project file 209 | # to a newer Visual Studio version. Backup files are not needed, 210 | # because we have git ;-) 211 | _UpgradeReport_Files/ 212 | Backup*/ 213 | UpgradeLog*.XML 214 | UpgradeLog*.htm 215 | 216 | # SQL Server files 217 | *.mdf 218 | *.ldf 219 | 220 | # Business Intelligence projects 221 | *.rdl.data 222 | *.bim.layout 223 | *.bim_*.settings 224 | 225 | # Microsoft Fakes 226 | FakesAssemblies/ 227 | 228 | # GhostDoc plugin setting file 229 | *.GhostDoc.xml 230 | 231 | # Node.js Tools for Visual Studio 232 | .ntvs_analysis.dat 233 | 234 | # Visual Studio 6 build log 235 | *.plg 236 | 237 | # Visual Studio 6 workspace options file 238 | *.opt 239 | 240 | # Visual Studio LightSwitch build output 241 | **/*.HTMLClient/GeneratedArtifacts 242 | **/*.DesktopClient/GeneratedArtifacts 243 | **/*.DesktopClient/ModelManifest.xml 244 | **/*.Server/GeneratedArtifacts 245 | **/*.Server/ModelManifest.xml 246 | _Pvt_Extensions 247 | 248 | # Paket dependency manager 249 | .paket/paket.exe 250 | paket-files/ 251 | 252 | # FAKE - F# Make 253 | .fake/ 254 | 255 | # JetBrains Rider 256 | .idea/ 257 | *.sln.iml 258 | 259 | # CodeRush 260 | .cr/ 261 | 262 | # Python Tools for Visual Studio (PTVS) 263 | __pycache__/ 264 | *.pyc -------------------------------------------------------------------------------- /src/after/PackageService/PackageService.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | PreserveNewest 15 | 16 | 17 | PreserveNewest 18 | Never 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/after/PackageService/PackageServiceFunction.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.Azure.WebJobs; 4 | using Microsoft.Azure.WebJobs.Extensions.Http; 5 | using Microsoft.AspNetCore.Http; 6 | using Microsoft.Extensions.Logging; 7 | using DroneDelivery.Common.Services; 8 | 9 | namespace PackageService 10 | { 11 | public static class PackageServiceFunction 12 | { 13 | [FunctionName("PackageServiceFunction")] 14 | public static Task Run( 15 | [HttpTrigger(AuthorizationLevel.Function, "put", Route = "packages/{id}")] HttpRequest req, 16 | string id, ILogger log) 17 | { 18 | log.LogInformation("C# HTTP trigger function processed a request."); 19 | 20 | //Uses common data store e.g. SQL Azure tables 21 | Utility.DoWork(100); 22 | return Task.FromResult((IActionResult)new CreatedResult("http://example.com", null)); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/after/PackageService/host.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0" 3 | } -------------------------------------------------------------------------------- /src/before/DroneDelivery-before/Connected Services/Application Insights/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", 3 | "Version": "8.14.20131.1", 4 | "GettingStartedDocument": { 5 | "Uri": "https://go.microsoft.com/fwlink/?LinkID=798432" 6 | } 7 | } -------------------------------------------------------------------------------- /src/before/DroneDelivery-before/Controllers/DeliveriesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.Extensions.Logging; 5 | using DroneDelivery.Common.Models; 6 | using DroneDelivery.Common.Services; 7 | 8 | namespace DroneDelivery_before.Controllers 9 | { 10 | [Route("api/[controller]")] 11 | [ApiController] 12 | public class DeliveriesController : ControllerBase 13 | { 14 | private readonly IDeliveryRepository deliveryRepository; 15 | private readonly ILogger logger; 16 | 17 | public DeliveriesController(IDeliveryRepository deliveryRepository, 18 | ILogger logger) 19 | { 20 | this.deliveryRepository = deliveryRepository; 21 | this.logger = logger; 22 | } 23 | 24 | // GET api/deliveries/5 25 | [Route("/api/[controller]/{id}", Name = "GetDelivery")] 26 | [HttpGet] 27 | [ProducesResponseType(typeof(Delivery), 200)] 28 | public async Task Get(string id) 29 | { 30 | logger.LogInformation("In Get action with id: {Id}", id); 31 | 32 | var delivery = await deliveryRepository.GetAsync(id); 33 | 34 | if (delivery == null) 35 | { 36 | logger.LogDebug("Delivery id: {Id} not found", id); 37 | return NotFound(); 38 | } 39 | 40 | return Ok(delivery); 41 | } 42 | 43 | 44 | // GET api/deliveries/5/status 45 | [Route("/api/[controller]/{id}/status")] 46 | [HttpGet] 47 | [ProducesResponseType(typeof(DeliveryStatus), 200)] 48 | public async Task GetStatus(string id) 49 | { 50 | logger.LogInformation("In GetStatus action with id: {Id}", id); 51 | 52 | var delivery = await deliveryRepository.GetAsync(id); 53 | if (delivery == null) 54 | { 55 | logger.LogDebug("Delivery id: {Id} not found", id); 56 | return NotFound(); 57 | } 58 | 59 | var status = new DeliveryStatus(DeliveryStage.HeadedToDropoff, new Location(0, 0, 0), DateTime.Now.AddMinutes(10).ToString(), DateTime.Now.AddHours(1).ToString()); 60 | return Ok(status); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/before/DroneDelivery-before/Controllers/DeliveryRequestsController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.Extensions.Logging; 4 | using DroneDelivery.Common.Models; 5 | using DroneDelivery.Common.Services; 6 | 7 | namespace DroneDelivery_before.Controllers 8 | { 9 | [Route("api/[controller]")] 10 | [ApiController] 11 | public class DeliveryRequestsController : ControllerBase 12 | { 13 | private readonly IRequestProcessor requestProcessor; 14 | private readonly ILogger logger; 15 | 16 | public DeliveryRequestsController(IRequestProcessor requestProcessor, 17 | ILogger logger) 18 | { 19 | this.requestProcessor = requestProcessor; 20 | this.logger = logger; 21 | } 22 | 23 | // POST api/deliveries 24 | [HttpPost()] 25 | [ProducesResponseType(typeof(Delivery), 201)] 26 | public async Task Post([FromBody]Delivery delivery) 27 | { 28 | logger.LogInformation("In Post action: {Delivery}", delivery); 29 | 30 | var success = await requestProcessor.ProcessDeliveryRequestAsync(delivery); 31 | 32 | return CreatedAtRoute("GetDelivery", new { id = delivery.DeliveryId }, delivery); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/before/DroneDelivery-before/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using System; 3 | using System.Diagnostics; 4 | using System.Net.Http; 5 | using System.Threading.Tasks; 6 | using DroneDelivery.Common.Models; 7 | using Newtonsoft.Json; 8 | 9 | namespace DroneDelivery_before.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | private const int RequestCount = 100; 14 | private readonly IHttpClientFactory httpClientFactory; 15 | private Delivery payload; 16 | 17 | public HomeController(IHttpClientFactory httpClientFactory) 18 | { 19 | this.httpClientFactory = httpClientFactory; 20 | 21 | this.payload = new Delivery() 22 | { 23 | DeliveryId = "delivery123", 24 | OwnerId = "owner123", 25 | PickupLocation = "pickup", 26 | DropoffLocation = "dropoff", 27 | PickupTime = DateTime.Now.AddDays(3), 28 | Deadline = "deadline", 29 | Expedited = true, 30 | ConfirmationRequired = ConfirmationRequired.None, 31 | PackageInfo = new PackageInfo() 32 | { 33 | PackageId = "package1234567", 34 | Size = ContainerSize.Small, 35 | Weight = 0, 36 | Tag = "tag" 37 | } 38 | }; 39 | } 40 | 41 | public IActionResult Index() 42 | { 43 | return View(); 44 | } 45 | 46 | [HttpPost()] 47 | [Route("/[controller]/SendRequests")] 48 | public IActionResult SendRequests() 49 | { 50 | var stopWatch = new Stopwatch(); 51 | stopWatch.Start(); 52 | 53 | var httpClient = httpClientFactory.CreateClient(); 54 | var urlBuilder = new UriBuilder(this.Request.Scheme, this.Request.Host.Host); 55 | httpClient.BaseAddress = urlBuilder.Uri; 56 | 57 | var tasks = new Task[RequestCount]; 58 | 59 | for (int i = 0; i < RequestCount; i++) 60 | { 61 | string jsonString = JsonConvert.SerializeObject(payload); 62 | 63 | var httpContent = new StringContent(jsonString, System.Text.Encoding.UTF8, "application/json"); 64 | 65 | tasks[i] = httpClient.PostAsync("/api/DeliveryRequests", httpContent); 66 | } 67 | 68 | Task.WaitAll(tasks); 69 | 70 | stopWatch.Stop(); 71 | ViewBag.Message = $"{RequestCount} messages sent in {stopWatch.Elapsed.Seconds} seconds"; 72 | return View(); 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /src/before/DroneDelivery-before/DroneDelivery-before.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/before/DroneDelivery-before/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Hosting; 3 | 4 | namespace DroneDelivery_before 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | CreateWebHostBuilder(args).Build().Run(); 11 | } 12 | 13 | public static IHostBuilder CreateWebHostBuilder(string[] args) => 14 | Host.CreateDefaultBuilder(args) 15 | .ConfigureWebHostDefaults(webBuilder => 16 | { 17 | webBuilder.UseStartup(); 18 | }); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/before/DroneDelivery-before/Services/PackageProcessor.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using DroneDelivery.Common.Models; 3 | using DroneDelivery.Common.Services; 4 | 5 | namespace DroneDelivery_before.Services 6 | { 7 | public class PackageProcessor : IPackageProcessor 8 | { 9 | public Task CreatePackageAsync(PackageInfo packageInfo) 10 | { 11 | //Uses common data store e.g. SQL Azure tables 12 | Utility.DoWork(100); 13 | return Task.FromResult(new PackageGen { Id = packageInfo.PackageId }); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/before/DroneDelivery-before/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Swashbuckle.AspNetCore.Swagger; 6 | using DroneDelivery.Common.Services; 7 | using DroneDelivery_before.Services; 8 | using Microsoft.Extensions.Hosting; 9 | 10 | namespace DroneDelivery_before 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 | .AddHttpClient() 26 | .AddTransient() 27 | .AddTransient() 28 | .AddTransient() 29 | .AddTransient(); 30 | 31 | services.AddControllersWithViews(); 32 | 33 | // Enable swagger doc 34 | services.AddSwaggerGen(c => 35 | { 36 | c.SwaggerDoc("v1", new Info { Title = "DroneDelivery-before API", Version = "v1" }); 37 | }); 38 | } 39 | 40 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 41 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 42 | { 43 | if (env.IsDevelopment()) 44 | { 45 | app.UseDeveloperExceptionPage(); 46 | } 47 | else 48 | { 49 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 50 | app.UseHsts(); 51 | } 52 | 53 | // Enable middleware to serve generated Swagger as a JSON endpoint. 54 | app.UseSwagger(); 55 | 56 | // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), 57 | // specifying the Swagger JSON endpoint. 58 | app.UseSwaggerUI(c => 59 | { 60 | c.SwaggerEndpoint("/swagger/v1/swagger.json", "DroneDelivery-before (Monolith) API v1"); 61 | }); 62 | 63 | app.UseHttpsRedirection(); 64 | 65 | app.UseEndpoints(endpoints => 66 | { 67 | endpoints.MapControllerRoute( 68 | name: "default", 69 | pattern: "{controller=Home}/{action=Index}/{id?}"); 70 | }); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/before/DroneDelivery-before/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Drone Delivery - before (Monolith) 7 | 8 | 9 |

Drone Delivery - before (Monolith)

10 |
11 | 12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /src/before/DroneDelivery-before/Views/Home/SendRequests.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Drone Delivery - before (Monolith): Send Requests 7 | 8 | 9 |

Drone Delivery - before (Monolith): Send Requests

10 |

@ViewBag.Message

11 | 12 | 13 | -------------------------------------------------------------------------------- /src/before/DroneDelivery-before/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/before/DroneDelivery-before/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*" 8 | } -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/DroneDelivery.Common.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Models/ConfirmationRequired.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Models 2 | { 3 | public enum ConfirmationRequired 4 | { 5 | FingerPrint, 6 | Picture, 7 | Voice, 8 | None 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Models/ConfirmationType.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Models 2 | { 3 | public enum ConfirmationType 4 | { 5 | FingerPrint, 6 | Picture, 7 | Voice, 8 | None 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Models/ContainerSize.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Models 2 | { 3 | public enum ContainerSize 4 | { 5 | Small, Medium, Large 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Models/Delivery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DroneDelivery.Common.Models 4 | { 5 | public class Delivery 6 | { 7 | public string DeliveryId { get; set; } 8 | public string OwnerId { get; set; } 9 | public string PickupLocation { get; set; } 10 | public string DropoffLocation { get; set; } 11 | public string Deadline { get; set; } 12 | public bool Expedited { get; set; } 13 | public ConfirmationRequired ConfirmationRequired { get; set; } 14 | public DateTime PickupTime { get; set; } 15 | public PackageInfo PackageInfo { get; set; } 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Models/DeliveryStage.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Models 2 | { 3 | public enum DeliveryStage 4 | { 5 | Created, 6 | Rescheduled, 7 | HeadedToPickup, 8 | HeadedToDropoff, 9 | Completed, 10 | Cancelled 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Models/DeliveryStatus.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Models 2 | { 3 | public class DeliveryStatus 4 | { 5 | public DeliveryStatus(DeliveryStage deliveryStage, Location lastKnownLocation, string pickupeta, string deliveryeta) 6 | { 7 | Stage = deliveryStage; 8 | LastKnownLocation = lastKnownLocation; 9 | PickupETA = pickupeta; 10 | DeliveryETA = deliveryeta; 11 | } 12 | public DeliveryStage Stage { get; } 13 | public Location LastKnownLocation { get; } 14 | public string PickupETA { get; } 15 | public string DeliveryETA { get; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Models/Location.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Models 2 | { 3 | public class Location 4 | { 5 | public Location(double altitude, double latitude, double longitude) 6 | { 7 | Altitude = altitude; 8 | Latitude = latitude; 9 | Longitude = longitude; 10 | } 11 | public double Altitude { get; } 12 | public double Latitude { get; } 13 | public double Longitude { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Models/PackageGen.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | 4 | namespace DroneDelivery.Common.Models 5 | { 6 | public class PackageGen 7 | { 8 | [JsonProperty("id")] 9 | public string Id { get; set; } 10 | [JsonProperty("size")] 11 | [JsonConverter(typeof(StringEnumConverter))] 12 | public ContainerSize Size { get; set; } 13 | [JsonProperty("tag")] 14 | public string Tag { get; set; } 15 | [JsonProperty("weight")] 16 | public double Weight { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Models/PackageInfo.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | 4 | namespace DroneDelivery.Common.Models 5 | { 6 | public class PackageInfo 7 | { 8 | [JsonProperty("packageId")] 9 | public string PackageId { get; set; } 10 | [JsonProperty("size")] 11 | [JsonConverter(typeof(StringEnumConverter))] 12 | public ContainerSize Size { get; set; } 13 | [JsonProperty("weight")] 14 | public double Weight { get; set; } 15 | [JsonProperty("tag")] 16 | public string Tag { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Models/UserAccount.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Models 2 | { 3 | public class UserAccount 4 | { 5 | public UserAccount(string userid, string accountid) 6 | { 7 | UserId = userid; 8 | AccountId = accountid; 9 | } 10 | public string UserId { get; } 11 | public string AccountId { get; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Services/DeliveryRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using DroneDelivery.Common.Models; 4 | 5 | namespace DroneDelivery.Common.Services 6 | { 7 | public class DeliveryRepository : IDeliveryRepository 8 | { 9 | public Task GetAsync(string id) 10 | { 11 | throw new NotImplementedException(); 12 | } 13 | 14 | public Task ScheduleDeliveryAsync(Delivery deliveryRequest, string droneId) 15 | { 16 | //Access common datastore e.g. SQL Azure 17 | Utility.DoWork(50); 18 | return Task.FromResult(true); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Services/DroneScheduler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using DroneDelivery.Common.Models; 3 | 4 | namespace DroneDelivery.Common.Services 5 | { 6 | public class DroneScheduler : IDroneScheduler 7 | { 8 | public Task GetDroneIdAsync(Delivery deliveryRequest) 9 | { 10 | //Access common data store e.g. SQL Azure 11 | Utility.DoWork(50); 12 | return Task.FromResult("test-drone-id"); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Services/IDeliveryRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using DroneDelivery.Common.Models; 3 | 4 | namespace DroneDelivery.Common.Services 5 | { 6 | public interface IDeliveryRepository 7 | { 8 | Task GetAsync(string id); 9 | Task ScheduleDeliveryAsync(Delivery deliveryRequest, string droneId); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Services/IDroneScheduler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using DroneDelivery.Common.Models; 3 | 4 | namespace DroneDelivery.Common.Services 5 | { 6 | public interface IDroneScheduler 7 | { 8 | Task GetDroneIdAsync(Delivery deliveryRequest); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Services/IPackageProcessor.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using DroneDelivery.Common.Models; 3 | 4 | namespace DroneDelivery.Common.Services 5 | { 6 | public interface IPackageProcessor 7 | { 8 | Task CreatePackageAsync(PackageInfo packageInfo); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Services/IRequestProcessor.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using DroneDelivery.Common.Models; 3 | 4 | namespace DroneDelivery.Common.Services 5 | { 6 | public interface IRequestProcessor 7 | { 8 | Task ProcessDeliveryRequestAsync(Delivery deliveryRequest); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Services/RequestProcessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Microsoft.Extensions.Logging; 4 | using DroneDelivery.Common.Models; 5 | 6 | namespace DroneDelivery.Common.Services 7 | { 8 | public class RequestProcessor : IRequestProcessor 9 | { 10 | private readonly ILogger logger; 11 | private readonly IPackageProcessor packageProcessor; 12 | private readonly IDroneScheduler droneScheduler; 13 | private readonly IDeliveryRepository deliveryRepository; 14 | 15 | public RequestProcessor( 16 | ILogger logger, 17 | IPackageProcessor packageProcessor, 18 | IDroneScheduler droneScheduler, 19 | IDeliveryRepository deliveryRepository) 20 | { 21 | this.logger = logger; 22 | this.packageProcessor = packageProcessor; 23 | this.droneScheduler = droneScheduler; 24 | this.deliveryRepository = deliveryRepository; 25 | } 26 | 27 | public async Task ProcessDeliveryRequestAsync(Delivery deliveryRequest) 28 | { 29 | logger.LogInformation("Processing delivery request {deliveryId}", deliveryRequest.DeliveryId); 30 | 31 | try 32 | { 33 | var packageGen = await packageProcessor.CreatePackageAsync(deliveryRequest.PackageInfo).ConfigureAwait(false); 34 | if (packageGen != null) 35 | { 36 | logger.LogInformation("Generated package {packageId} for delivery {deliveryId}", packageGen.Id, deliveryRequest.DeliveryId); 37 | 38 | var droneId = await droneScheduler.GetDroneIdAsync(deliveryRequest).ConfigureAwait(false); 39 | if (droneId != null) 40 | { 41 | logger.LogInformation("Assigned drone {droneId} for delivery {deliveryId}", droneId, deliveryRequest.DeliveryId); 42 | 43 | var success = await deliveryRepository.ScheduleDeliveryAsync(deliveryRequest, droneId).ConfigureAwait(false); 44 | if (success) 45 | { 46 | logger.LogInformation("Completed delivery {deliveryId}", deliveryRequest.DeliveryId); 47 | return true; 48 | } 49 | else 50 | { 51 | logger.LogError("Failed delivery for request {deliveryId}", deliveryRequest.DeliveryId); 52 | } 53 | } 54 | } 55 | } 56 | catch (Exception e) 57 | { 58 | logger.LogError(e, "Error processing delivery request {deliveryId}", deliveryRequest.DeliveryId); 59 | throw; 60 | } 61 | 62 | return false; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.Common/Services/Utility.cs: -------------------------------------------------------------------------------- 1 | namespace DroneDelivery.Common.Services 2 | { 3 | public class Utility 4 | { 5 | public static long DoWork(int permutations) 6 | { 7 | long count = 0; 8 | 9 | for (int i = 0; i < permutations; i++) 10 | { 11 | for (int j = 0; j < permutations; j++) 12 | { 13 | for (int k = 0; k < permutations; k++) 14 | { 15 | for (int l = 0; l < permutations; l++) 16 | { 17 | 18 | } 19 | count++; 20 | } 21 | } 22 | } 23 | 24 | return count; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/before/DroneDelivery.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29123.88 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DroneDelivery-before", "DroneDelivery-before\DroneDelivery-before.csproj", "{EF64D1F0-26D3-4AEA-92B5-4A07965EABAF}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{96975B09-2DA2-4E2A-A97A-C17A4B39B4C5}" 9 | ProjectSection(SolutionItems) = preProject 10 | Local.testsettings = Local.testsettings 11 | EndProjectSection 12 | EndProject 13 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DroneDelivery.Common", "DroneDelivery.Common\DroneDelivery.Common.csproj", "{4E11CAF6-3BBC-4D3A-B5B3-D319B920ACB9}" 14 | EndProject 15 | Global 16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 17 | Debug|Any CPU = Debug|Any CPU 18 | Release|Any CPU = Release|Any CPU 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {EF64D1F0-26D3-4AEA-92B5-4A07965EABAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {EF64D1F0-26D3-4AEA-92B5-4A07965EABAF}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {EF64D1F0-26D3-4AEA-92B5-4A07965EABAF}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {EF64D1F0-26D3-4AEA-92B5-4A07965EABAF}.Release|Any CPU.Build.0 = Release|Any CPU 25 | {4E11CAF6-3BBC-4D3A-B5B3-D319B920ACB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {4E11CAF6-3BBC-4D3A-B5B3-D319B920ACB9}.Debug|Any CPU.Build.0 = Debug|Any CPU 27 | {4E11CAF6-3BBC-4D3A-B5B3-D319B920ACB9}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {4E11CAF6-3BBC-4D3A-B5B3-D319B920ACB9}.Release|Any CPU.Build.0 = Release|Any CPU 29 | EndGlobalSection 30 | GlobalSection(SolutionProperties) = preSolution 31 | HideSolutionNode = FALSE 32 | EndGlobalSection 33 | GlobalSection(ExtensibilityGlobals) = postSolution 34 | SolutionGuid = {2389C4E8-6EFD-40DE-96FD-65E2B85DC651} 35 | EndGlobalSection 36 | EndGlobal 37 | --------------------------------------------------------------------------------