http urls monitor.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. // Copyright 2015 go-swagger maintainers
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package spec
  15. import (
  16. "encoding/json"
  17. "fmt"
  18. "net/url"
  19. "strings"
  20. "github.com/go-openapi/jsonpointer"
  21. "github.com/go-openapi/swag"
  22. )
  23. // BooleanProperty creates a boolean property
  24. func BooleanProperty() *Schema {
  25. return &Schema{SchemaProps: SchemaProps{Type: []string{"boolean"}}}
  26. }
  27. // BoolProperty creates a boolean property
  28. func BoolProperty() *Schema { return BooleanProperty() }
  29. // StringProperty creates a string property
  30. func StringProperty() *Schema {
  31. return &Schema{SchemaProps: SchemaProps{Type: []string{"string"}}}
  32. }
  33. // CharProperty creates a string property
  34. func CharProperty() *Schema {
  35. return &Schema{SchemaProps: SchemaProps{Type: []string{"string"}}}
  36. }
  37. // Float64Property creates a float64/double property
  38. func Float64Property() *Schema {
  39. return &Schema{SchemaProps: SchemaProps{Type: []string{"number"}, Format: "double"}}
  40. }
  41. // Float32Property creates a float32/float property
  42. func Float32Property() *Schema {
  43. return &Schema{SchemaProps: SchemaProps{Type: []string{"number"}, Format: "float"}}
  44. }
  45. // Int8Property creates an int8 property
  46. func Int8Property() *Schema {
  47. return &Schema{SchemaProps: SchemaProps{Type: []string{"integer"}, Format: "int8"}}
  48. }
  49. // Int16Property creates an int16 property
  50. func Int16Property() *Schema {
  51. return &Schema{SchemaProps: SchemaProps{Type: []string{"integer"}, Format: "int16"}}
  52. }
  53. // Int32Property creates an int32 property
  54. func Int32Property() *Schema {
  55. return &Schema{SchemaProps: SchemaProps{Type: []string{"integer"}, Format: "int32"}}
  56. }
  57. // Int64Property creates an int64 property
  58. func Int64Property() *Schema {
  59. return &Schema{SchemaProps: SchemaProps{Type: []string{"integer"}, Format: "int64"}}
  60. }
  61. // StrFmtProperty creates a property for the named string format
  62. func StrFmtProperty(format string) *Schema {
  63. return &Schema{SchemaProps: SchemaProps{Type: []string{"string"}, Format: format}}
  64. }
  65. // DateProperty creates a date property
  66. func DateProperty() *Schema {
  67. return &Schema{SchemaProps: SchemaProps{Type: []string{"string"}, Format: "date"}}
  68. }
  69. // DateTimeProperty creates a date time property
  70. func DateTimeProperty() *Schema {
  71. return &Schema{SchemaProps: SchemaProps{Type: []string{"string"}, Format: "date-time"}}
  72. }
  73. // MapProperty creates a map property
  74. func MapProperty(property *Schema) *Schema {
  75. return &Schema{SchemaProps: SchemaProps{Type: []string{"object"}, AdditionalProperties: &SchemaOrBool{Allows: true, Schema: property}}}
  76. }
  77. // RefProperty creates a ref property
  78. func RefProperty(name string) *Schema {
  79. return &Schema{SchemaProps: SchemaProps{Ref: MustCreateRef(name)}}
  80. }
  81. // RefSchema creates a ref property
  82. func RefSchema(name string) *Schema {
  83. return &Schema{SchemaProps: SchemaProps{Ref: MustCreateRef(name)}}
  84. }
  85. // ArrayProperty creates an array property
  86. func ArrayProperty(items *Schema) *Schema {
  87. if items == nil {
  88. return &Schema{SchemaProps: SchemaProps{Type: []string{"array"}}}
  89. }
  90. return &Schema{SchemaProps: SchemaProps{Items: &SchemaOrArray{Schema: items}, Type: []string{"array"}}}
  91. }
  92. // ComposedSchema creates a schema with allOf
  93. func ComposedSchema(schemas ...Schema) *Schema {
  94. s := new(Schema)
  95. s.AllOf = schemas
  96. return s
  97. }
  98. // SchemaURL represents a schema url
  99. type SchemaURL string
  100. // MarshalJSON marshal this to JSON
  101. func (r SchemaURL) MarshalJSON() ([]byte, error) {
  102. if r == "" {
  103. return []byte("{}"), nil
  104. }
  105. v := map[string]interface{}{"$schema": string(r)}
  106. return json.Marshal(v)
  107. }
  108. // UnmarshalJSON unmarshal this from JSON
  109. func (r *SchemaURL) UnmarshalJSON(data []byte) error {
  110. var v map[string]interface{}
  111. if err := json.Unmarshal(data, &v); err != nil {
  112. return err
  113. }
  114. return r.fromMap(v)
  115. }
  116. func (r *SchemaURL) fromMap(v map[string]interface{}) error {
  117. if v == nil {
  118. return nil
  119. }
  120. if vv, ok := v["$schema"]; ok {
  121. if str, ok := vv.(string); ok {
  122. u, err := url.Parse(str)
  123. if err != nil {
  124. return err
  125. }
  126. *r = SchemaURL(u.String())
  127. }
  128. }
  129. return nil
  130. }
  131. // type ExtraSchemaProps map[string]interface{}
  132. // // JSONSchema represents a structure that is a json schema draft 04
  133. // type JSONSchema struct {
  134. // SchemaProps
  135. // ExtraSchemaProps
  136. // }
  137. // // MarshalJSON marshal this to JSON
  138. // func (s JSONSchema) MarshalJSON() ([]byte, error) {
  139. // b1, err := json.Marshal(s.SchemaProps)
  140. // if err != nil {
  141. // return nil, err
  142. // }
  143. // b2, err := s.Ref.MarshalJSON()
  144. // if err != nil {
  145. // return nil, err
  146. // }
  147. // b3, err := s.Schema.MarshalJSON()
  148. // if err != nil {
  149. // return nil, err
  150. // }
  151. // b4, err := json.Marshal(s.ExtraSchemaProps)
  152. // if err != nil {
  153. // return nil, err
  154. // }
  155. // return swag.ConcatJSON(b1, b2, b3, b4), nil
  156. // }
  157. // // UnmarshalJSON marshal this from JSON
  158. // func (s *JSONSchema) UnmarshalJSON(data []byte) error {
  159. // var sch JSONSchema
  160. // if err := json.Unmarshal(data, &sch.SchemaProps); err != nil {
  161. // return err
  162. // }
  163. // if err := json.Unmarshal(data, &sch.Ref); err != nil {
  164. // return err
  165. // }
  166. // if err := json.Unmarshal(data, &sch.Schema); err != nil {
  167. // return err
  168. // }
  169. // if err := json.Unmarshal(data, &sch.ExtraSchemaProps); err != nil {
  170. // return err
  171. // }
  172. // *s = sch
  173. // return nil
  174. // }
  175. // SchemaProps describes a JSON schema (draft 4)
  176. type SchemaProps struct {
  177. ID string `json:"id,omitempty"`
  178. Ref Ref `json:"-"`
  179. Schema SchemaURL `json:"-"`
  180. Description string `json:"description,omitempty"`
  181. Type StringOrArray `json:"type,omitempty"`
  182. Format string `json:"format,omitempty"`
  183. Title string `json:"title,omitempty"`
  184. Default interface{} `json:"default,omitempty"`
  185. Maximum *float64 `json:"maximum,omitempty"`
  186. ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
  187. Minimum *float64 `json:"minimum,omitempty"`
  188. ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"`
  189. MaxLength *int64 `json:"maxLength,omitempty"`
  190. MinLength *int64 `json:"minLength,omitempty"`
  191. Pattern string `json:"pattern,omitempty"`
  192. MaxItems *int64 `json:"maxItems,omitempty"`
  193. MinItems *int64 `json:"minItems,omitempty"`
  194. UniqueItems bool `json:"uniqueItems,omitempty"`
  195. MultipleOf *float64 `json:"multipleOf,omitempty"`
  196. Enum []interface{} `json:"enum,omitempty"`
  197. MaxProperties *int64 `json:"maxProperties,omitempty"`
  198. MinProperties *int64 `json:"minProperties,omitempty"`
  199. Required []string `json:"required,omitempty"`
  200. Items *SchemaOrArray `json:"items,omitempty"`
  201. AllOf []Schema `json:"allOf,omitempty"`
  202. OneOf []Schema `json:"oneOf,omitempty"`
  203. AnyOf []Schema `json:"anyOf,omitempty"`
  204. Not *Schema `json:"not,omitempty"`
  205. Properties map[string]Schema `json:"properties,omitempty"`
  206. AdditionalProperties *SchemaOrBool `json:"additionalProperties,omitempty"`
  207. PatternProperties map[string]Schema `json:"patternProperties,omitempty"`
  208. Dependencies Dependencies `json:"dependencies,omitempty"`
  209. AdditionalItems *SchemaOrBool `json:"additionalItems,omitempty"`
  210. Definitions Definitions `json:"definitions,omitempty"`
  211. }
  212. // SwaggerSchemaProps are additional properties supported by swagger schemas, but not JSON-schema (draft 4)
  213. type SwaggerSchemaProps struct {
  214. Discriminator string `json:"discriminator,omitempty"`
  215. ReadOnly bool `json:"readOnly,omitempty"`
  216. XML *XMLObject `json:"xml,omitempty"`
  217. ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"`
  218. Example interface{} `json:"example,omitempty"`
  219. }
  220. // Schema the schema object allows the definition of input and output data types.
  221. // These types can be objects, but also primitives and arrays.
  222. // This object is based on the [JSON Schema Specification Draft 4](http://json-schema.org/)
  223. // and uses a predefined subset of it.
  224. // On top of this subset, there are extensions provided by this specification to allow for more complete documentation.
  225. //
  226. // For more information: http://goo.gl/8us55a#schemaObject
  227. type Schema struct {
  228. VendorExtensible
  229. SchemaProps
  230. SwaggerSchemaProps
  231. ExtraProps map[string]interface{} `json:"-"`
  232. }
  233. // JSONLookup implements an interface to customize json pointer lookup
  234. func (s Schema) JSONLookup(token string) (interface{}, error) {
  235. if ex, ok := s.Extensions[token]; ok {
  236. return &ex, nil
  237. }
  238. if ex, ok := s.ExtraProps[token]; ok {
  239. return &ex, nil
  240. }
  241. r, _, err := jsonpointer.GetForToken(s.SchemaProps, token)
  242. if r != nil || (err != nil && !strings.HasPrefix(err.Error(), "object has no field")) {
  243. return r, err
  244. }
  245. r, _, err = jsonpointer.GetForToken(s.SwaggerSchemaProps, token)
  246. return r, err
  247. }
  248. // WithID sets the id for this schema, allows for chaining
  249. func (s *Schema) WithID(id string) *Schema {
  250. s.ID = id
  251. return s
  252. }
  253. // WithTitle sets the title for this schema, allows for chaining
  254. func (s *Schema) WithTitle(title string) *Schema {
  255. s.Title = title
  256. return s
  257. }
  258. // WithDescription sets the description for this schema, allows for chaining
  259. func (s *Schema) WithDescription(description string) *Schema {
  260. s.Description = description
  261. return s
  262. }
  263. // WithProperties sets the properties for this schema
  264. func (s *Schema) WithProperties(schemas map[string]Schema) *Schema {
  265. s.Properties = schemas
  266. return s
  267. }
  268. // SetProperty sets a property on this schema
  269. func (s *Schema) SetProperty(name string, schema Schema) *Schema {
  270. if s.Properties == nil {
  271. s.Properties = make(map[string]Schema)
  272. }
  273. s.Properties[name] = schema
  274. return s
  275. }
  276. // WithAllOf sets the all of property
  277. func (s *Schema) WithAllOf(schemas ...Schema) *Schema {
  278. s.AllOf = schemas
  279. return s
  280. }
  281. // WithMaxProperties sets the max number of properties an object can have
  282. func (s *Schema) WithMaxProperties(max int64) *Schema {
  283. s.MaxProperties = &max
  284. return s
  285. }
  286. // WithMinProperties sets the min number of properties an object must have
  287. func (s *Schema) WithMinProperties(min int64) *Schema {
  288. s.MinProperties = &min
  289. return s
  290. }
  291. // Typed sets the type of this schema for a single value item
  292. func (s *Schema) Typed(tpe, format string) *Schema {
  293. s.Type = []string{tpe}
  294. s.Format = format
  295. return s
  296. }
  297. // AddType adds a type with potential format to the types for this schema
  298. func (s *Schema) AddType(tpe, format string) *Schema {
  299. s.Type = append(s.Type, tpe)
  300. if format != "" {
  301. s.Format = format
  302. }
  303. return s
  304. }
  305. // CollectionOf a fluent builder method for an array parameter
  306. func (s *Schema) CollectionOf(items Schema) *Schema {
  307. s.Type = []string{"array"}
  308. s.Items = &SchemaOrArray{Schema: &items}
  309. return s
  310. }
  311. // WithDefault sets the default value on this parameter
  312. func (s *Schema) WithDefault(defaultValue interface{}) *Schema {
  313. s.Default = defaultValue
  314. return s
  315. }
  316. // WithRequired flags this parameter as required
  317. func (s *Schema) WithRequired(items ...string) *Schema {
  318. s.Required = items
  319. return s
  320. }
  321. // AddRequired adds field names to the required properties array
  322. func (s *Schema) AddRequired(items ...string) *Schema {
  323. s.Required = append(s.Required, items...)
  324. return s
  325. }
  326. // WithMaxLength sets a max length value
  327. func (s *Schema) WithMaxLength(max int64) *Schema {
  328. s.MaxLength = &max
  329. return s
  330. }
  331. // WithMinLength sets a min length value
  332. func (s *Schema) WithMinLength(min int64) *Schema {
  333. s.MinLength = &min
  334. return s
  335. }
  336. // WithPattern sets a pattern value
  337. func (s *Schema) WithPattern(pattern string) *Schema {
  338. s.Pattern = pattern
  339. return s
  340. }
  341. // WithMultipleOf sets a multiple of value
  342. func (s *Schema) WithMultipleOf(number float64) *Schema {
  343. s.MultipleOf = &number
  344. return s
  345. }
  346. // WithMaximum sets a maximum number value
  347. func (s *Schema) WithMaximum(max float64, exclusive bool) *Schema {
  348. s.Maximum = &max
  349. s.ExclusiveMaximum = exclusive
  350. return s
  351. }
  352. // WithMinimum sets a minimum number value
  353. func (s *Schema) WithMinimum(min float64, exclusive bool) *Schema {
  354. s.Minimum = &min
  355. s.ExclusiveMinimum = exclusive
  356. return s
  357. }
  358. // WithEnum sets a the enum values (replace)
  359. func (s *Schema) WithEnum(values ...interface{}) *Schema {
  360. s.Enum = append([]interface{}{}, values...)
  361. return s
  362. }
  363. // WithMaxItems sets the max items
  364. func (s *Schema) WithMaxItems(size int64) *Schema {
  365. s.MaxItems = &size
  366. return s
  367. }
  368. // WithMinItems sets the min items
  369. func (s *Schema) WithMinItems(size int64) *Schema {
  370. s.MinItems = &size
  371. return s
  372. }
  373. // UniqueValues dictates that this array can only have unique items
  374. func (s *Schema) UniqueValues() *Schema {
  375. s.UniqueItems = true
  376. return s
  377. }
  378. // AllowDuplicates this array can have duplicates
  379. func (s *Schema) AllowDuplicates() *Schema {
  380. s.UniqueItems = false
  381. return s
  382. }
  383. // AddToAllOf adds a schema to the allOf property
  384. func (s *Schema) AddToAllOf(schemas ...Schema) *Schema {
  385. s.AllOf = append(s.AllOf, schemas...)
  386. return s
  387. }
  388. // WithDiscriminator sets the name of the discriminator field
  389. func (s *Schema) WithDiscriminator(discriminator string) *Schema {
  390. s.Discriminator = discriminator
  391. return s
  392. }
  393. // AsReadOnly flags this schema as readonly
  394. func (s *Schema) AsReadOnly() *Schema {
  395. s.ReadOnly = true
  396. return s
  397. }
  398. // AsWritable flags this schema as writeable (not read-only)
  399. func (s *Schema) AsWritable() *Schema {
  400. s.ReadOnly = false
  401. return s
  402. }
  403. // WithExample sets the example for this schema
  404. func (s *Schema) WithExample(example interface{}) *Schema {
  405. s.Example = example
  406. return s
  407. }
  408. // WithExternalDocs sets/removes the external docs for/from this schema.
  409. // When you pass empty strings as params the external documents will be removed.
  410. // When you pass non-empty string as one value then those values will be used on the external docs object.
  411. // So when you pass a non-empty description, you should also pass the url and vice versa.
  412. func (s *Schema) WithExternalDocs(description, url string) *Schema {
  413. if description == "" && url == "" {
  414. s.ExternalDocs = nil
  415. return s
  416. }
  417. if s.ExternalDocs == nil {
  418. s.ExternalDocs = &ExternalDocumentation{}
  419. }
  420. s.ExternalDocs.Description = description
  421. s.ExternalDocs.URL = url
  422. return s
  423. }
  424. // WithXMLName sets the xml name for the object
  425. func (s *Schema) WithXMLName(name string) *Schema {
  426. if s.XML == nil {
  427. s.XML = new(XMLObject)
  428. }
  429. s.XML.Name = name
  430. return s
  431. }
  432. // WithXMLNamespace sets the xml namespace for the object
  433. func (s *Schema) WithXMLNamespace(namespace string) *Schema {
  434. if s.XML == nil {
  435. s.XML = new(XMLObject)
  436. }
  437. s.XML.Namespace = namespace
  438. return s
  439. }
  440. // WithXMLPrefix sets the xml prefix for the object
  441. func (s *Schema) WithXMLPrefix(prefix string) *Schema {
  442. if s.XML == nil {
  443. s.XML = new(XMLObject)
  444. }
  445. s.XML.Prefix = prefix
  446. return s
  447. }
  448. // AsXMLAttribute flags this object as xml attribute
  449. func (s *Schema) AsXMLAttribute() *Schema {
  450. if s.XML == nil {
  451. s.XML = new(XMLObject)
  452. }
  453. s.XML.Attribute = true
  454. return s
  455. }
  456. // AsXMLElement flags this object as an xml node
  457. func (s *Schema) AsXMLElement() *Schema {
  458. if s.XML == nil {
  459. s.XML = new(XMLObject)
  460. }
  461. s.XML.Attribute = false
  462. return s
  463. }
  464. // AsWrappedXML flags this object as wrapped, this is mostly useful for array types
  465. func (s *Schema) AsWrappedXML() *Schema {
  466. if s.XML == nil {
  467. s.XML = new(XMLObject)
  468. }
  469. s.XML.Wrapped = true
  470. return s
  471. }
  472. // AsUnwrappedXML flags this object as an xml node
  473. func (s *Schema) AsUnwrappedXML() *Schema {
  474. if s.XML == nil {
  475. s.XML = new(XMLObject)
  476. }
  477. s.XML.Wrapped = false
  478. return s
  479. }
  480. // MarshalJSON marshal this to JSON
  481. func (s Schema) MarshalJSON() ([]byte, error) {
  482. b1, err := json.Marshal(s.SchemaProps)
  483. if err != nil {
  484. return nil, fmt.Errorf("schema props %v", err)
  485. }
  486. b2, err := json.Marshal(s.VendorExtensible)
  487. if err != nil {
  488. return nil, fmt.Errorf("vendor props %v", err)
  489. }
  490. b3, err := s.Ref.MarshalJSON()
  491. if err != nil {
  492. return nil, fmt.Errorf("ref prop %v", err)
  493. }
  494. b4, err := s.Schema.MarshalJSON()
  495. if err != nil {
  496. return nil, fmt.Errorf("schema prop %v", err)
  497. }
  498. b5, err := json.Marshal(s.SwaggerSchemaProps)
  499. if err != nil {
  500. return nil, fmt.Errorf("common validations %v", err)
  501. }
  502. var b6 []byte
  503. if s.ExtraProps != nil {
  504. jj, err := json.Marshal(s.ExtraProps)
  505. if err != nil {
  506. return nil, fmt.Errorf("extra props %v", err)
  507. }
  508. b6 = jj
  509. }
  510. return swag.ConcatJSON(b1, b2, b3, b4, b5, b6), nil
  511. }
  512. // UnmarshalJSON marshal this from JSON
  513. func (s *Schema) UnmarshalJSON(data []byte) error {
  514. props := struct {
  515. SchemaProps
  516. SwaggerSchemaProps
  517. }{}
  518. if err := json.Unmarshal(data, &props); err != nil {
  519. return err
  520. }
  521. sch := Schema{
  522. SchemaProps: props.SchemaProps,
  523. SwaggerSchemaProps: props.SwaggerSchemaProps,
  524. }
  525. var d map[string]interface{}
  526. if err := json.Unmarshal(data, &d); err != nil {
  527. return err
  528. }
  529. _ = sch.Ref.fromMap(d)
  530. _ = sch.Schema.fromMap(d)
  531. delete(d, "$ref")
  532. delete(d, "$schema")
  533. for _, pn := range swag.DefaultJSONNameProvider.GetJSONNames(s) {
  534. delete(d, pn)
  535. }
  536. for k, vv := range d {
  537. lk := strings.ToLower(k)
  538. if strings.HasPrefix(lk, "x-") {
  539. if sch.Extensions == nil {
  540. sch.Extensions = map[string]interface{}{}
  541. }
  542. sch.Extensions[k] = vv
  543. continue
  544. }
  545. if sch.ExtraProps == nil {
  546. sch.ExtraProps = map[string]interface{}{}
  547. }
  548. sch.ExtraProps[k] = vv
  549. }
  550. *s = sch
  551. return nil
  552. }