Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 2 additions & 12 deletions src/SwaggerProvider.DesignTime/Provider.OpenApiClient.fs
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,8 @@ type public OpenApiClientTypeProvider(cfg : TypeProviderConfig) as this =
let addCache() =
lazy
let schemaData =
match schemaPathRaw.StartsWith("http", true, null) with
| true ->
let request = new HttpRequestMessage(HttpMethod.Get, schemaPathRaw)
// using a custom handler means that we can set the default credentials.
use handler = new HttpClientHandler(UseDefaultCredentials = true)
use client = new HttpClient(handler)
async {
let! response = client.SendAsync(request) |> Async.AwaitTask
return! response.Content.ReadAsStringAsync() |> Async.AwaitTask
} |> Async.RunSynchronously
| false ->
schemaPathRaw |> IO.File.ReadAllText
SwaggerProvider.Internal.SchemaReader.readSchemaPath "" schemaPathRaw
|> Async.RunSynchronously
let openApiReader = Microsoft.OpenApi.Readers.OpenApiStringReader()

let (schema, diagnostic) = openApiReader.Read(schemaData)
Expand Down
25 changes: 2 additions & 23 deletions src/SwaggerProvider.DesignTime/Provider.SwaggerClient.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ namespace SwaggerProvider

open System
open System.Reflection
open System.Net.Http
open ProviderImplementation.ProvidedTypes
open Microsoft.FSharp.Core.CompilerServices
open Swagger
Expand Down Expand Up @@ -70,28 +69,8 @@ type public SwaggerTypeProvider(cfg : TypeProviderConfig) as this =
let addCache() =
lazy
let schemaData =
match schemaPathRaw.StartsWith("http", true, null) with
| true ->
let headers =
headersStr.Split('|')
|> Seq.choose (fun x ->
let pair = x.Split('=')
if (pair.Length = 2)
then Some (pair.[0],pair.[1])
else None
)
let request = new HttpRequestMessage(HttpMethod.Get, schemaPathRaw)
for (name, value) in headers do
request.Headers.TryAddWithoutValidation(name, value) |> ignore
// using a custom handler means that we can set the default credentials.
use handler = new HttpClientHandler(UseDefaultCredentials = true)
use client = new HttpClient(handler)
async {
let! response = client.SendAsync(request) |> Async.AwaitTask
return! response.Content.ReadAsStringAsync() |> Async.AwaitTask
} |> Async.RunSynchronously
| false ->
schemaPathRaw |> IO.File.ReadAllText
SwaggerProvider.Internal.SchemaReader.readSchemaPath headersStr schemaPathRaw
|> Async.RunSynchronously
let schema = SwaggerParser.parseSchema schemaData

let defCompiler = DefinitionCompiler(schema, preferNullable)
Expand Down
43 changes: 42 additions & 1 deletion src/SwaggerProvider.DesignTime/Utils.fs
Original file line number Diff line number Diff line change
@@ -1,4 +1,45 @@
namespace SwaggerProvider.Internal
namespace SwaggerProvider.Internal

module SchemaReader =
open System
open System.Net.Http

let readSchemaPath (headersStr:string) (schemaPathRaw:string) =
async {
match schemaPathRaw.StartsWith("http", true, null) with
| true ->
let headers =
headersStr.Split('|')
|> Seq.choose (fun x ->
let pair = x.Split('=')
if (pair.Length = 2)
then Some (pair.[0],pair.[1])
else None
)
let request = new HttpRequestMessage(HttpMethod.Get, schemaPathRaw)
for (name, value) in headers do
request.Headers.TryAddWithoutValidation(name, value) |> ignore
// using a custom handler means that we can set the default credentials.
use handler = new HttpClientHandler(UseDefaultCredentials = true)
use client = new HttpClient(handler)
let! res =
async {
let! response = client.SendAsync(request) |> Async.AwaitTask
return! response.Content.ReadAsStringAsync() |> Async.AwaitTask
} |> Async.Catch
match res with
| Choice1Of2 x -> return x
| Choice2Of2 (:? System.Net.WebException as wex) ->
use stream = wex.Response.GetResponseStream()
use reader = new System.IO.StreamReader(stream)
let err = reader.ReadToEnd()
return
if String.IsNullOrEmpty err then raise wex
else err.ToString()
| Choice2Of2 e -> return failwith(e.ToString())
| false ->
return schemaPathRaw |> IO.File.ReadAllText
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this line is inside async we can replace in by

use sr = new StreamReader(schemaPathRaw)
return! sr.ReadToEndAsync() |> Async.AwaitTask

}

type UniqueNameGenerator() =
let hash = System.Collections.Generic.HashSet<_>()
Expand Down
15 changes: 14 additions & 1 deletion src/SwaggerProvider.DesignTime/v2/Parser/Parsers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,20 @@ module Parsers =
| "options" -> Some <| parseOperationObject context path Options obj
| "head" -> Some <| parseOperationObject context path Head obj
| "patch" -> Some <| parseOperationObject context path Patch obj
| "$ref" -> failwith "External definition of this path item is not supported yet"
| "$ref" ->
let fileName = obj.AsString()
let path =
// If path is empty:
// We could match something like interactive __SOURCE_DIRECTORY__
// or else (System.Reflection.Assembly.GetExecutingAssembly().Location |> System.IO.Path.GetDirectoryName)
obj.GetStringSafe("basePath")
let filePath = System.IO.Path.Combine [| path; (if fileName.Contains("#") then fileName.Split('#').[0] else fileName) |]

let schemaData =
SwaggerProvider.Internal.SchemaReader.readSchemaPath "" filePath
|> Async.RunSynchronously

failwith "External definition of this path item is not supported yet"
Copy link
Copy Markdown
Member

@sergey-tihon sergey-tihon Jun 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Thorium few questions here

  1. Why to use basePath instead of schemaPathRaw? I would expect that $ref if relative to schema rather than API base path
  2. What is point to request schema before raising exception?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, with this commit was an earlier commit for the other PR #152
and with that I the failwith is still the old code, the Parsers.fs changes can be ignored.

| _ -> None
let updateContext (pathItemObj:SchemaNode) =
match pathItemObj.TryGetProperty("parameters") with
Expand Down
12 changes: 12 additions & 0 deletions tests/SwaggerProvider.Tests/v2/Schema.Spec.Yaml.Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -821,4 +821,16 @@ GeneralError:
}
|] |> Map.ofArray)
Expect.equal actual expected "Responses Definitions Object"


ptestCase "External reference test" <| fun _ -> // Ignore("Not supported")
"""
# What should be the relative path? e.g. $ref: ../v2/token.yaml#/token
/tokens:
$ref: ./tests/SwaggerProvider.Tests/v2/token.yaml#/token
"""
|> SwaggerParser.parseYaml
|> Parsers.parsePathsObject Parsers.ParserContext.Empty
|> fun actual ->
Expect.equal (actual.ToString()) "token" "External reference test"
]
19 changes: 19 additions & 0 deletions tests/SwaggerProvider.Tests/v2/token.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
token:
post:
summary: Just a test
operationId: test_token
requestBody:
required: true
content:
application/json:
schema:
$ref: ../v2/token.yaml
responses:
"200":
description: Generated
content:
application/json:
schema:
$ref: ../v2/token.yaml
default:
$ref: ../error.yaml