├── .github
├── CODE_OF_CONDUCT.md
├── ISSUE_TEMPLATE.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ └── pull-request-validator.yml
├── .gitignore
├── .vscode
└── settings.json
├── ApiManagementSchemaImport
├── ApiManagementSchemaImport.sln
├── Microsoft.Azure.ApiManagement.Common
│ ├── ConsoleLog.cs
│ ├── ILog.cs
│ └── Microsoft.Azure.ApiManagement.Common.csproj
├── Microsoft.Azure.ApiManagement.WsdlProcessor.App
│ ├── Microsoft.Azure.ApiManagement.WsdlProcessor.App.csproj
│ ├── Program.cs
│ └── appsettings.json
├── Microsoft.Azure.ApiManagement.WsdlProcessor.Common
│ ├── CommonResources.Designer.cs
│ ├── CommonResources.resx
│ ├── DocumentParsingException.cs
│ ├── Microsoft.Azure.ApiManagement.WsdlProcessor.Common.csproj
│ ├── WsdlDocument.cs
│ └── WsdlDocumentException.cs
├── Microsoft.Azure.ApiManagement.XmlSchemaProcessor.App
│ ├── Microsoft.Azure.ApiManagement.XmlSchemaProcessor.App.csproj
│ └── Program.cs
├── Microsoft.Azure.ApiManagement.XmlSchemaProcessor.Common
│ ├── Microsoft.Azure.ApiManagement.XmlSchemaProcessor.Common.csproj
│ └── XmlSchemaDocument.cs
├── Microsoft.Azure.ApiManagement.XmlSchemaProcessor.TestConsole
│ ├── Microsoft.Azure.ApiManagement.XmlSchemaProcessor.TestConsole.csproj
│ └── Program.cs
├── TestConsole
│ ├── Program.cs
│ └── TestConsole.csproj
├── batchWsdlProcessor.ps1
├── batchXmlSchemaProcessor.ps1
└── uploadschemas.ps1
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
└── examples
├── WsdlProcessor
├── Include.xsd
├── echoInclude.wsdl
└── output.wsdl
├── XmlSchemaProcessor
├── outputFolder
│ ├── schema1.xsd
│ ├── schema2.xsd
│ └── upload-plan.json
├── schema1.xsd
└── schema2.xsd
├── batchWsdlProcessor
└── configFileWsdl.json
├── batchXmlSchemaProcessor
└── configFileXml.json
└── uploadSchemas
└── upload-plan.json
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Microsoft Open Source Code of Conduct
2 |
3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
4 |
5 | Resources:
6 |
7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
10 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
4 | > Please provide us with the following information:
5 | > ---------------------------------------------------------------
6 |
7 | ### This issue is for a: (mark with an `x`)
8 | ```
9 | - [ ] bug report -> please search issues before submitting
10 | - [ ] feature request
11 | - [ ] documentation issue or request
12 | - [ ] regression (a behavior that used to work and stopped in a new release)
13 | ```
14 |
15 | ### Minimal steps to reproduce
16 | >
17 |
18 | ### Any log messages given by the failure
19 | >
20 |
21 | ### Expected/desired behavior
22 | >
23 |
24 | ### OS and Version?
25 | > Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?)
26 |
27 | ### Versions
28 | >
29 |
30 | ### Mention any other details that might be useful
31 |
32 | > ---------------------------------------------------------------
33 | > Thanks! We'll be in touch soon.
34 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Purpose
2 |
3 | * ...
4 |
5 | ## Does this introduce a breaking change?
6 |
7 | ```
8 | [ ] Yes
9 | [ ] No
10 | ```
11 |
12 | ## Pull Request Type
13 | What kind of change does this Pull Request introduce?
14 |
15 |
16 | ```
17 | [ ] Bugfix
18 | [ ] Feature
19 | [ ] Code style update (formatting, local variables)
20 | [ ] Refactoring (no functional changes, no api changes)
21 | [ ] Documentation content changes
22 | [ ] Other... Please describe:
23 | ```
24 |
25 | ## How to Test
26 | * Get the code
27 |
28 | ```
29 | git clone [repo-address]
30 | cd [repo-name]
31 | git checkout [branch-name]
32 | npm install
33 | ```
34 |
35 | * Test the code
36 |
37 | ```
38 | ```
39 |
40 | ## What to Check
41 | Verify that the following are valid
42 | * ...
43 |
44 | ## Other Information
45 |
--------------------------------------------------------------------------------
/.github/workflows/pull-request-validator.yml:
--------------------------------------------------------------------------------
1 | name: Pull Request Build Validator
2 | run-name: Pull Request Build Validator created by ${{ github.actor }}
3 |
4 | on:
5 | pull_request:
6 | types: [opened, synchronize, reopened]
7 |
8 | env:
9 | dotnetVersion: 9.x
10 |
11 | jobs:
12 | build:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | with:
17 | fetch-depth: 0
18 |
19 | - name: Setup .NET
20 | uses: actions/setup-dotnet@v3
21 | with:
22 | dotnet-version: ${{ env.dotnetVersion }}
23 |
24 | - name: Restore dependencies
25 | run: dotnet restore ./ApiManagementSchemaImport/ApiManagementSchemaImport.sln
26 |
27 | - name: Build
28 | run: dotnet build ./ApiManagementSchemaImport/ApiManagementSchemaImport.sln --no-restore
29 |
--------------------------------------------------------------------------------
/.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 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Aa][Rr][Mm]/
27 | [Aa][Rr][Mm]64/
28 | bld/
29 | [Bb]in/
30 | [Oo]bj/
31 | [Ll]og/
32 | [Ll]ogs/
33 |
34 | # Visual Studio 2015/2017 cache/options directory
35 | .vs/
36 | # Uncomment if you have tasks that create the project's static files in wwwroot
37 | #wwwroot/
38 |
39 | # Visual Studio 2017 auto generated files
40 | Generated\ Files/
41 |
42 | # MSTest test Results
43 | [Tt]est[Rr]esult*/
44 | [Bb]uild[Ll]og.*
45 |
46 | # NUnit
47 | *.VisualState.xml
48 | TestResult.xml
49 | nunit-*.xml
50 |
51 | # Build Results of an ATL Project
52 | [Dd]ebugPS/
53 | [Rr]eleasePS/
54 | dlldata.c
55 |
56 | # Benchmark Results
57 | BenchmarkDotNet.Artifacts/
58 |
59 | # .NET Core
60 | project.lock.json
61 | project.fragment.lock.json
62 | artifacts/
63 |
64 | # StyleCop
65 | StyleCopReport.xml
66 |
67 | # Files built by Visual Studio
68 | *_i.c
69 | *_p.c
70 | *_h.h
71 | *.ilk
72 | *.meta
73 | *.obj
74 | *.iobj
75 | *.pch
76 | *.pdb
77 | *.ipdb
78 | *.pgc
79 | *.pgd
80 | *.rsp
81 | *.sbr
82 | *.tlb
83 | *.tli
84 | *.tlh
85 | *.tmp
86 | *.tmp_proj
87 | *_wpftmp.csproj
88 | *.log
89 | *.vspscc
90 | *.vssscc
91 | .builds
92 | *.pidb
93 | *.svclog
94 | *.scc
95 |
96 | # Chutzpah Test files
97 | _Chutzpah*
98 |
99 | # Visual C++ cache files
100 | ipch/
101 | *.aps
102 | *.ncb
103 | *.opendb
104 | *.opensdf
105 | *.sdf
106 | *.cachefile
107 | *.VC.db
108 | *.VC.VC.opendb
109 |
110 | # Visual Studio profiler
111 | *.psess
112 | *.vsp
113 | *.vspx
114 | *.sap
115 |
116 | # Visual Studio Trace Files
117 | *.e2e
118 |
119 | # TFS 2012 Local Workspace
120 | $tf/
121 |
122 | # Guidance Automation Toolkit
123 | *.gpState
124 |
125 | # ReSharper is a .NET coding add-in
126 | _ReSharper*/
127 | *.[Rr]e[Ss]harper
128 | *.DotSettings.user
129 |
130 | # TeamCity is a build add-in
131 | _TeamCity*
132 |
133 | # DotCover is a Code Coverage Tool
134 | *.dotCover
135 |
136 | # AxoCover is a Code Coverage Tool
137 | .axoCover/*
138 | !.axoCover/settings.json
139 |
140 | # Visual Studio code coverage results
141 | *.coverage
142 | *.coveragexml
143 |
144 | # NCrunch
145 | _NCrunch_*
146 | .*crunch*.local.xml
147 | nCrunchTemp_*
148 |
149 | # MightyMoose
150 | *.mm.*
151 | AutoTest.Net/
152 |
153 | # Web workbench (sass)
154 | .sass-cache/
155 |
156 | # Installshield output folder
157 | [Ee]xpress/
158 |
159 | # DocProject is a documentation generator add-in
160 | DocProject/buildhelp/
161 | DocProject/Help/*.HxT
162 | DocProject/Help/*.HxC
163 | DocProject/Help/*.hhc
164 | DocProject/Help/*.hhk
165 | DocProject/Help/*.hhp
166 | DocProject/Help/Html2
167 | DocProject/Help/html
168 |
169 | # Click-Once directory
170 | publish/
171 |
172 | # Publish Web Output
173 | *.[Pp]ublish.xml
174 | *.azurePubxml
175 | # Note: Comment the next line if you want to checkin your web deploy settings,
176 | # but database connection strings (with potential passwords) will be unencrypted
177 | *.pubxml
178 | *.publishproj
179 |
180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
181 | # checkin your Azure Web App publish settings, but sensitive information contained
182 | # in these scripts will be unencrypted
183 | PublishScripts/
184 |
185 | # NuGet Packages
186 | *.nupkg
187 | # NuGet Symbol Packages
188 | *.snupkg
189 | # The packages folder can be ignored because of Package Restore
190 | **/[Pp]ackages/*
191 | # except build/, which is used as an MSBuild target.
192 | !**/[Pp]ackages/build/
193 | # Uncomment if necessary however generally it will be regenerated when needed
194 | #!**/[Pp]ackages/repositories.config
195 | # NuGet v3's project.json files produces more ignorable files
196 | *.nuget.props
197 | *.nuget.targets
198 |
199 | # Microsoft Azure Build Output
200 | csx/
201 | *.build.csdef
202 |
203 | # Microsoft Azure Emulator
204 | ecf/
205 | rcf/
206 |
207 | # Windows Store app package directories and files
208 | AppPackages/
209 | BundleArtifacts/
210 | Package.StoreAssociation.xml
211 | _pkginfo.txt
212 | *.appx
213 | *.appxbundle
214 | *.appxupload
215 |
216 | # Visual Studio cache files
217 | # files ending in .cache can be ignored
218 | *.[Cc]ache
219 | # but keep track of directories ending in .cache
220 | !?*.[Cc]ache/
221 |
222 | # Others
223 | ClientBin/
224 | ~$*
225 | *~
226 | *.dbmdl
227 | *.dbproj.schemaview
228 | *.jfm
229 | *.pfx
230 | *.publishsettings
231 | orleans.codegen.cs
232 |
233 | # Including strong name files can present a security risk
234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
235 | #*.snk
236 |
237 | # Since there are multiple workflows, uncomment next line to ignore bower_components
238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
239 | #bower_components/
240 |
241 | # RIA/Silverlight projects
242 | Generated_Code/
243 |
244 | # Backup & report files from converting an old project file
245 | # to a newer Visual Studio version. Backup files are not needed,
246 | # because we have git ;-)
247 | _UpgradeReport_Files/
248 | Backup*/
249 | UpgradeLog*.XML
250 | UpgradeLog*.htm
251 | ServiceFabricBackup/
252 | *.rptproj.bak
253 |
254 | # SQL Server files
255 | *.mdf
256 | *.ldf
257 | *.ndf
258 |
259 | # Business Intelligence projects
260 | *.rdl.data
261 | *.bim.layout
262 | *.bim_*.settings
263 | *.rptproj.rsuser
264 | *- [Bb]ackup.rdl
265 | *- [Bb]ackup ([0-9]).rdl
266 | *- [Bb]ackup ([0-9][0-9]).rdl
267 |
268 | # Microsoft Fakes
269 | FakesAssemblies/
270 |
271 | # GhostDoc plugin setting file
272 | *.GhostDoc.xml
273 |
274 | # Node.js Tools for Visual Studio
275 | .ntvs_analysis.dat
276 | node_modules/
277 |
278 | # Visual Studio 6 build log
279 | *.plg
280 |
281 | # Visual Studio 6 workspace options file
282 | *.opt
283 |
284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
285 | *.vbw
286 |
287 | # Visual Studio LightSwitch build output
288 | **/*.HTMLClient/GeneratedArtifacts
289 | **/*.DesktopClient/GeneratedArtifacts
290 | **/*.DesktopClient/ModelManifest.xml
291 | **/*.Server/GeneratedArtifacts
292 | **/*.Server/ModelManifest.xml
293 | _Pvt_Extensions
294 |
295 | # Paket dependency manager
296 | .paket/paket.exe
297 | paket-files/
298 |
299 | # FAKE - F# Make
300 | .fake/
301 |
302 | # CodeRush personal settings
303 | .cr/personal
304 |
305 | # Python Tools for Visual Studio (PTVS)
306 | __pycache__/
307 | *.pyc
308 |
309 | # Cake - Uncomment if you are using it
310 | # tools/**
311 | # !tools/packages.config
312 |
313 | # Tabs Studio
314 | *.tss
315 |
316 | # Telerik's JustMock configuration file
317 | *.jmconfig
318 |
319 | # BizTalk build output
320 | *.btp.cs
321 | *.btm.cs
322 | *.odx.cs
323 | *.xsd.cs
324 |
325 | # OpenCover UI analysis results
326 | OpenCover/
327 |
328 | # Azure Stream Analytics local run output
329 | ASALocalRun/
330 |
331 | # MSBuild Binary and Structured Log
332 | *.binlog
333 |
334 | # NVidia Nsight GPU debugger configuration file
335 | *.nvuser
336 |
337 | # MFractors (Xamarin productivity tool) working folder
338 | .mfractor/
339 |
340 | # Local History for Visual Studio
341 | .localhistory/
342 |
343 | # BeatPulse healthcheck temp database
344 | healthchecksdb
345 |
346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
347 | MigrationBackup/
348 |
349 | # Ionide (cross platform F# VS Code tools) working folder
350 | .ionide/
351 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "markdownlint.config": {
3 | "MD028": false,
4 | "MD025": {
5 | "front_matter_title": ""
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/ApiManagementSchemaImport.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31529.105
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.ApiManagement.WsdlProcessor.App", "Microsoft.Azure.ApiManagement.WsdlProcessor.App\Microsoft.Azure.ApiManagement.WsdlProcessor.App.csproj", "{4ABFD15B-37F2-4A16-A9A5-A80DC918B0F2}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.ApiManagement.WsdlProcessor.Common", "Microsoft.Azure.ApiManagement.WsdlProcessor.Common\Microsoft.Azure.ApiManagement.WsdlProcessor.Common.csproj", "{FFC31B5C-03C1-4303-96C7-E25052186877}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestConsole", "TestConsole\TestConsole.csproj", "{44D72813-AB99-4230-985C-FFD0E40092A5}"
11 | EndProject
12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.ApiManagement.XmlSchemaProcessor.App", "Microsoft.Azure.ApiManagement.XmlSchemaProcessor.App\Microsoft.Azure.ApiManagement.XmlSchemaProcessor.App.csproj", "{5233A8EC-5B87-43AD-B993-655CCC6EB455}"
13 | EndProject
14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.ApiManagement.XmlSchemaProcessor.Common", "Microsoft.Azure.ApiManagement.XmlSchemaProcessor.Common\Microsoft.Azure.ApiManagement.XmlSchemaProcessor.Common.csproj", "{8FC578CA-8FD6-412A-9B46-48152458D816}"
15 | EndProject
16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Azure.ApiManagement.XmlSchemaProcessor.TestConsole", "Microsoft.Azure.ApiManagement.XmlSchemaProcessor.TestConsole\Microsoft.Azure.ApiManagement.XmlSchemaProcessor.TestConsole.csproj", "{15848C1D-60C0-456B-8A2A-7ACFA83AFC31}"
17 | EndProject
18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Azure.ApiManagement.Common", "Microsoft.Azure.ApiManagement.Common\Microsoft.Azure.ApiManagement.Common.csproj", "{375671A0-1996-4D1B-813F-6F7BBBE5F16B}"
19 | EndProject
20 | Global
21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
22 | Debug|Any CPU = Debug|Any CPU
23 | Release|Any CPU = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
26 | {4ABFD15B-37F2-4A16-A9A5-A80DC918B0F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {4ABFD15B-37F2-4A16-A9A5-A80DC918B0F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {4ABFD15B-37F2-4A16-A9A5-A80DC918B0F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {4ABFD15B-37F2-4A16-A9A5-A80DC918B0F2}.Release|Any CPU.Build.0 = Release|Any CPU
30 | {FFC31B5C-03C1-4303-96C7-E25052186877}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31 | {FFC31B5C-03C1-4303-96C7-E25052186877}.Debug|Any CPU.Build.0 = Debug|Any CPU
32 | {FFC31B5C-03C1-4303-96C7-E25052186877}.Release|Any CPU.ActiveCfg = Release|Any CPU
33 | {FFC31B5C-03C1-4303-96C7-E25052186877}.Release|Any CPU.Build.0 = Release|Any CPU
34 | {44D72813-AB99-4230-985C-FFD0E40092A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35 | {44D72813-AB99-4230-985C-FFD0E40092A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
36 | {44D72813-AB99-4230-985C-FFD0E40092A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
37 | {44D72813-AB99-4230-985C-FFD0E40092A5}.Release|Any CPU.Build.0 = Release|Any CPU
38 | {5233A8EC-5B87-43AD-B993-655CCC6EB455}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39 | {5233A8EC-5B87-43AD-B993-655CCC6EB455}.Debug|Any CPU.Build.0 = Debug|Any CPU
40 | {5233A8EC-5B87-43AD-B993-655CCC6EB455}.Release|Any CPU.ActiveCfg = Release|Any CPU
41 | {5233A8EC-5B87-43AD-B993-655CCC6EB455}.Release|Any CPU.Build.0 = Release|Any CPU
42 | {8FC578CA-8FD6-412A-9B46-48152458D816}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
43 | {8FC578CA-8FD6-412A-9B46-48152458D816}.Debug|Any CPU.Build.0 = Debug|Any CPU
44 | {8FC578CA-8FD6-412A-9B46-48152458D816}.Release|Any CPU.ActiveCfg = Release|Any CPU
45 | {8FC578CA-8FD6-412A-9B46-48152458D816}.Release|Any CPU.Build.0 = Release|Any CPU
46 | {15848C1D-60C0-456B-8A2A-7ACFA83AFC31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
47 | {15848C1D-60C0-456B-8A2A-7ACFA83AFC31}.Debug|Any CPU.Build.0 = Debug|Any CPU
48 | {15848C1D-60C0-456B-8A2A-7ACFA83AFC31}.Release|Any CPU.ActiveCfg = Release|Any CPU
49 | {15848C1D-60C0-456B-8A2A-7ACFA83AFC31}.Release|Any CPU.Build.0 = Release|Any CPU
50 | {375671A0-1996-4D1B-813F-6F7BBBE5F16B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
51 | {375671A0-1996-4D1B-813F-6F7BBBE5F16B}.Debug|Any CPU.Build.0 = Debug|Any CPU
52 | {375671A0-1996-4D1B-813F-6F7BBBE5F16B}.Release|Any CPU.ActiveCfg = Release|Any CPU
53 | {375671A0-1996-4D1B-813F-6F7BBBE5F16B}.Release|Any CPU.Build.0 = Release|Any CPU
54 | EndGlobalSection
55 | GlobalSection(SolutionProperties) = preSolution
56 | HideSolutionNode = FALSE
57 | EndGlobalSection
58 | GlobalSection(ExtensibilityGlobals) = postSolution
59 | SolutionGuid = {605FBF9A-0F9D-4586-AE7E-749C92A40148}
60 | EndGlobalSection
61 | EndGlobal
62 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.Common/ConsoleLog.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Azure.ApiManagement.Common;
2 |
3 | public class ConsoleLog : ILog
4 | {
5 | public void Critical(string eventName)
6 | {
7 | Console.WriteLine("Critical : " + eventName);
8 | }
9 |
10 | public void Critical(string eventName, string message)
11 | {
12 | Console.WriteLine("Critical : " + eventName + " : " + message);
13 | }
14 |
15 | public void Critical(string eventName, Exception ex)
16 | {
17 | Console.WriteLine("Critical : " + eventName + " : Exception : " + ex.Message);
18 | }
19 |
20 | public void Critical(string eventName, string message, Exception ex)
21 | {
22 | Console.WriteLine("Critical : " + eventName + " : " + message + " : Exception : " + ex.Message);
23 | }
24 |
25 | public void Critical(string eventName, string message, Exception ex, params object[] args)
26 | {
27 | Console.WriteLine("Critical : " + eventName + " : " + message + " : Exception : " + ex.Message);
28 | }
29 |
30 | public void Error(string eventName)
31 | {
32 | Console.WriteLine("Error : " + eventName);
33 | }
34 |
35 | public void Error(string eventName, string message)
36 | {
37 | Console.WriteLine("Error : " + eventName + " : " + message);
38 | }
39 |
40 | public void Error(string eventName, Exception ex)
41 | {
42 | Console.WriteLine("Error : " + eventName + " : Exception : " + ex.Message);
43 | }
44 |
45 | public void Error(string eventName, string message, Exception ex)
46 | {
47 | Console.WriteLine("Error : " + eventName + " : " + message + " : Exception : " + ex.Message);
48 | }
49 |
50 | public void Error(string eventName, string message, Exception ex, params object[] args)
51 | {
52 | Console.WriteLine("Error : " + eventName + " : " + message + " : Exception : " + ex.Message);
53 | }
54 |
55 | public void Informational(string eventName)
56 | {
57 | Console.WriteLine("Info : " + eventName);
58 | }
59 |
60 | public void Informational(string eventName, string message)
61 | {
62 | Console.WriteLine("Info : " + eventName + " : " + message);
63 | }
64 |
65 | public void Informational(string eventName, Exception ex)
66 | {
67 | Console.WriteLine("Info : " + eventName + " : Exception : " + ex.Message);
68 | }
69 |
70 | public void Informational(string eventName, string message, Exception ex)
71 | {
72 | Console.WriteLine("Info : " + eventName + " : " + message + " : Exception : " + ex.Message);
73 | }
74 |
75 | public void Informational(string eventName, string message, Exception ex, params object[] args)
76 | {
77 | Console.WriteLine("Info : " + eventName + " : " + message + " : Exception : " + ex.Message);
78 | }
79 |
80 | public void Verbose(string eventName)
81 | {
82 | Console.WriteLine("Verbose : " + eventName);
83 | }
84 |
85 | public void Verbose(string eventName, string message)
86 | {
87 | Console.WriteLine("Verbose : " + eventName + " : " + message);
88 | }
89 |
90 | public void Verbose(string eventName, Exception ex)
91 | {
92 | Console.WriteLine("Verbose : " + eventName + " : Exception : " + ex.Message);
93 | }
94 |
95 | public void Verbose(string eventName, string message, Exception ex)
96 | {
97 | Console.WriteLine("Verbose : " + eventName + " : " + message + " : Exception : " + ex.Message);
98 | }
99 |
100 | public void Verbose(string eventName, string message, Exception ex, params object[] args)
101 | {
102 | Console.WriteLine("Verbose : " + eventName + " : " + message + " : Exception : " + ex.Message);
103 | }
104 |
105 | public void Warning(string eventName)
106 | {
107 | Console.WriteLine("Warning : " + eventName);
108 | }
109 |
110 | public void Warning(string eventName, string message)
111 | {
112 | Console.WriteLine("Warning : " + eventName + " : " + message);
113 | }
114 |
115 | public void Warning(string eventName, Exception ex)
116 | {
117 | Console.WriteLine("Warning : " + eventName + " : Exception : " + ex.Message);
118 | }
119 |
120 | public void Warning(string eventName, string message, Exception ex)
121 | {
122 | Console.WriteLine("Warning : " + eventName + " : " + message + " : Exception : " + ex.Message);
123 | }
124 |
125 | public void Warning(string eventName, string message, Exception ex, params object[] args)
126 | {
127 | Console.WriteLine("Warning : " + eventName + " : " + message + " : Exception : " + ex.Message);
128 | }
129 |
130 | public void Success(string msg)
131 | {
132 | Console.WriteLine("Success : " + msg);
133 | }
134 | }
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.Common/ILog.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.Azure.ApiManagement.Common
2 | {
3 | public interface ILog
4 | {
5 | void Verbose(string eventName);
6 |
7 | void Verbose(string eventName, string message);
8 |
9 | void Verbose(string eventName, Exception ex);
10 |
11 | void Verbose(string eventName, string message, Exception ex);
12 |
13 | void Verbose(string eventName, string message, Exception ex, params object[] args);
14 |
15 | void Informational(string eventName);
16 |
17 | void Informational(string eventName, string message);
18 |
19 | void Informational(string eventName, Exception ex);
20 |
21 | void Informational(string eventName, string message, Exception ex);
22 |
23 | void Informational(string eventName, string message, Exception ex, params object[] args);
24 |
25 | void Warning(string eventName);
26 |
27 | void Warning(string eventName, string message);
28 |
29 | void Warning(string eventName, Exception ex);
30 |
31 | void Warning(string eventName, string message, Exception ex);
32 |
33 | void Warning(string eventName, string message, Exception ex, params object[] args);
34 |
35 | void Error(string eventName);
36 |
37 | void Error(string eventName, string message);
38 |
39 | void Error(string eventName, Exception ex);
40 |
41 | void Error(string eventName, string message, Exception ex);
42 |
43 | void Error(string eventName, string message, Exception ex, params object[] args);
44 |
45 | void Critical(string eventName);
46 |
47 | void Critical(string eventName, string message);
48 |
49 | void Critical(string eventName, Exception ex);
50 |
51 | void Critical(string eventName, string message, Exception ex);
52 |
53 | void Critical(string eventName, string message, Exception ex, params object[] args);
54 |
55 | void Success(string msg);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.Common/Microsoft.Azure.ApiManagement.Common.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net9.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.WsdlProcessor.App/Microsoft.Azure.ApiManagement.WsdlProcessor.App.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net9.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.WsdlProcessor.App/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Azure.ApiManagement.WsdlProcessor.Common;
2 | using System;
3 | using System.IO;
4 | using System.Threading.Tasks;
5 | using System.Xml;
6 | using System.Xml.Linq;
7 |
8 | namespace Microsoft.Azure.ApiManagement.WsdlProcessor.App
9 | {
10 | class Program
11 | {
12 | static async Task Main(string[] args)
13 | {
14 | string wsdlFile, outputFile = string.Empty;
15 |
16 | var log = new ConsoleLog();
17 | int exitCode = 0;
18 |
19 | if (args.Length == 2)
20 | {
21 | wsdlFile = args[0];
22 | if (!File.Exists(wsdlFile))
23 | {
24 | var msg = $"The input file {wsdlFile} does not exists or we cannot access.";
25 | log.Error(msg);
26 | throw new Exception(msg);
27 | }
28 |
29 | wsdlFile = wsdlFile.Contains(".wsdl") ? wsdlFile : wsdlFile + ".wsdl";
30 |
31 | outputFile = args[1];
32 | outputFile = Path.IsPathRooted(outputFile) ? outputFile : Path.Join(Directory.GetCurrentDirectory(), outputFile);
33 | }
34 | else
35 | {
36 | Console.WriteLine("Please fill the corrects parameters.");
37 | Console.WriteLine("Parameters 1 = WSDL file path.");
38 | Console.WriteLine("Parameters 2 = Output file path.");
39 | Environment.Exit(1);
40 |
41 | return;
42 | }
43 |
44 | try
45 | {
46 | var wsdlString = File.ReadAllText(wsdlFile);
47 | var xDocument = XDocument.Parse(wsdlString);
48 | await WsdlDocument.LoadAsync(xDocument.Root, log);
49 |
50 | xDocument.Root.Save(outputFile);
51 |
52 | Console.WriteLine();
53 | Console.WriteLine();
54 |
55 | log.Success($"*** WSDL file {wsdlFile} processed successfully and generate file {outputFile}.");
56 | }
57 | catch (XmlException e)
58 | {
59 | exitCode = 1;
60 | log.Error($"{e.Message}");
61 | log.Error($"Location {wsdlFile} contains invalid xml: {e.StackTrace}");
62 | }
63 | catch (Exception e)
64 | {
65 | exitCode = 1;
66 | log.Error($"{e.Message}");
67 | log.Error($"Stacktrace: {e.StackTrace}");
68 | }
69 |
70 | Environment.Exit(exitCode);
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.WsdlProcessor.App/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "HttpTimeoutMilliseconds": 10000
3 | }
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.WsdlProcessor.Common/CommonResources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Microsoft.Azure.ApiManagement.WsdlProcessor.Common {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class CommonResources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal CommonResources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Azure.ApiManagement.WsdlProcessor.Common.CommonResources", typeof(CommonResources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to Binding '{0}' not found..
65 | ///
66 | internal static string BindingNotFound {
67 | get {
68 | return ResourceManager.GetString("BindingNotFound", resourceCulture);
69 | }
70 | }
71 |
72 | ///
73 | /// Looks up a localized string similar to Could not resolve type '{0}'..
74 | ///
75 | internal static string CannotResolveType {
76 | get {
77 | return ResourceManager.GetString("CannotResolveType", resourceCulture);
78 | }
79 | }
80 |
81 | ///
82 | /// Looks up a localized string similar to Could not retrieve import from '{0}'. The request failed with error '{1}' and message '{2}'..
83 | ///
84 | internal static string FailedToImport {
85 | get {
86 | return ResourceManager.GetString("FailedToImport", resourceCulture);
87 | }
88 | }
89 |
90 | ///
91 | /// Looks up a localized string similar to Could not retrieve import from '{0}'. The request response code was '{1}' and parsing the response content failed with '{2}' and message '{3}'..
92 | ///
93 | internal static string FailedToParseImportedSchemaResponse {
94 | get {
95 | return ResourceManager.GetString("FailedToParseImportedSchemaResponse", resourceCulture);
96 | }
97 | }
98 |
99 | ///
100 | /// Looks up a localized string similar to Cannot resolve referenced input message '{0}'..
101 | ///
102 | internal static string InputMessageNotFound {
103 | get {
104 | return ResourceManager.GetString("InputMessageNotFound", resourceCulture);
105 | }
106 | }
107 |
108 | ///
109 | /// Looks up a localized string similar to Interface '{0}' not found..
110 | ///
111 | internal static string InterfaceNotFound {
112 | get {
113 | return ResourceManager.GetString("InterfaceNotFound", resourceCulture);
114 | }
115 | }
116 |
117 | ///
118 | /// Looks up a localized string similar to The provided schema '{0}' is invalid and cannot be parsed..
119 | ///
120 | internal static string InvalidXmlSchema {
121 | get {
122 | return ResourceManager.GetString("InvalidXmlSchema", resourceCulture);
123 | }
124 | }
125 |
126 | ///
127 | /// Looks up a localized string similar to Loaded '{0}' bindings..
128 | ///
129 | internal static string LoadedBindings {
130 | get {
131 | return ResourceManager.GetString("LoadedBindings", resourceCulture);
132 | }
133 | }
134 |
135 | ///
136 | /// Looks up a localized string similar to Loaded '{0}' interfaces..
137 | ///
138 | internal static string LoadedInterfaces {
139 | get {
140 | return ResourceManager.GetString("LoadedInterfaces", resourceCulture);
141 | }
142 | }
143 |
144 | ///
145 | /// Looks up a localized string similar to Loaded '{0}' messages..
146 | ///
147 | internal static string LoadedMessages {
148 | get {
149 | return ResourceManager.GetString("LoadedMessages", resourceCulture);
150 | }
151 | }
152 |
153 | ///
154 | /// Looks up a localized string similar to No schemas found..
155 | ///
156 | internal static string LoadedNoSchemas {
157 | get {
158 | return ResourceManager.GetString("LoadedNoSchemas", resourceCulture);
159 | }
160 | }
161 |
162 | ///
163 | /// Looks up a localized string similar to Target Namespace: '{0}'..
164 | ///
165 | internal static string LoadedSchema {
166 | get {
167 | return ResourceManager.GetString("LoadedSchema", resourceCulture);
168 | }
169 | }
170 |
171 | ///
172 | /// Looks up a localized string similar to Loaded '{0}' schemas..
173 | ///
174 | internal static string LoadedSchemas {
175 | get {
176 | return ResourceManager.GetString("LoadedSchemas", resourceCulture);
177 | }
178 | }
179 |
180 | ///
181 | /// Looks up a localized string similar to Loaded '{0}' services..
182 | ///
183 | internal static string LoadedServices {
184 | get {
185 | return ResourceManager.GetString("LoadedServices", resourceCulture);
186 | }
187 | }
188 |
189 | ///
190 | /// Looks up a localized string similar to Loaded '{0}' types..
191 | ///
192 | internal static string LoadedTypes {
193 | get {
194 | return ResourceManager.GetString("LoadedTypes", resourceCulture);
195 | }
196 | }
197 |
198 | ///
199 | /// Looks up a localized string similar to No interfaces found..
200 | ///
201 | internal static string NoInterfacesFound {
202 | get {
203 | return ResourceManager.GetString("NoInterfacesFound", resourceCulture);
204 | }
205 | }
206 |
207 | ///
208 | /// Looks up a localized string similar to Notification Operation '{0}' is not supported. Only Request-response and Solicit-response Operations are supported..
209 | ///
210 | internal static string NotificationOperationNotSupported {
211 | get {
212 | return ResourceManager.GetString("NotificationOperationNotSupported", resourceCulture);
213 | }
214 | }
215 |
216 | ///
217 | /// Looks up a localized string similar to One-way Operation '{0}' is not supported. Only Request-response and Solicit-response Operations are supported..
218 | ///
219 | internal static string OneWayOperationNotSupported {
220 | get {
221 | return ResourceManager.GetString("OneWayOperationNotSupported", resourceCulture);
222 | }
223 | }
224 |
225 | ///
226 | /// Looks up a localized string similar to Unable to generate unique resource identifiers for operations, both operation names and SOAP actions conflict. Please modify the WSDL document to avoid redundant operation names, including redundant use of empty string..
227 | ///
228 | internal static string OperationsActionsBothDoConflict {
229 | get {
230 | return ResourceManager.GetString("OperationsActionsBothDoConflict", resourceCulture);
231 | }
232 | }
233 |
234 | ///
235 | /// Looks up a localized string similar to Cannot resolve referenced output message '{0}'..
236 | ///
237 | internal static string OutputMessageNotFound {
238 | get {
239 | return ResourceManager.GetString("OutputMessageNotFound", resourceCulture);
240 | }
241 | }
242 |
243 | ///
244 | /// Looks up a localized string similar to Completed parsing XML..
245 | ///
246 | internal static string ParsingXmlComplete {
247 | get {
248 | return ResourceManager.GetString("ParsingXmlComplete", resourceCulture);
249 | }
250 | }
251 |
252 | ///
253 | /// Looks up a localized string similar to Started parsing XML..
254 | ///
255 | internal static string ParsingXmlStarted {
256 | get {
257 | return ResourceManager.GetString("ParsingXmlStarted", resourceCulture);
258 | }
259 | }
260 |
261 | ///
262 | /// Looks up a localized string similar to Element named '{0}' has a recursive definition. Recursive types are not supported..
263 | ///
264 | internal static string RecursiveTypesNotSupported {
265 | get {
266 | return ResourceManager.GetString("RecursiveTypesNotSupported", resourceCulture);
267 | }
268 | }
269 |
270 | ///
271 | /// Looks up a localized string similar to Schemas only allow Imports or Includes..
272 | ///
273 | internal static string SchemaOnlyAllowsIncludeOrImport {
274 | get {
275 | return ResourceManager.GetString("SchemaOnlyAllowsIncludeOrImport", resourceCulture);
276 | }
277 | }
278 |
279 | ///
280 | /// Looks up a localized string similar to A soap:address element with location attribute is required in the wsdl:port element named '{0}' of the WSDL document..
281 | ///
282 | internal static string SoapAddressLocationRequired {
283 | get {
284 | return ResourceManager.GetString("SoapAddressLocationRequired", resourceCulture);
285 | }
286 | }
287 |
288 | ///
289 | /// Looks up a localized string similar to Unable to import API from WSDL..
290 | ///
291 | internal static string UnableToImportApiFromWsdl {
292 | get {
293 | return ResourceManager.GetString("UnableToImportApiFromWsdl", resourceCulture);
294 | }
295 | }
296 |
297 | ///
298 | /// Looks up a localized string similar to Unable to parse WSDL..
299 | ///
300 | internal static string UnableToParseWsdl {
301 | get {
302 | return ResourceManager.GetString("UnableToParseWsdl", resourceCulture);
303 | }
304 | }
305 |
306 | ///
307 | /// Looks up a localized string similar to Unexpected null binding operation or null operation. Please check the WSDL document operations and bindings..
308 | ///
309 | internal static string UnexpectedNullOperationOrBinding {
310 | get {
311 | return ResourceManager.GetString("UnexpectedNullOperationOrBinding", resourceCulture);
312 | }
313 | }
314 |
315 | ///
316 | /// Looks up a localized string similar to Unknown WSDL Version: '{0}'..
317 | ///
318 | internal static string UnknownWsdlVersion {
319 | get {
320 | return ResourceManager.GetString("UnknownWsdlVersion", resourceCulture);
321 | }
322 | }
323 |
324 | ///
325 | /// Looks up a localized string similar to WSDL 2.0 currently not supported for import..
326 | ///
327 | internal static string Wsdl20CurrentlyNotSupported {
328 | get {
329 | return ResourceManager.GetString("Wsdl20CurrentlyNotSupported", resourceCulture);
330 | }
331 | }
332 |
333 | ///
334 | /// Looks up a localized string similar to WsdlVersion: '{0}' TargetNamespace: '{1}'..
335 | ///
336 | internal static string WsdlIdentification {
337 | get {
338 | return ResourceManager.GetString("WsdlIdentification", resourceCulture);
339 | }
340 | }
341 |
342 | ///
343 | /// Looks up a localized string similar to XSD Schema http://www.w3.org/2000/10/XMLSchema is not supported. Use http://www.w3.org/2001/XMLSchema instead..
344 | ///
345 | internal static string WsdlImportRuleCheckXmlSchemaNamespace {
346 | get {
347 | return ResourceManager.GetString("WsdlImportRuleCheckXmlSchemaNamespace", resourceCulture);
348 | }
349 | }
350 |
351 | ///
352 | /// Looks up a localized string similar to WSDL Import is currently not supported..
353 | ///
354 | internal static string WsdlImportRuleImportNotSupported {
355 | get {
356 | return ResourceManager.GetString("WsdlImportRuleImportNotSupported", resourceCulture);
357 | }
358 | }
359 |
360 | ///
361 | /// Looks up a localized string similar to Message '{0}' contains multiple parts..
362 | ///
363 | internal static string WsdlImportRuleSingleParts {
364 | get {
365 | return ResourceManager.GetString("WsdlImportRuleSingleParts", resourceCulture);
366 | }
367 | }
368 |
369 | ///
370 | /// Looks up a localized string similar to WSDL message '{0}' has no name attribute. The name attribute is required per WSDL 1.1 specification..
371 | ///
372 | internal static string WsdlMessageNameAttributeNotFound {
373 | get {
374 | return ResourceManager.GetString("WsdlMessageNameAttributeNotFound", resourceCulture);
375 | }
376 | }
377 |
378 | ///
379 | /// Looks up a localized string similar to Completed WSDL verification. WSDL is considered valid..
380 | ///
381 | internal static string WsdlPrecheckComplete {
382 | get {
383 | return ResourceManager.GetString("WsdlPrecheckComplete", resourceCulture);
384 | }
385 | }
386 |
387 | ///
388 | /// Looks up a localized string similar to Failed WSDL verification..
389 | ///
390 | internal static string WsdlPrecheckFailed {
391 | get {
392 | return ResourceManager.GetString("WsdlPrecheckFailed", resourceCulture);
393 | }
394 | }
395 |
396 | ///
397 | /// Looks up a localized string similar to Location: '{0}' TargetNamespace: '{1}'..
398 | ///
399 | internal static string XsdImport {
400 | get {
401 | return ResourceManager.GetString("XsdImport", resourceCulture);
402 | }
403 | }
404 |
405 | ///
406 | /// Looks up a localized string similar to FROM: '{0}' BEGIN.
407 | ///
408 | internal static string XsdImportBegin {
409 | get {
410 | return ResourceManager.GetString("XsdImportBegin", resourceCulture);
411 | }
412 | }
413 |
414 | ///
415 | /// Looks up a localized string similar to FROM: '{0}' END.
416 | ///
417 | internal static string XsdImportEnd {
418 | get {
419 | return ResourceManager.GetString("XsdImportEnd", resourceCulture);
420 | }
421 | }
422 |
423 | ///
424 | /// Looks up a localized string similar to Location '{0}' cannot be resolved. Cannot resolve WSDL Imports that use relative URLs..
425 | ///
426 | internal static string XsdImportFailure {
427 | get {
428 | return ResourceManager.GetString("XsdImportFailure", resourceCulture);
429 | }
430 | }
431 |
432 | ///
433 | /// Looks up a localized string similar to Found '{0}' imports..
434 | ///
435 | internal static string XsdImportsFound {
436 | get {
437 | return ResourceManager.GetString("XsdImportsFound", resourceCulture);
438 | }
439 | }
440 | }
441 | }
442 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.WsdlProcessor.Common/CommonResources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Binding '{0}' not found.
122 |
123 |
124 | Could not resolve type '{0}'.
125 |
126 |
127 | Could not retrieve import from '{0}'. The request failed with error '{1}' and message '{2}'.
128 |
129 |
130 | Could not retrieve import from '{0}'. The request response code was '{1}' and parsing the response content failed with '{2}' and message '{3}'.
131 |
132 |
133 | Cannot resolve referenced input message '{0}'.
134 |
135 |
136 | Interface '{0}' not found.
137 |
138 |
139 | The provided schema '{0}' is invalid and cannot be parsed.
140 |
141 |
142 | Loaded '{0}' bindings.
143 |
144 |
145 | Loaded '{0}' interfaces.
146 |
147 |
148 | Loaded '{0}' messages.
149 |
150 |
151 | No schemas found.
152 |
153 |
154 | Target Namespace: '{0}'.
155 |
156 |
157 | Loaded '{0}' schemas.
158 |
159 |
160 | Loaded '{0}' services.
161 |
162 |
163 | Loaded '{0}' types.
164 |
165 |
166 | No interfaces found.
167 |
168 |
169 | Notification Operation '{0}' is not supported. Only Request-response and Solicit-response Operations are supported.
170 |
171 |
172 | One-way Operation '{0}' is not supported. Only Request-response and Solicit-response Operations are supported.
173 |
174 |
175 | Unable to generate unique resource identifiers for operations, both operation names and SOAP actions conflict. Please modify the WSDL document to avoid redundant operation names, including redundant use of empty string.
176 |
177 |
178 | Cannot resolve referenced output message '{0}'.
179 |
180 |
181 | Completed parsing XML.
182 |
183 |
184 | Started parsing XML.
185 |
186 |
187 | Element named '{0}' has a recursive definition. Recursive types are not supported.
188 |
189 |
190 | Schemas only allow Imports or Includes.
191 |
192 |
193 | A soap:address element with location attribute is required in the wsdl:port element named '{0}' of the WSDL document.
194 |
195 |
196 | Unable to import API from WSDL.
197 |
198 |
199 | Unable to parse WSDL.
200 |
201 |
202 | Unexpected null binding operation or null operation. Please check the WSDL document operations and bindings.
203 |
204 |
205 | Unknown WSDL Version: '{0}'.
206 |
207 |
208 | WSDL 2.0 currently not supported for import.
209 |
210 |
211 | WsdlVersion: '{0}' TargetNamespace: '{1}'.
212 |
213 |
214 | XSD Schema http://www.w3.org/2000/10/XMLSchema is not supported. Use http://www.w3.org/2001/XMLSchema instead.
215 |
216 |
217 | WSDL Import is currently not supported.
218 |
219 |
220 | Message '{0}' contains multiple parts.
221 |
222 |
223 | WSDL message '{0}' has no name attribute. The name attribute is required per WSDL 1.1 specification.
224 |
225 |
226 | Completed WSDL verification. WSDL is considered valid.
227 |
228 |
229 | Failed WSDL verification.
230 |
231 |
232 | Location: '{0}' TargetNamespace: '{1}'.
233 |
234 |
235 | FROM: '{0}' BEGIN
236 |
237 |
238 | FROM: '{0}' END
239 |
240 |
241 | Location '{0}' cannot be resolved. Cannot resolve WSDL Imports that use relative URLs.
242 |
243 |
244 | Found '{0}' imports.
245 |
246 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.WsdlProcessor.Common/DocumentParsingException.cs:
--------------------------------------------------------------------------------
1 | // --------------------------------------------------------------------------
2 | //
3 | // Copyright (c) Microsoft Corporation. All rights reserved.
4 | //
5 | // --------------------------------------------------------------------------
6 |
7 | namespace Microsoft.Azure.ApiManagement.WsdlProcessor.Common
8 | {
9 | using System;
10 |
11 | [Serializable]
12 | public class DocumentParsingException : Exception
13 | {
14 | public DocumentParsingException(string message) : base(message)
15 | {
16 | }
17 |
18 | public DocumentParsingException(string message, string report) : base(message)
19 | {
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.WsdlProcessor.Common/Microsoft.Azure.ApiManagement.WsdlProcessor.Common.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net9.0
5 |
6 |
7 |
8 |
9 | True
10 | True
11 | CommonResources.resx
12 |
13 |
14 |
15 |
16 |
17 | ResXFileCodeGenerator
18 | CommonResources.Designer.cs
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.WsdlProcessor.Common/WsdlDocument.cs:
--------------------------------------------------------------------------------
1 | // --------------------------------------------------------------------------
2 | //
3 | // Copyright (c) Microsoft Corporation. All rights reserved.
4 | //
5 | // --------------------------------------------------------------------------
6 | using Microsoft.Azure.ApiManagement.Common;
7 | using System;
8 | using System.Collections.Generic;
9 | using System.IO;
10 | using System.Linq;
11 | using System.Net.Http;
12 | using System.Threading.Tasks;
13 | using System.Xml;
14 | using System.Xml.Linq;
15 | using System.Xml.Schema;
16 |
17 | namespace Microsoft.Azure.ApiManagement.WsdlProcessor.Common
18 | {
19 | // WS-I Basic Profile 1.1 : use SOAP 1.1, WSDL 1.1 and UDDI 2.0
20 | // WS-I Basic Profile 1.2 (9th Nov, 2010) specifies the usage of SOAP 1.1, WSDL 1.1, UDDI 2.0, WS-Addressing 1.0 and MTOM
21 | // WS-I Basic Profile 2.0 (9th Nov, 2010) specifies the usage of SOAP 1.2, WSDL 1.1, UDDI 2.0, WS-Addressing and MTOM.
22 | // http://www.w3.org/2003/06/soap11-soap12.html
23 |
24 | public enum WsdlVersionLiteral
25 | {
26 | Wsdl11,
27 | Wsdl20 // Almost never used and currently not supported
28 | }
29 |
30 | public class WsdlDocument
31 | {
32 | public const string Wsdl11Namespace = "http://schemas.xmlsoap.org/wsdl/";
33 |
34 | public const string Wsdl20Namespace = "http://www.w3.org/ns/wsdl";
35 |
36 | public const string DefaultPrefix = "MS";
37 |
38 | //public IList RootAttributes { get; set; }
39 |
40 | public static XNamespace WsdlSoap12Namespace = XNamespace.Get("http://schemas.xmlsoap.org/wsdl/soap12/");
41 |
42 | public static XNamespace WsdlSoap11Namespace = XNamespace.Get("http://schemas.xmlsoap.org/wsdl/soap/");
43 |
44 | public static XNamespace WsAddressingWsdlNamespace = XNamespace.Get("http://www.w3.org/2006/05/addressing/wsdl");
45 |
46 | public static XNamespace WsAddressingNamespace = XNamespace.Get("http://www.w3.org/2006/05/addressing");
47 |
48 | public static XNamespace XsdSchemaNamespace = XNamespace.Get("http://www.w3.org/2001/XMLSchema");
49 |
50 | public static XNamespace XsdSchemaInstanceNamespace = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
51 |
52 | public static string[] XsdTypes = new string[] { "anyURI", "base64Binary", "boolean", "date", "dateTime", "decimal", "double", "duration", "float", "hexBinary", "gDay", "gMonth", "gMonthDay", "gYear", "gYearMonth", "NOTATION", "QName", "string", "time", "integer" };
53 |
54 | public XNamespace TargetNamespace { get; set; }
55 |
56 | public WsdlVersionLiteral WsdlVersion { get; set; }
57 |
58 | public XNamespace WsdlNamespace
59 | {
60 | get
61 | {
62 | return this.WsdlVersion == WsdlVersionLiteral.Wsdl11 ? Wsdl11Namespace : Wsdl20Namespace;
63 | }
64 | }
65 |
66 | public Dictionary Schemas { get; set; }
67 |
68 | public Dictionary> Imports { get; set; }
69 |
70 | readonly ILog logger;
71 |
72 | public WsdlDocument(ILog logger)
73 | {
74 | this.WsdlVersion = WsdlVersionLiteral.Wsdl11;
75 | this.logger = logger;
76 | }
77 |
78 | private static XNamespace GetTargetNamespace(XElement element)
79 | {
80 | XNamespace targetNamespace = XNamespace.None;
81 | XAttribute attr = element.Attribute("targetNamespace");
82 |
83 | if (attr != null)
84 | {
85 | targetNamespace = XNamespace.Get(attr.Value);
86 | }
87 |
88 | return targetNamespace;
89 | }
90 |
91 | ///
92 | /// Loads a WSDL Document from an .
93 | ///
94 | ///
95 | /// The document is not verified for support and may result in unhandled exceptions.
96 | /// Use of this method is preferred for trusted documents that have already been verified
97 | /// and do not require further verification such as documents already saved.
98 | ///
99 | /// The containing the WSDL.
100 | /// A logger for parsing events.
101 | /// A UNC Path about schemaLocations.
102 | public static async Task LoadAsync(XElement documentElement, ILog logger)
103 | {
104 | var doc = new WsdlDocument(logger)
105 | {
106 | WsdlVersion = DetermineVersion(documentElement.Name.Namespace),
107 |
108 | TargetNamespace = GetTargetNamespace(documentElement),
109 |
110 | Imports = new Dictionary>()
111 | };
112 |
113 | logger.Informational("WsdlIdentification", string.Format(
114 | CommonResources.WsdlIdentification,
115 | doc.WsdlVersion,
116 | doc.TargetNamespace.NamespaceName));
117 |
118 | await ProcessWsdlImports(doc, documentElement, logger);
119 |
120 | //doc.RootAttributes = documentElement.Attributes().Where(a => a.ToString().Contains("xmlns:")).ToList();
121 |
122 | XElement types = documentElement.Element(doc.WsdlNamespace + "types");
123 |
124 | if (types != null)
125 | {
126 | ILookup targetNamespaces = types.Elements(XsdSchemaNamespace + "schema")
127 | .ToLookup(
128 | k =>
129 | {
130 | XNamespace key = GetTargetNamespace(k);
131 | logger.Informational("LoadedSchema", string.Format(
132 | CommonResources.LoadedSchema,
133 | key.NamespaceName));
134 | return key;
135 | },
136 | v => v);
137 |
138 | // Merge duplicate schemas
139 | doc.Schemas = targetNamespaces.Select(s =>
140 | {
141 | XElement schema = s.First();
142 | MergeSchemas(schema, s.Skip(1).ToList());
143 | return new { key = s.Key, value = schema };
144 | }).ToDictionary(k => k.key, v => v.value);
145 |
146 | await ProcessXsdImportsIncludes(doc, logger);
147 |
148 | logger.Informational("LoadedSchemas", string.Format(CommonResources.LoadedSchemas, doc.Schemas.Count));
149 | }
150 | else
151 | {
152 | doc.Schemas = new Dictionary();
153 | logger.Warning("LoadedSchemas", CommonResources.LoadedNoSchemas);
154 | }
155 |
156 | types.Elements().Remove();
157 |
158 | foreach (var schema in doc.Schemas)
159 | {
160 | //if (!types.Elements(XsdSchemaNamespace + "schema").Any(i => i.ToString().Equals(schema.Value.ToString(), StringComparison.InvariantCultureIgnoreCase) || schema.Key.NamespaceName.Equals(i.Attribute("targetNamespace")?.Value)))
161 | //{
162 | types.Add(schema.Value);
163 | //}
164 | }
165 |
166 | //Adding imports to each schema
167 | foreach (var schema in types.Elements(XsdSchemaNamespace + "schema").Where(e => e.Attribute("targetNamespace") != null))
168 | {
169 | if (doc.Imports.TryGetValue(schema.Attribute("targetNamespace")?.Value, out var imports))
170 | {
171 | foreach (var item in imports)
172 | {
173 | schema.AddFirst(new XElement(XsdSchemaNamespace + "import", new XAttribute("namespace", item)));
174 | }
175 | }
176 | }
177 |
178 | //Removing third party elements from documentElement
179 | var listToRemove = new List();
180 |
181 | var allowedPrefixes = documentElement
182 | .Attributes()
183 | .Where(a => a.ToString().Contains("xmlns:"))
184 | .Select(a => a.Name.LocalName)
185 | .ToHashSet();
186 |
187 | documentElement.Elements().Where(e => !e.Name.LocalName.Equals("types")).DescendantsAndSelf().
188 | Where(x => !x.Name.NamespaceName.Equals(Wsdl11Namespace)
189 | && !x.Name.NamespaceName.Equals(XsdSchemaNamespace.NamespaceName)
190 | && !allowedPrefixes.Contains(x.GetPrefixOfNamespace(x.Name.Namespace)))
191 | .ToList()
192 | .ForEach(i => listToRemove.Add(i));
193 |
194 | //Another approach to remove third party elements is with Schema Validation.
195 | listToRemove.ForEach(i => i.Remove());
196 | }
197 |
198 | ///
199 | /// Merges all wsdl:imports in parent WSDL.
200 | ///
201 | ///
202 | ///
203 | ///
204 | ///
205 | private static async Task ProcessWsdlImports(WsdlDocument doc, XElement documentElement, ILog logger)
206 | {
207 | var wsdlImports = documentElement.Elements(doc.WsdlNamespace + "import")
208 | .Select(e => new
209 | {
210 | Location = e.Attribute("location").Value,
211 | Namespace = e.Attribute("namespace")?.Value
212 | })
213 | .ToHashSet();
214 | documentElement.Elements(doc.WsdlNamespace + "import").Remove();
215 | //var rootAttributes = documentElement.Attributes().Where(a => a.ToString().Contains("xmlns:")).Select(a => a.ToString().Split('=')[0]).ToHashSet();
216 | var attributesToAdd = new List();
217 | var elementsToAdd = new List();
218 |
219 | while (wsdlImports.Count > 0)
220 | {
221 | var import = wsdlImports.First();
222 | wsdlImports.Remove(import);
223 | //TODO: Add log messages
224 | var wsdlText = await GetStringDocumentFromUri(logger, import.Location);
225 |
226 | var importXDocument = XDocument.Parse(wsdlText);
227 | var xDocument = importXDocument.Root;
228 | var elements = xDocument.Elements().Reverse();
229 |
230 | //Modify the elements before adding them to WSDL parent
231 | AddXmlnsAndChangePrefixReferenced(documentElement, elements, xDocument.Attributes().
232 | Where(a => a.ToString().Contains("xmlns:")).ToDictionary(a => a.Value, a => a.Name.LocalName));
233 |
234 | elementsToAdd.AddRange(elements);
235 | //We need to check for new wsdl:imports
236 | var newImports = xDocument.Elements(doc.WsdlNamespace + "import")
237 | .Select(e => new
238 | {
239 | Location = e.Attribute("location").Value,
240 | Namespace = e.Attribute("namespace")?.Value
241 | })
242 | .ToHashSet();
243 | wsdlImports.Union(newImports);
244 | }
245 |
246 | elementsToAdd.ForEach(i => documentElement.AddFirst(i));
247 | ChangeElementsToParentTargetNamespace(doc, documentElement);
248 | }
249 |
250 | ///
251 | /// Process all XSD Imports and Includes
252 | ///
253 | /// doc.Schemas where all the imports are added
254 | ///
255 | ///
256 | ///
257 | private static async Task ProcessXsdImportsIncludes(WsdlDocument doc, ILog logger)
258 | {
259 | if (doc.Schemas == null)
260 | {
261 | return;
262 | }
263 | var schemaNames = new HashSet();
264 | // Walk the schemas looking for imports of other schemas
265 | var schemasToProcess = doc.Schemas
266 | .SelectMany(e => e.Value.Elements(XsdSchemaNamespace + "import"))
267 | .Where(e => e != null && e.Attribute("schemaLocation") != null)
268 | .Select(i => new
269 | {
270 | TargetNamespace = i.Attribute("namespace")?.Value,
271 | SchemaLocation = i.Attribute("schemaLocation")?.Value,
272 | Type = "import",
273 | SchemaDirectory = Directory.GetCurrentDirectory()
274 | })
275 | .ToList();
276 |
277 | //Adding includes in
278 | schemasToProcess.AddRange(doc.Schemas
279 | .SelectMany(e => e.Value.Elements(XsdSchemaNamespace + "include"))
280 | .Where(e => e != null && e.Attribute("schemaLocation") != null)
281 | .Select(i => new
282 | {
283 | TargetNamespace = i.Parent.Attribute("namespace")?.Value,
284 | SchemaLocation = i.Attribute("schemaLocation")?.Value,
285 | Type = "include",
286 | SchemaDirectory = Directory.GetCurrentDirectory()
287 | })
288 | .ToList());
289 | //Includes and imports removed from schemas
290 |
291 | schemasToProcess.ForEach(i => schemaNames.Add(i.SchemaLocation));
292 |
293 | foreach (var item in doc.Schemas)
294 | {
295 | item.Value.Elements(XsdSchemaNamespace + "include").Remove();
296 | item.Value.Elements(XsdSchemaNamespace + "import").Remove();
297 | }
298 | // Resolve the schemas and add to existing ones
299 | while (schemasToProcess.Count > 0)
300 | {
301 | var import = schemasToProcess.First();
302 |
303 | var realSchemaDirectory = import.SchemaLocation != string.Empty
304 | ? import.SchemaLocation
305 | : Path.GetDirectoryName(Path.GetFullPath(Path.Join(import.SchemaDirectory, import.SchemaLocation)));
306 |
307 | schemasToProcess.Remove(import);
308 | XmlSchema xmlSchema;
309 |
310 | logger.Informational("XsdImportInclude", string.Format(
311 | CommonResources.XsdImport,
312 | import.SchemaLocation,
313 | import.TargetNamespace));
314 |
315 | string schemaText = string.Empty;
316 |
317 | schemaText = await GetStringDocumentFromUri(logger, import.SchemaLocation);
318 |
319 | xmlSchema = GetXmlSchema(schemaText, logger);
320 | var includesToRemove = new List();
321 | var importsToAdd = new HashSet();
322 |
323 | foreach (XmlSchemaExternal item in xmlSchema.Includes)
324 | {
325 | if (item is XmlSchemaImport || item is XmlSchemaInclude)
326 | {
327 | var schemaLocation = item.SchemaLocation;
328 |
329 | if (!schemaNames.Contains(item.SchemaLocation))
330 | {
331 | var xmlTargetNamespace = xmlSchema.TargetNamespace;
332 | string itemType;
333 |
334 | if (item is XmlSchemaImport importItem)
335 | {
336 | logger.Informational("import");
337 | itemType = "import";
338 | xmlTargetNamespace = importItem.Namespace;
339 | }
340 | else
341 | {
342 | logger.Informational("include");
343 | itemType = "include";
344 | }
345 |
346 | //All new imports are added
347 | importsToAdd.Add(xmlTargetNamespace);
348 | schemaNames.Add(item.SchemaLocation);
349 |
350 | var newSchemaToProcess = new
351 | {
352 | TargetNamespace = xmlTargetNamespace,
353 | SchemaLocation = schemaLocation,
354 | Type = itemType,
355 | SchemaDirectory = realSchemaDirectory
356 | };
357 |
358 | schemasToProcess.Add(newSchemaToProcess);
359 | logger.Informational(
360 | @$"SchemaLocation: {newSchemaToProcess.SchemaLocation},
361 | SchemaDirectory: {newSchemaToProcess.SchemaDirectory}");
362 | }
363 |
364 | if (item is XmlSchemaImport)
365 | {
366 | item.SchemaLocation = null;
367 | }
368 |
369 | includesToRemove.Add(item);
370 | }
371 | else
372 | {
373 | throw new WsdlDocumentException(CommonResources.SchemaOnlyAllowsIncludeOrImport);
374 | }
375 | }
376 |
377 | includesToRemove.ForEach(x => xmlSchema.Includes.Remove(x));
378 |
379 | var sw = new StringWriter();
380 | xmlSchema.Write(sw);
381 | schemaText = sw.ToString();
382 |
383 | var schemaElement = XElement.Parse(schemaText, LoadOptions.SetLineInfo);
384 | //BEGIN track schema comment
385 | schemaElement.AddFirst(new XComment(string.Format(CommonResources.XsdImportBegin, import.SchemaLocation)));
386 | schemaElement.Add(new XComment(string.Format(CommonResources.XsdImportEnd, import.SchemaLocation)));
387 | //END track schema comment
388 | XNamespace targetNamespace = import.TargetNamespace ?? GetTargetNamespace(schemaElement);
389 |
390 | if (doc.Schemas.ContainsKey(targetNamespace))
391 | {
392 | XElement existingSchema = doc.Schemas[targetNamespace];
393 | var existingSchemaXmlns = existingSchema.Attribute("xmlns")?.Value;
394 | var schemaelementXmlns = schemaElement.Attribute("xmlns")?.Value;
395 |
396 | if (existingSchemaXmlns != null && schemaelementXmlns != null && !existingSchemaXmlns.Equals(schemaelementXmlns))
397 | {
398 | if (existingSchema.HasElements)
399 | throw new WsdlDocumentException(
400 | $"The xmlns attribute is not the same between schemas with targetNamespace {targetNamespace.NamespaceName}");
401 |
402 | existingSchema.Parent.Element(existingSchema.Name).Remove();
403 | doc.Schemas[targetNamespace] = schemaElement;
404 | }
405 | else
406 | {
407 | MergeSchemas(existingSchema, new List() { schemaElement });
408 | }
409 | }
410 | else
411 | {
412 | doc.Schemas.Add(targetNamespace, schemaElement);
413 |
414 | }
415 | importsToAdd.Remove(targetNamespace.NamespaceName);
416 |
417 | if (doc.Imports.ContainsKey(targetNamespace))
418 | {
419 | doc.Imports[targetNamespace].UnionWith(importsToAdd);
420 | }
421 | else
422 | {
423 | doc.Imports[targetNamespace] = importsToAdd;
424 | }
425 | }
426 | }
427 |
428 | ///
429 | /// Get string document from uri (URL or path)
430 | ///
431 | ///
432 | ///
433 | /// string document
434 | private static async Task GetStringDocumentFromUri(ILog logger, string location)
435 | {
436 | string documentText;
437 | //We need to check if is URL or a File location
438 | var result = Uri.TryCreate(location, UriKind.Absolute, out var uriResult)
439 | && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
440 |
441 | if (result)
442 | {
443 | var clientHandler = new HttpClientHandler();
444 | clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
445 | HttpResponseMessage response = null;
446 |
447 | using (var httpClient = new HttpClient(clientHandler))
448 | {
449 | var uri = new Uri(location, UriKind.RelativeOrAbsolute);
450 |
451 | try
452 | {
453 | response = await httpClient.GetAsync(uri);
454 |
455 | documentText = await response.Content.ReadAsStringAsync();
456 |
457 | if (response.StatusCode != System.Net.HttpStatusCode.OK)
458 | {
459 | // NOTE(daviburg): when the status code was failed, the return string if one is an error message rather than the schema.
460 | logger.Error("FailedToImport", string.Format(
461 | CommonResources.FailedToImport,
462 | uri.OriginalString,
463 | response.StatusCode,
464 | documentText));
465 |
466 | throw new Exception("Failed to import schema from external url");
467 | }
468 | }
469 | catch (InvalidOperationException ex)
470 | {
471 | // NOTE(daviburg): this can happen when the content type header charset value of the response is invalid.
472 | logger.Error("FailedToImport", string.Format(
473 | CommonResources.FailedToParseImportedSchemaResponse,
474 | uri.OriginalString,
475 | response.StatusCode,
476 | nameof(InvalidOperationException),
477 | ex.StackTrace));
478 | throw;
479 | }
480 | catch (HttpRequestException ex)
481 | {
482 | logger.Error("FailedToImport from external url", string.Format(
483 | CommonResources.FailedToImport,
484 | uri.OriginalString,
485 | nameof(HttpRequestException),
486 | ex.StackTrace));
487 | throw;
488 | }
489 | catch (Exception ex)
490 | {
491 | logger.Error("FailedToImport from external url", string.Format(
492 | CommonResources.FailedToImport,
493 | uri.OriginalString,
494 | nameof(Exception),
495 | ex.StackTrace));
496 | throw;
497 | }
498 | }
499 | }
500 | else
501 | {
502 | var importLocation = Path.IsPathRooted(location) ? location : Path.Join(Directory.GetCurrentDirectory(), location);
503 | documentText = File.ReadAllText(importLocation);
504 | }
505 |
506 | return documentText;
507 | }
508 |
509 | ///
510 | /// Add namespaces to documentElement.
511 | /// Then, It changes newElements attributes that have prefixes.
512 | ///
513 | /// XElement where the method will add New namespaces
514 | /// List of XElements where attributes value are going to change if have prefixes
515 | /// Namespaces of the newElements
516 | private static void AddXmlnsAndChangePrefixReferenced(
517 | XElement documentElement,
518 | IEnumerable newElements,
519 | Dictionary namespaces)
520 | {
521 | var parentNamespaces = documentElement
522 | .Attributes()
523 | .Where(a => a.ToString()
524 | .Contains("xmlns:"))
525 | .Select(a => new
526 | {
527 | Prefix = a.Name.LocalName,
528 | Namespace = a.Value
529 | }).ToDictionary(a => a.Namespace, a => a.Prefix);
530 |
531 | foreach (var item in namespaces)
532 | {
533 | //string prefix = string.Empty;
534 | parentNamespaces.TryGetValue(item.Key, out string prefix);
535 |
536 | if (prefix == null)
537 | {
538 | prefix = GenerateNewNamespace(documentElement, parentNamespaces, item);
539 | }
540 |
541 | //Modify attributes from elements with the same prefix
542 | var prefixValue = item.Value + ":";
543 |
544 | foreach (var element in newElements.DescendantsAndSelf())
545 | {
546 | //Go through all attributes and modify if they have the prefix
547 | var attributes = element
548 | .Attributes()
549 | .Where(e => e.Value.Contains(prefixValue));
550 |
551 | foreach (var attribute in attributes)
552 | {
553 | if (attribute.Value.Count(i => i == ':') == 1
554 | && !(Uri.TryCreate(attribute.Value, UriKind.Absolute, out var uriResult)
555 | && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps)))
556 | {
557 | var splitValue = attribute.Value.Split(':');
558 | attribute.Value = prefix + ":" + splitValue[1];
559 | }
560 | }
561 | }
562 | }
563 | }
564 |
565 | ///
566 | /// It generates a new xmlns:prefix and add it to documentElement
567 | ///
568 | /// XElement to add new xmlns
569 | /// All namespaces of XElement
570 | /// Namespace, prefix KeyValuepair
571 | ///
572 | private static string GenerateNewNamespace(
573 | XElement documentElement,
574 | Dictionary parentNamespaces,
575 | KeyValuePair item)
576 | {
577 | var newNamespaces = parentNamespaces.Values.Where(v => v.Contains(WsdlDocument.DefaultPrefix));
578 | var initialValue = 1;
579 |
580 | if (newNamespaces.Any())
581 | {
582 | initialValue = newNamespaces.Select(i => i.Substring(2)).Max(i => int.Parse(i)) + 1;
583 | }
584 |
585 | var newPrefix = DefaultPrefix + initialValue.ToString();
586 | documentElement.Add(new XAttribute(XNamespace.Xmlns + newPrefix, item.Key));
587 | parentNamespaces.Add(item.Key, newPrefix);
588 |
589 | return newPrefix;
590 | }
591 |
592 | ///
593 | /// Change WSDL elements to Parent targetNamespace/Prefix
594 | ///
595 | ///
596 | /// Wsdl merged
597 | private static void ChangeElementsToParentTargetNamespace(WsdlDocument doc, XElement documentElement)
598 | {
599 | //Searching for wsdl:portType and getting all the inputs, outputs and faults
600 | var prefixParentNamespace = documentElement.GetPrefixOfNamespace(documentElement.Attribute("targetNamespace").Value);
601 | var operationChildren = documentElement
602 | .Elements(doc.WsdlNamespace + "portType")
603 | .Elements(doc.WsdlNamespace + "operation")
604 | .Elements()
605 | .Where(e => e.Name.LocalName.Equals("input")
606 | || e.Name.LocalName.Equals("output")
607 | || e.Name.LocalName.Equals("fault"));
608 |
609 | foreach (var item in operationChildren)
610 | {
611 | var attribute = item.Attribute("message");
612 |
613 | if (attribute != null
614 | && attribute.Value.Count(i => i == ':') == 1
615 | && !(Uri.TryCreate(attribute.Value, UriKind.Absolute, out var uriResult)
616 | && (uriResult.Scheme == Uri.UriSchemeHttp
617 | || uriResult.Scheme == Uri.UriSchemeHttps)))
618 | {
619 | var splitValue = attribute.Value.Split(':');
620 | attribute.Value = prefixParentNamespace + ":" + splitValue[1];
621 | }
622 | }
623 |
624 | //Searching for binding/type
625 | var bindingsType = documentElement.Elements(doc.WsdlNamespace + "binding");
626 |
627 | foreach (var item in bindingsType)
628 | {
629 | var attribute = item.Attribute("type");
630 |
631 | if (attribute != null
632 | && attribute.Value.Count(i => i == ':') == 1
633 | && !(Uri.TryCreate(attribute.Value, UriKind.Absolute, out var uriResult)
634 | && (uriResult.Scheme == Uri.UriSchemeHttp
635 | || uriResult.Scheme == Uri.UriSchemeHttps)))
636 | {
637 | var splitValue = attribute.Value.Split(':');
638 | attribute.Value = prefixParentNamespace + ":" + splitValue[1];
639 | }
640 | }
641 | }
642 |
643 | private static void MergeSchemas(XElement schema, IList schemas)
644 | {
645 | foreach (XElement dupSchema in schemas)
646 | {
647 | foreach (XAttribute attribute in dupSchema.Attributes())
648 | {
649 | var schemaAttribute = schema.Attribute(attribute.Name);
650 |
651 | if (schemaAttribute == null)
652 | {
653 | schema.Add(new XAttribute(attribute.Name, attribute.Value));
654 | }
655 | else
656 | {
657 | if (schemaAttribute.Name.LocalName.Equals(attribute.Name.LocalName) &&
658 | !schemaAttribute.Value.Equals(attribute.Value))
659 | {
660 | AddXmlnsAndChangePrefixReferenced(
661 | schema,
662 | dupSchema.Elements(),
663 | new Dictionary()
664 | {
665 | { attribute.Value, attribute.Name.LocalName }
666 | });
667 | }
668 | }
669 | }
670 | schema.Add(dupSchema.Elements());
671 | }
672 | }
673 |
674 | private static WsdlVersionLiteral DetermineVersion(XNamespace wsdlNS)
675 | {
676 | return wsdlNS.NamespaceName switch
677 | {
678 | Wsdl11Namespace => WsdlVersionLiteral.Wsdl11,
679 | Wsdl20Namespace => WsdlVersionLiteral.Wsdl20,
680 | _ => throw new DocumentParsingException(string.Format(CommonResources.UnknownWsdlVersion, wsdlNS.NamespaceName))
681 | };
682 | }
683 |
684 | private static XmlSchema GetXmlSchema(string xmlSchema, ILog logger)
685 | {
686 | try
687 | {
688 | if (File.Exists(xmlSchema))
689 | {
690 | xmlSchema = new StreamReader(xmlSchema).ReadToEnd();
691 | }
692 |
693 | using (var doc = new StringReader(xmlSchema))
694 | {
695 | var result = XmlSchema.Read(doc, null);
696 | return result;
697 | }
698 | }
699 | catch (XmlException ex)
700 | {
701 | logger.Error("GetXmlSchema XmlException", ex);
702 | throw;
703 | }
704 | catch (XmlSchemaException ex)
705 | {
706 | logger.Error("GetXmlSchema XmlSchemaException", ex);
707 | throw;
708 | }
709 | }
710 | }
711 | }
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.WsdlProcessor.Common/WsdlDocumentException.cs:
--------------------------------------------------------------------------------
1 | // --------------------------------------------------------------------------
2 | //
3 | // Copyright (c) Microsoft Corporation. All rights reserved.
4 | //
5 | // --------------------------------------------------------------------------
6 | using System;
7 |
8 | namespace Microsoft.Azure.ApiManagement.WsdlProcessor.Common
9 | {
10 | [Serializable]
11 | public class WsdlDocumentException : Exception
12 | {
13 | public WsdlDocumentException(string message) : base(message)
14 | {
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.XmlSchemaProcessor.App/Microsoft.Azure.ApiManagement.XmlSchemaProcessor.App.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net9.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.XmlSchemaProcessor.App/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Azure.ApiManagement.XmlSchemaProcessor.Common;
2 | using System.Threading.Tasks;
3 |
4 | namespace Microsoft.Azure.ApiManagement.XmlSchemaProcessor.App
5 | {
6 | class Program
7 | {
8 | static async Task Main(string[] args)
9 | {
10 | var log = new ConsoleLog();
11 |
12 | if (args.Length == 2)
13 | {
14 | var xsdDirectory = args[0];
15 | var outputDirectory = args[1];
16 | await XmlSchemaDocument.LoadAsync(xsdDirectory, log, outputDirectory);
17 | }
18 | else
19 | {
20 | log.Error("XSD Directory path and output directory should be provided as a parameter of the tool.");
21 | }
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.XmlSchemaProcessor.Common/Microsoft.Azure.ApiManagement.XmlSchemaProcessor.Common.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net9.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.XmlSchemaProcessor.Common/XmlSchemaDocument.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Text.RegularExpressions;
8 | using System.Threading.Tasks;
9 | using System.Xml;
10 | using System.Xml.Schema;
11 | using Microsoft.Azure.ApiManagement.Common;
12 |
13 | namespace Microsoft.Azure.ApiManagement.XmlSchemaProcessor.Common
14 | {
15 | public class XmlSchemaDocument
16 | {
17 | private const string SchemaPath = "/schemas/";
18 | //private const string NewDirectory = "newdirectory";
19 | private static Dictionary Schemas { get; set; }
20 |
21 | private static Dictionary PathXmlSchemaPair { get; set; }
22 |
23 | private static Dictionary> PathOrderListSchemas { get; set; }
24 |
25 | private static string DirectoryPath { get; set; }
26 |
27 | public static async Task LoadAsync(string directoryPath, ILog logger, string outputDirectory)
28 | {
29 | directoryPath = Path.IsPathRooted(directoryPath) ? directoryPath : Path.Join(Directory.GetCurrentDirectory(), directoryPath);
30 | DirectoryPath = directoryPath;
31 | //outputDirectory = outputDirectory ?? NewDirectory;
32 | outputDirectory = Path.IsPathRooted(outputDirectory) ? outputDirectory : Path.Join(DirectoryPath, outputDirectory);
33 | Schemas = new Dictionary();
34 | PathXmlSchemaPair = new Dictionary();
35 | PathOrderListSchemas = new Dictionary>();
36 | logger.Informational($"Getting all xsd files from folder {directoryPath}");
37 | var schemaPaths = Directory.GetFiles(directoryPath, "*.xsd");
38 |
39 | if (!schemaPaths.Any())
40 | {
41 | logger.Error($"No xsd files in folder {directoryPath}");
42 | return;
43 | }
44 |
45 | if (Directory.Exists(outputDirectory) && Directory.GetFiles(outputDirectory).Length > 0)
46 | {
47 | logger.Error($"{outputDirectory} directory should not have files before executing the tool.");
48 | return;
49 | }
50 | else if (!Directory.Exists(outputDirectory))
51 | {
52 | Directory.CreateDirectory(outputDirectory);
53 | }
54 |
55 | logger.Informational($"Generating new names for schemas");
56 | GenerateNewNameForSchemas(schemaPaths, logger);
57 |
58 | logger.Informational($"Starting process of xsd files");
59 | await ProcessXsdImportsIncludes(schemaPaths, logger);
60 |
61 | //new xsd files
62 | logger.Informational($"Generating new files in {outputDirectory}");
63 |
64 | foreach (var xmlFile in PathXmlSchemaPair.Keys)
65 | {
66 | logger.Informational($"Generating new file for {xmlFile}");
67 | var newSchemaFile = PathXmlSchemaPair[xmlFile];
68 | var file = new FileStream(Path.Join(outputDirectory, Schemas[xmlFile] + ".xsd"),
69 | FileMode.Create,
70 | FileAccess.ReadWrite);
71 |
72 | var xwriter = new XmlTextWriter(file, new UTF8Encoding())
73 | {
74 | Formatting = System.Xml.Formatting.Indented
75 | };
76 |
77 | newSchemaFile.Write(xwriter);
78 | logger.Informational($"File generated {Path.GetFileName(file.Name)}");
79 | }
80 |
81 | var outputDictionary = new Dictionary();
82 | PathOrderListSchemas
83 | .OrderByDescending(x => x.Value.Count)
84 | .SelectMany(x => x.Value)
85 | .ToList()
86 | .ForEach(item => outputDictionary[Path.GetFileName(item)] = Schemas[item]);
87 |
88 | logger.Informational("Generating upload-plan.json file");
89 | var uploadPlan = JsonConvert.SerializeObject(outputDictionary, Newtonsoft.Json.Formatting.Indented);
90 | File.WriteAllText(Path.Join(outputDirectory, "upload-plan.json"), uploadPlan);
91 | }
92 |
93 | ///
94 | /// Process all XSD Imports and Includes
95 | ///
96 | /// doc.Schemas where all the imports are added
97 | ///
98 | ///
99 | private static async Task ProcessXsdImportsIncludes(string[] schemaPaths, ILog logger)
100 | {
101 | var visitedSchemas = new HashSet();
102 |
103 | foreach (var item in schemaPaths)
104 | {
105 | if (!visitedSchemas.Contains(item))
106 | {
107 | logger.Informational($"Processing parent {Path.GetFileName(item)} schema file.");
108 | var orderedListOfSchemas = new List();
109 |
110 | if (!(await FindOrder(item, new HashSet(), new HashSet(), orderedListOfSchemas, logger)))
111 | {
112 | throw new InvalidOperationException($"There was an error trying to process {item}");
113 | }
114 | else
115 | {
116 | PathOrderListSchemas[item] = orderedListOfSchemas;
117 | orderedListOfSchemas.ForEach(i => visitedSchemas.Add(i));
118 | }
119 | }
120 | logger.Informational($"Schema file {Path.GetFileName(item)} is already processed.");
121 | }
122 | }
123 |
124 | ///
125 | /// Fill orderedListOfSchemas keeping the independent schemas at the beginning
126 | /// and the dependent schemas at the end
127 | ///
128 | ///
129 | ///
130 | ///
131 | ///
132 | ///
133 | /// True if there is no problem processing. False if there is a circular dependency or a Redefine element in schema
134 | private async static Task FindOrder(
135 | string schemaLocation,
136 | HashSet importedNamespaces,
137 | HashSet visitedNamespaces,
138 | IList orderedListOfSchemas,
139 | ILog logger)
140 | {
141 | logger.Informational($"Processing {Path.GetFileName(schemaLocation)} schema file.");
142 |
143 | if (importedNamespaces.Contains(schemaLocation))
144 | {
145 | logger.Error($"There is a circular dependency in the xml schemas. {Path.GetFileName(schemaLocation)} is in a cycle of schema dependencies");
146 | return false;
147 | }
148 |
149 | if (visitedNamespaces.Contains(schemaLocation))
150 | {
151 | logger.Informational($"Already visited {schemaLocation}");
152 | return true;
153 | }
154 |
155 | var documentText = await GetStringDocumentFromPathAsync(schemaLocation);
156 | var xmlSchema = GetXmlSchema(documentText, logger);
157 | PathXmlSchemaPair[schemaLocation] = xmlSchema;
158 |
159 | importedNamespaces.Add(schemaLocation);
160 | visitedNamespaces.Add(schemaLocation);
161 | logger.Informational("Processing Imports and Includes");
162 |
163 | foreach (XmlSchemaExternal element in xmlSchema.Includes)
164 | {
165 | string location = string.Empty;
166 |
167 | if (element is XmlSchemaImport || element is XmlSchemaInclude)
168 | {
169 | location = Path.IsPathRooted(element.SchemaLocation) ? element.SchemaLocation : Path.Join(DirectoryPath, element.SchemaLocation);
170 | element.SchemaLocation = NormalizeWellFormedArmSchema(location, logger);
171 | }
172 | else
173 | {
174 | logger.Error($"Redefine is not allowed in the tool.");
175 | return false;
176 | }
177 |
178 | if (!(await FindOrder(location, importedNamespaces, visitedNamespaces, orderedListOfSchemas, logger)))
179 | {
180 | return false;
181 | }
182 | }
183 |
184 | orderedListOfSchemas.Add(schemaLocation);
185 | importedNamespaces.Remove(schemaLocation);
186 | logger.Informational($"End of processing {Path.GetFileName(schemaLocation)} schema file.");
187 |
188 | return true;
189 | }
190 |
191 | private static void GenerateNewNameForSchemas(string schemaPaths, ILog logger)
192 | {
193 | GenerateNewNameForSchemas(new string[] { schemaPaths }, logger);
194 | }
195 |
196 | ///
197 | /// Generates new name for schemas
198 | /// e.g. foo.xsd -> foo, foo_1.xsd -> foo-1, foo_1_2.xsd -> foo-1-2
199 | ///
200 | ///
201 | ///
202 | ///
203 | private static void GenerateNewNameForSchemas(string[] schemaPaths, ILog logger)
204 | {
205 | foreach (var item in schemaPaths)
206 | {
207 | var schemaNameWithoutExtension = Path.GetFileNameWithoutExtension(item);
208 | logger.Informational($"Generating new name for {schemaNameWithoutExtension}.xsd");
209 | var rgx = new Regex("[^a-zA-Z0-9 -]");
210 | Schemas[item] = rgx.Replace(schemaNameWithoutExtension, "-");
211 | logger.Informational($"New name for {schemaNameWithoutExtension} -> {Schemas[item]}");
212 | }
213 | }
214 |
215 | ///
216 | /// Get string document from uri (URL or path)
217 | ///
218 | ///
219 | /// string document
220 | private static async Task GetStringDocumentFromPathAsync(string location)
221 | {
222 | string documentText;
223 | var importLocation = Path.IsPathRooted(location) ? location : Path.Join(DirectoryPath, location);
224 | documentText = await File.ReadAllTextAsync(importLocation);
225 |
226 | return documentText;
227 | }
228 |
229 | ///
230 | /// Gets the new name for schemas and generates a new location for targetnamespace in Imports and Includes
231 | ///
232 | ///
233 | ///
234 | ///
235 | private static string NormalizeWellFormedArmSchema(string schema, ILog logger)
236 | {
237 | Schemas.TryGetValue(schema, out var schemaNewName);
238 |
239 | if (string.IsNullOrEmpty(schemaNewName))
240 | {
241 | logger.Warning($"No new name found for {schema}");
242 | GenerateNewNameForSchemas(schema, logger);
243 | schemaNewName = Schemas[schema];
244 | }
245 |
246 | return string.Concat(SchemaPath, schemaNewName);
247 | }
248 |
249 | private static XmlSchema GetXmlSchema(string xmlSchema, ILog logger)
250 | {
251 | try
252 | {
253 | using (var doc = new StringReader(xmlSchema))
254 | {
255 | var result = XmlSchema.Read(doc, null);
256 |
257 | if (string.IsNullOrEmpty(result.TargetNamespace))
258 | {
259 | var error = $"{xmlSchema} does not have targetNamespace attribute";
260 | logger.Error(error);
261 | throw new NullReferenceException(error);
262 | }
263 |
264 | return result;
265 | }
266 | }
267 | catch (XmlException e)
268 | {
269 | logger.Error($"{e.Message}");
270 | logger.Error($"Location {xmlSchema} contains invalid xml: {e.StackTrace}");
271 | throw;
272 | }
273 | catch (XmlSchemaException e)
274 | {
275 | logger.Error($"{e.Message}");
276 | logger.Error($"Location {xmlSchema} contains invalid xml: {e.StackTrace}");
277 | throw;
278 | }
279 | }
280 | }
281 | }
282 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.XmlSchemaProcessor.TestConsole/Microsoft.Azure.ApiManagement.XmlSchemaProcessor.TestConsole.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net9.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | Always
15 |
16 |
17 | Always
18 |
19 |
20 | Always
21 |
22 |
23 | Always
24 |
25 |
26 | Always
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.XmlSchemaProcessor.TestConsole/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Azure.ApiManagement.XmlSchemaProcessor.Common;
2 | using System.IO;
3 | using System.Threading.Tasks;
4 |
5 | namespace Microsoft.Azure.ApiManagement.XmlSchemaProcessor.TestConsole
6 | {
7 | public class Program
8 | {
9 | static async Task Main(string[] args)
10 | {
11 | var log = new ConsoleLog();
12 | var directoryPath = @"C:\proj\GMFiles\XSD with Include\GetProvideShipments";
13 | await XmlSchemaDocument.LoadAsync(directoryPath, log, Path.Combine(directoryPath, "myoutput"));
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/TestConsole/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Azure.ApiManagement.WsdlProcessor.Common;
2 | using System;
3 | using System.IO;
4 | using System.Threading.Tasks;
5 | using System.Xml.Linq;
6 |
7 | namespace TestConsole
8 | {
9 | class Program
10 | {
11 | static async Task Main(string[] args)
12 | {
13 | var log = new ConsoleLog();
14 | var wsdlfile = "API-0427";
15 | var wsdlString = File.ReadAllText(wsdlfile + ".wsdl");
16 | var xDocument = XDocument.Parse(wsdlString);
17 | await WsdlDocument.LoadAsync(xDocument.Root, log);
18 | //WsdlDocument.DumpInvalidNodes(xDocument.Root);
19 | xDocument.Root.Save(wsdlfile + "-processed.wsdl");
20 | //FileStream fs = new FileStream(@"C:\Temp\" + wsdlfile + "-processed.wsdl", FileMode.Create);
21 | //wsdlDocument.Save(XmlWriter.Create(fs, new XmlWriterSettings() { Indent = true }));
22 | //fs.Close();
23 | Console.ReadLine();
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/TestConsole/TestConsole.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net9.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Always
16 |
17 |
18 | Always
19 |
20 |
21 | Always
22 |
23 |
24 | Always
25 |
26 |
27 | Always
28 |
29 |
30 | Always
31 |
32 |
33 | Always
34 |
35 |
36 | Always
37 |
38 |
39 | Always
40 |
41 |
42 | Always
43 |
44 |
45 | Always
46 |
47 |
48 | Always
49 |
50 |
51 | Always
52 |
53 |
54 | Always
55 |
56 |
57 | Always
58 |
59 |
60 | Always
61 |
62 |
63 | Always
64 |
65 |
66 | Always
67 |
68 |
69 | Always
70 |
71 |
72 | Always
73 |
74 |
75 | Always
76 |
77 |
78 | Always
79 |
80 |
81 | Always
82 |
83 |
84 | Always
85 |
86 |
87 | Always
88 |
89 |
90 | Always
91 |
92 |
93 | Always
94 |
95 |
96 | Always
97 |
98 |
99 | Always
100 |
101 |
102 | Always
103 |
104 |
105 | Always
106 |
107 |
108 | Always
109 |
110 |
111 | Always
112 |
113 |
114 | Always
115 |
116 |
117 | Always
118 |
119 |
120 | Always
121 |
122 |
123 | Always
124 |
125 |
126 | Always
127 |
128 |
129 | Always
130 |
131 |
132 | Always
133 |
134 |
135 | Always
136 |
137 |
138 | Always
139 |
140 |
141 | Always
142 |
143 |
144 | Always
145 |
146 |
147 | Always
148 |
149 |
150 | Always
151 |
152 |
153 | Always
154 |
155 |
156 | Always
157 |
158 |
159 | Always
160 |
161 |
162 | Always
163 |
164 |
165 | Always
166 |
167 |
168 | Always
169 |
170 |
171 | Always
172 |
173 |
174 | Always
175 |
176 |
177 | Always
178 |
179 |
180 | Always
181 |
182 |
183 | Always
184 |
185 |
186 | Always
187 |
188 |
189 | Always
190 |
191 |
192 | Always
193 |
194 |
195 | Always
196 |
197 |
198 | Always
199 |
200 |
201 | Always
202 |
203 |
204 | Always
205 |
206 |
207 | Always
208 |
209 |
210 | Always
211 |
212 |
213 | Always
214 |
215 |
216 | Always
217 |
218 |
219 | Always
220 |
221 |
222 | Always
223 |
224 |
225 |
226 |
227 |
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/batchWsdlProcessor.ps1:
--------------------------------------------------------------------------------
1 | param ([Parameter(Mandatory)]$configFile, [Parameter(Mandatory)]$apimresource, [Parameter(Mandatory)]$wsdlProcessor)
2 | #$apimResource = "https://management.apim.net/subscriptions/a200340d-6b82-494d-9dbf-687ba6e33f9e/resourceGroups/devenv/providers/Microsoft.ApiManagement/service/devenv"
3 | #$configFile = ""
4 | Write-Output "Starting Azure login"
5 | az login
6 | Write-Output "Starting the process"
7 | $ErrorActionPreference = "Stop"
8 | $token = az account get-access-token | ConvertFrom-Json
9 | $bearer =$token.accessToken
10 | $headers = @{Authorization = "Bearer $bearer"}
11 |
12 | Write-Output "Reading file $configFile"
13 | $json = (Get-Content -Path $configFile -Raw) | ConvertFrom-Json
14 | $counter = 1
15 | $json.psobject.properties | ForEach-Object {
16 | $directory = $_.Value
17 | $wsdlFile = $_.Name
18 | Set-Location $directory
19 | $fileOutput = "new-" + $wsdlFile
20 | & $wsdlProcessor $wsdlFile $fileOutput
21 | $content = Get-Content -Path $fileOutput -Raw -Encoding utf8
22 | $apiName = "test" + $counter
23 | Write-Output "Api name: $apiName"
24 | $uri = "$apimResource/apis/" + $apiName + "?import=true&api-version=2021-01-01-preview"
25 | Write-Output "Calling $uri"
26 | $res = iwr -UseBasicParsing -Method Put -Headers $headers -Uri $uri -ContentType "application/json; charset=utf-8" -Body (@{ "id"="/apis/$apiName"; "name"="$apiName" ; "properties" = @{ "format" = "wsdl"; "value" = "$content"; "displayName"="$apiName"; "protocols"=@("https"); "path"="$apiName"}; } | ConvertTo-Json)
27 | if (($res.StatusCode -ne 200) -and ($res.StatusCode -ne 201) -and ($res.StatusCode -ne 202))
28 | {
29 | Throw "Request returned with HTTP code $req.StatusCode"
30 | }
31 | $counter = $counter + 1
32 | }
33 |
34 | Write-Output "Process successfully ended"
35 | #Now we upload the file
36 | #$res = iwr -UseBasicParsing -Method Put -Headers $headers -Uri $uri -ContentType "application/json; charset=utf-8" -Body (@{ "id"="/apis/test2"; "name"="test2" ; "properties" = @{ "format" = "wsdl"; "value" = "$content"; "displayName"="test1"; "protocols"=@("https"); "path"="test2"}; } | ConvertTo-Json)
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/batchXmlSchemaProcessor.ps1:
--------------------------------------------------------------------------------
1 | param ([Parameter(Mandatory)]$configFile, [Parameter(Mandatory)]$apimresource, [Parameter(Mandatory)]$xmlProcessor)
2 | #$apimResource = "https://management.apim.net/subscriptions/a200340d-6b82-494d-9dbf-687ba6e33f9e/resourceGroups/devenv/providers/Microsoft.ApiManagement/service/devenv"
3 | #$configFile = ""
4 | Write-Output "Starting Azure login"
5 | az login
6 | Write-Output "Starting the process"
7 | $ErrorActionPreference = "Stop"
8 | $token = az account get-access-token | ConvertFrom-Json
9 | $bearer =$token.accessToken
10 | $headers = @{Authorization = "Bearer $bearer"}
11 |
12 | Write-Output "Reading file $configFile"
13 | $json = (Get-Content -Path $configFile -Raw) | ConvertFrom-Json
14 | $json.psobject.properties | ForEach-Object {
15 | $inputDirectory = $_.Name
16 | $outputDirectory = $_.Value
17 | Write-Output "Input directory: $inputDirectory"
18 | Write-Output "Output directory: $outputDirectory"
19 | Set-Location $inputDirectory
20 | & $xmlProcessor $inputDirectory $outputDirectory
21 | $file = Join-Path -Path $outputDirectory -ChildPath "upload-plan.json"
22 | $jsonXml = (Get-Content -Path $file -Raw) | ConvertFrom-Json
23 |
24 | $jsonXml.psobject.properties | ForEach-Object {
25 | $childPath = $_.Value + ".xsd"
26 | $schema = Join-Path -Path $outputDirectory -ChildPath $childPath
27 | $uri = $apimresource + "/schemas/" + $_.Value + "?api-version=2021-04-01-preview"
28 | Write-Output "Reading $schema"
29 | $content = Get-Content -Path $schema -Raw -Encoding utf8
30 | Write-Output "Updating schema to $uri"
31 | $res = iwr -UseBasicParsing -Method Put -Headers $headers -Uri $uri -ContentType "application/json; charset=utf-8" `
32 | -Body (@{ `
33 | "properties" = @{ `
34 | "schemaType" = "xml"; `
35 | "value" = "$content"; `
36 | }; `
37 | } | ConvertTo-Json)
38 | if (($res.StatusCode -ne 200) -and ($res.StatusCode -ne 201) -and ($res.StatusCode -ne 202))
39 | {
40 | Throw "Request returned with HTTP code $req.StatusCode"
41 | }
42 | }
43 | }
44 |
45 | Write-Output "Process successfully ended"
46 | #Now we upload the file
47 | #$res = iwr -UseBasicParsing -Method Put -Headers $headers -Uri $uri -ContentType "application/json; charset=utf-8" -Body (@{ "id"="/apis/test2"; "name"="test2" ; "properties" = @{ "format" = "wsdl"; "value" = "$content"; "displayName"="test1"; "protocols"=@("https"); "path"="test2"}; } | ConvertTo-Json)
--------------------------------------------------------------------------------
/ApiManagementSchemaImport/uploadschemas.ps1:
--------------------------------------------------------------------------------
1 | param ([Parameter(Mandatory)]$file, [Parameter(Mandatory)]$apimresource)
2 | Write-Output "Starting Azure login"
3 | az login
4 | Write-Output "Starting the process"
5 | $ErrorActionPreference = "Stop"
6 | $token = az account get-access-token | ConvertFrom-Json
7 | $bearer =$token.accessToken
8 | $headers = @{Authorization = "Bearer $bearer"}
9 |
10 | $directoryPath = Split-Path -Path $file
11 | Write-Output "Reading file $file"
12 | $json = (Get-Content -Path $file -Raw) | ConvertFrom-Json
13 |
14 | $json.psobject.properties | ForEach-Object {
15 | $childPath = $_.Value + ".xsd"
16 | $schema = Join-Path -Path $directoryPath -ChildPath $childPath
17 | $uri = $apimresource + "/schemas/" + $_.Value + "?api-version=2021-04-01-preview"
18 | Write-Output "Reading $schema"
19 | $content = Get-Content -Path $schema -Raw -Encoding utf8
20 | Write-Output "Updating schema to $uri"
21 | $res = iwr -UseBasicParsing -Method Put -Headers $headers -Uri $uri -ContentType "application/json; charset=utf-8" `
22 | -Body (@{ `
23 | "properties" = @{ `
24 | "schemaType" = "xml"; `
25 | "value" = "$content"; `
26 | }; `
27 | } | ConvertTo-Json)
28 | if (($res.StatusCode -ne 200) -and ($res.StatusCode -ne 201) -and ($res.StatusCode -ne 202))
29 | {
30 | Throw "Request returned with HTTP code $req.StatusCode"
31 | }
32 | }
33 |
34 | Write-Output "Process successfully ended"
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [project-title] Changelog
2 |
3 |
4 | # x.y.z (yyyy-mm-dd)
5 |
6 | *Features*
7 | * ...
8 |
9 | *Bug Fixes*
10 | * ...
11 |
12 | *Breaking Changes*
13 | * ...
14 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to [project-title]
2 |
3 | This project welcomes contributions and suggestions. Most contributions require you to agree to a
4 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
5 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
6 |
7 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide
8 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
9 | provided by the bot. You will only need to do this once across all repos using our CLA.
10 |
11 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
12 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
13 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
14 |
15 | - [Code of Conduct](#coc)
16 | - [Issues and Bugs](#issue)
17 | - [Feature Requests](#feature)
18 | - [Submission Guidelines](#submit)
19 |
20 | ## Code of Conduct
21 | Help us keep this project open and inclusive. Please read and follow our [Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
22 |
23 | ## Found an Issue?
24 | If you find a bug in the source code or a mistake in the documentation, you can help us by
25 | [submitting an issue](#submit-issue) to the GitHub Repository. Even better, you can
26 | [submit a Pull Request](#submit-pr) with a fix.
27 |
28 | ## Want a Feature?
29 | You can *request* a new feature by [submitting an issue](#submit-issue) to the GitHub
30 | Repository. If you would like to *implement* a new feature, please submit an issue with
31 | a proposal for your work first, to be sure that we can use it.
32 |
33 | * **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
34 |
35 | ## Submission Guidelines
36 |
37 | ### Submitting an Issue
38 | Before you submit an issue, search the archive, maybe your question was already answered.
39 |
40 | If your issue appears to be a bug, and hasn't been reported, open a new issue.
41 | Help us to maximize the effort we can spend fixing issues and adding new
42 | features, by not reporting duplicate issues. Providing the following information will increase the
43 | chances of your issue being dealt with quickly:
44 |
45 | * **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
46 | * **Version** - what version is affected (e.g. 0.1.2)
47 | * **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you
48 | * **Browsers and Operating System** - is this a problem with all browsers?
49 | * **Reproduce the Error** - provide a live example or a unambiguous set of steps
50 | * **Related Issues** - has a similar issue been reported before?
51 | * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
52 | causing the problem (line of code or commit)
53 |
54 | You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/[organization-name]/[repository-name]/issues/new].
55 |
56 | ### Submitting a Pull Request (PR)
57 | Before you submit your Pull Request (PR) consider the following guidelines:
58 |
59 | * Search the repository (https://github.com/[organization-name]/[repository-name]/pulls) for an open or closed PR
60 | that relates to your submission. You don't want to duplicate effort.
61 |
62 | * Make your changes in a new git fork:
63 |
64 | * Commit your changes using a descriptive commit message
65 | * Push your fork to GitHub:
66 | * In GitHub, create a pull request
67 | * If we suggest changes then:
68 | * Make the required updates.
69 | * Rebase your fork and force push to your GitHub repository (this will update your Pull Request):
70 |
71 | ```shell
72 | git rebase master -i
73 | git push -f
74 | ```
75 |
76 | That's it! Thank you for your contribution!
77 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Microsoft Corporation.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # API Management schema import tools
2 |
3 | This repository contains the source code for several tools that are useful to prepare and upload WSDL and XML schema files for use in your [Azure API Management](https://azure.microsoft.com/services/api-management/) service instance:
4 |
5 | - **WSDLProcessor**: Takes a WSDL file as an input and outputs another WSDL file with references through `wsdl:import`, `xsd:import`, and `xsd:include` resolved and merged inline. The references are resolved from the local filesystem or through a URL.
6 | - **XMLSchemaProcessor**: Takes a folder with XSD files, renames them based on Azure Resource Manager naming requirements, and creates a sequence to upload those schemas into Azure API Management based on a schema dependency graph
7 | - **PowerShell tools**
8 | - **uploadschemas.ps1**: Uploads the XSD schema files generated by the XMLSchemaProcessor to your Azure API Management service
9 | - **batchWsdlProcessor.ps1**: Runs WSDLProcessor on all WSDL files with location specified in a JSON file and uploads the generated WSDL files into your Azure API Management service
10 | - **batchXmlSchemaProcessor.ps1**: Runs XMLSchemaProcessor for all folders listed in a JSON file and uploads the generated XSD schemas into your Azure API Management service
11 |
12 | ## Features
13 |
14 | ### WSDLProcessor
15 |
16 | This project framework provides the following features:
17 |
18 | - Accepts two command-line parameters:
19 | - Path to input WSDL file (required)
20 | - Path to schemaLocation (optional)
21 | - Detects, resolves, and inlines:
22 | - All `wsdl:import` directives
23 | - All `xsd:import` and `xsd:include` elements in XML schemas
24 | - Merges all XML schemas with the same target namespace into a single schema
25 | - Resolves the following types of references:
26 | - HTTP/HTTPS absolute URLs. Any non-`200` response is a failure.
27 | - Absolute local filesystem locations
28 | - Relative local filesystem locations. For the base location, the tool uses the current file location, **not root file location or the location of the tool itself**.
29 | - Outputs a single WSDL file
30 |
31 | ### XMLSchemaProcessor
32 |
33 | This tool provides the following features:
34 |
35 | - Accepts two command-line parameters:
36 | - A folder with all schemas
37 | - Output folder
38 | - Produces a single file upload-plan.json in the output folder
39 | - Performs the following steps:
40 |
41 | - Iterates through all files in the folder with .xsd extension
42 | - Detects all `xsd:import` and `xsd:include` elements
43 | - **Fails immediately if any import or include doesn't have `schemaLocation` or the value is not a local file location**
44 | - For each filename, generates an Azure Resource Manager-compliant resource name:
45 |
46 | - Drops file extension
47 | - Replaces all non-alphanumeric symbols with a single dash
48 |
49 | Examples: foo.xsd -> foo, foo_1.xsd -> foo-1, foo_1_2.xsd -> foo-1-2, etc.
50 |
51 | - Replaces `schemaLocation` with a reference to a well-formed ARM schema resource: foo.xsd -> /schemas/foo, foo_1_2.xsd -> /schemas/foo-1-2
52 | - Builds a dependency graph between all schema files
53 | - Writes a single JSON document in the output file with property names corresponding to filenames and property values corresponding to ARM names in the order of dependency
54 |
55 | Example: If foo.xsd depends on foo_1_2.xsd, upload-plan.json should contain: `{ "foo_1_2.xsd": "foo-1-2", "foo.xsd": "foo" }`
56 |
57 | - Fails on the first error with a descriptive error message written to standard output
58 |
59 | ### PowerShell script to upload generated XML schemas
60 |
61 | The Powershell script **uploadschemas.ps1** provides the following features:
62 |
63 | - Accepts two command-line parameters:
64 | - Location of JSON file generated by schema processing tool (XMLSchemaProcessor)
65 | - API Management resource URL, e.g. `https://management.azure.com/subscriptions/{subid}/resourceGroups/{rgname}/providers/Microsoft.ApiManagement/service/{servicename}`
66 | - Acquires Azure access token for current user
67 | - Iterates through schemas in the source JSON file and uploads them to the API Management service using HTTP calls
68 | - Fails on first error
69 |
70 | ### PowerShell script to generate WSDL merged files and upload them to API Management
71 |
72 | The Powershell script **batchWsdlProcessor.ps1** provides the following features:
73 |
74 | - Accepts three command-line parameters:
75 | - Full path of JSON configuration file with content similar to:
76 | `{"wsdlFileName.wsdl" : "DirectoryPathOfWsdlFile", ...}`
77 | - API Management resource URL, e.g., `https://management.azure.com/subscriptions/{subid}/resourceGroups/{rgname}/providers/Microsoft.ApiManagement/service/{servicename}`
78 | - WSDLProcessor path, e.g., `C:\myPathParent\myPathChild\[...]\Microsoft.Azure.ApiManagement.WsdlProcessor.App.exe`
79 | - Acquires Azure access token for current user
80 | - Iterates through JSON configuration file and generates new WSDL files with merged schemas
81 | - Uploads the new WSDL files to the API Management service using HTTP calls
82 | - Fails on first error
83 |
84 | ### PowerShell script to generate new XML schemas and upload them to API Management
85 |
86 | The Powershell script **batchXmlSchemaProcessor.ps1** provides the following features:
87 |
88 | - Accepts three command-line parameters:
89 | - Full path of JSON configuration file with content similar to:
90 | `{"inputDirectoryWithSchemas" : "OutputDirectory", ...}`
91 | - API Management resource URL, e.g., `https://management.azure.com/subscriptions/{subid}/resourceGroups/{rgname}/providers/Microsoft.ApiManagement/service/{servicename}`
92 | - XMLSchemaProcessor path, e.g. `C:\myPathParent\myPathChild\[...]\Microsoft.Azure.ApiManagement.XmlSchemaProcessor.App.exe`
93 | - Acquires Azure access token for current user
94 | - Iterates through JSON configuration file and generates new XML schema files and an upload-plan.json for each
95 | - Uploads the new XML schema files to the API Management service using the upload-plan.json files and HTTP calls
96 | - Fails on first failure
97 |
98 | ## Getting started
99 |
100 | ### Prerequisites
101 |
102 | - OS: Windows, Linux, macOS
103 | - [.NET 9.0](https://dotnet.microsoft.com/download/dotnet/9.0)
104 | - [.NET CLI](https://docs.microsoft.com//dotnet/core/tools/)
105 | - [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
106 | - [PowerShell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell)
107 |
108 | ### Run WSDLProcessor
109 |
110 | 1. When you have the .NET CLI installed on your OS of choice, download the code and go to the Microsoft.Azure.ApiManagement.WsdlProcessor.App directory:
111 |
112 | git clone https://github.com/Azure-Samples/api-management-schema-import.git
113 |
114 | cd api-management-schema-import/ApiManagementSchemaImport/Microsoft.Azure.ApiManagement.WsdlProcessor.App
115 |
116 | 1. Restore the packages that are specified in the .csproj file of the project:
117 |
118 | dotnet restore
119 |
120 | 1. Build the project:
121 |
122 | dotnet build
123 |
124 | This will drop a binary in `./bin/[configuration]/[net9.0]/[Microsoft.Azure.ApiManagement.WsdlProcessor.App.exe]`
125 |
126 | 1. Run the binary:
127 | 1.1. Scenario 1 (with all schemaReference at http URL)
128 | C:\folder\Microsoft.Azure.ApiManagement.WsdlProcessor.App.exe "/mywsdlfile.wsdl"
129 |
130 | 1.2. Scenario 2 (with all schemaReference point to a file)
131 | C:\folder\Microsoft.Azure.ApiManagement.WsdlProcessor.App.exe "/mywsdlfile.wsdl" ""
132 |
133 | ### Run XmlSchemaProcessor
134 |
135 | 1. When you have the .NET CLI installed on your OS of choice, download the code and go to the Microsoft.Azure.ApiManagement.XmlSchemaProcessor.App directory:
136 |
137 | git clone https://github.com/Azure-Samples/api-management-schema-import.git
138 |
139 | cd api-management-schema-import/Mcrosoft.Azure.ApiManagement.XmlSchemaProcessor.App
140 |
141 | 1. Restore the packages that are specified in the .csproj file of the projecgt:
142 |
143 | dotnet restore
144 |
145 | 1. Build the project:
146 |
147 | dotnet build
148 |
149 | This will drop a binary in `./bin/[configuration]/[net9.0]/[Microsoft.Azure.ApiManagement.XmlSchemaProcessor.App.exe]`
150 |
151 | 1. Run the binary:
152 |
153 | c:\folder\Microsoft.Azure.ApiManagement.XmlSchemaProcessor.App.exe "c:\schemaslocation\" "c:\schemaslocation\output\"
154 |
155 | ### Powershell UploadSchemas quickstart
156 |
157 | .\uploadschemas.ps1 "upload-planLocationFile" "https://management.azure.com/subscriptions/{subid}/resourceGroups/{rgname}/providers/Microsoft.ApiManagement/service/{servicename}"
158 |
159 | ### Powershell batchWsdlProcessor quickstart
160 |
161 | .\batchWsdlProcessor.ps1 "C:\myPathParent\myPathChild\...\wsdlFiles.json" "https://management.azure.com/subscriptions/{subid}/resourceGroups/{rgname}/providers/Microsoft.ApiManagement/service/{servicename}" "c:\folder\Microsoft.Azure.ApiManagement.WsdlProcessor.App.exe"
162 |
163 | ### Powershell batchXmlSchemaProcessor quickstart
164 |
165 | .\batchXmlSchemaProcessor.ps1 "C:\myPathParent\myPathChild\...\xmlSchemaFolders.json" "https://management.azure.com/subscriptions/{subid}/resourceGroups/{rgname}/providers/Microsoft.ApiManagement/service/{servicename}" "c:\folder\Microsoft.Azure.ApiManagement.XmlSchemaProcessor.App.exe"
166 |
167 | ## Resources
168 |
169 | * [WSDL Schema Files Specification](https://schemas.xmlsoap.org/wsdl/)
170 | * [API Management REST API](https://docs.microsoft.com/rest/api/apimanagement/current-ga/global-schema)
171 | * [Validation policies in API Management](https://docs.microsoft.com/azure/api-management/validation-policies)
172 | * [API Management schemas for content validation](https://docs.microsoft.com/azure/api-management/validation-policies#schemas-for-content-validation)
173 |
--------------------------------------------------------------------------------
/examples/WsdlProcessor/Include.xsd:
--------------------------------------------------------------------------------
1 |
2 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/WsdlProcessor/echoInclude.wsdl:
--------------------------------------------------------------------------------
1 |
2 |
12 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/examples/WsdlProcessor/output.wsdl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/examples/XmlSchemaProcessor/outputFolder/schema1.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/examples/XmlSchemaProcessor/outputFolder/schema2.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Addresses for International Purchase order schema
6 | Copyright 2000 Example.com. All rights reserved.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/examples/XmlSchemaProcessor/outputFolder/upload-plan.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema2.xsd": "schema2",
3 | "schema1.xsd": "schema1"
4 | }
--------------------------------------------------------------------------------
/examples/XmlSchemaProcessor/schema1.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/examples/XmlSchemaProcessor/schema2.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Addresses for International Purchase order schema
5 | Copyright 2000 Example.com. All rights reserved.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/examples/batchWsdlProcessor/configFileWsdl.json:
--------------------------------------------------------------------------------
1 | {
2 | "wsdlFileName1.wsdl" : "C:/myPathParent/myPathChild/",
3 | "wsdlFileName2.wsdl" : "C:/myPathParent/myPathChild/",
4 | "wsdlFileName3.wsdl" : "C:/myPathParent/myPathChild/"
5 | }
--------------------------------------------------------------------------------
/examples/batchXmlSchemaProcessor/configFileXml.json:
--------------------------------------------------------------------------------
1 | {
2 | "C:/myPathParent/myPathChild/XmlSchemasFolder1/" : "C:/myPathParent/myPathChild/XmlSchemasFolder1/outputfolder",
3 | "C:/myPathParent/myPathChild/XmlSchemasFolder2/" : "C:/myPathParent/myPathChild/XmlSchemasFolder2/outputfolder",
4 | "C:/myPathParent/myPathChild/XmlSchemasFolder3/" : "C:/myPathParent/myPathChild/XmlSchemasFolder3/outputfolder"
5 | }
--------------------------------------------------------------------------------
/examples/uploadSchemas/upload-plan.json:
--------------------------------------------------------------------------------
1 | {
2 | "GetProvideShipments_1.xsd": "GetProvideShipments-1",
3 | "GetProvideShipments.xsd": "GetProvideShipments"
4 | }
--------------------------------------------------------------------------------