question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

CLI crashes when "oneOf" is used the in schema

See original GitHub issue

When oneof is used the resource schema, the Cli crashes. Here is an example of a resource schema that uses oneof:

{
    "typeName": "brian::foo::me",
    "description": "An example resource schema demonstrating some basic constructs and validation rules.",
    "sourceUrl": "https://github.com/aws-cloudformation/aws-cloudformation-rpdk.git",
    "definitions": {
        "InitechDateFormat": {
            "$comment": "Use the `definitions` block to provide shared resource property schemas",
            "type": "string",
            "format": "date-time"
        },
        "Memo": {
            "type": "object",
            "properties": {
                "Heading": {
                    "type": "string"
                },
                "Body": {
                    "type": "string"
                }
            },
            "additionalProperties": false
        },
        "Tag": {
            "description": "A key-value pair to associate with a resource.",
            "type": "object",
            "properties": {
                "Key": {
                    "type": "string",
                    "description": "The key name of the tag. You can specify a value that is 1 to 128 Unicode characters in length and cannot be prefixed with aws:. You can use any of the following characters: the set of Unicode letters, digits, whitespace, _, ., /, =, +, and -.",
                    "minLength": 1,
                    "maxLength": 128
                },
                "Value": {
                    "type": "string",
                    "description": "The value for the tag. You can specify a value that is 0 to 256 Unicode characters in length and cannot be prefixed with aws:. You can use any of the following characters: the set of Unicode letters, digits, whitespace, _, ., /, =, +, and -.",
                    "minLength": 0,
                    "maxLength": 256
                }
            },
            "required": [
                "Key",
                "Value"
            ],
            "additionalProperties": false
        }
    },
    "properties": {
        "Cookies": {
            "oneOf": [
              {
                "additionalProperties": false,
                "properties": {
                  "Forward": {
                    "description": "Specifies which cookies to forward to the origin for this cache behavior.",
                    "enum": [
                      "all",
                      "none"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "Forward"
                ]
              },
              {
                "additionalProperties": false,
                "properties": {
                  "Forward": {
                    "description": "Specifies which cookies to forward to the origin for this cache behavior.",
                    "enum": [
                      "whitelist"
                    ],
                    "type": "string"
                  },
                  "WhitelistedNames": {
                    "description": "Required if you specify whitelist for the value of Forward.",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "Forward",
                  "WhitelistedNames"
                ]
              }
            ],
            "type": "object"
          }
    },
    "additionalProperties": false,
    "required": [
        "TestCode",
        "Title"
    ],
    "readOnlyProperties": [
        "/properties/TPSCode"
    ],
    "primaryIdentifier": [
        "/properties/TPSCode"
    ],
    "handlers": {
        "create": {
            "permissions": [
                "initech:CreateReport"
            ]
        },
        "read": {
            "permissions": [
                "initech:DescribeReport"
            ]
        },
        "update": {
            "permissions": [
                "initech:UpdateReport"
            ]
        },
        "delete": {
            "permissions": [
                "initech:DeleteReport"
            ]
        },
        "list": {
            "permissions": [
                "initech:ListReports"
            ]
        }
    }
}
$ cfn generate
Explicitly specify value for insertionOrder for array: WhitelistedNames
Explicitly specify value for tagging
Resource schema is valid.
=== Unhandled exception ===
Please report this issue to the team.
Issue tracker: github.com/aws-cloudformation/cloudformation-cli/issues
Please include the log file 'rpdk.log'

rpdk.log

[2022-03-04T19:38:08Z] DEBUG    - Logging set up successfully
[2022-03-04T19:38:08Z] DEBUG    - Running generate: Namespace(version=False, subparser_name='generate', command=<function generate at 0x116803b80>, verbose=0, endpoint_url=None, region=None, target_schemas=[])
[2022-03-04T19:38:08Z] DEBUG    - Root directory: /private/tmp/foo
[2022-03-04T19:38:08Z] DEBUG    - Loading project file '/private/tmp/foo/.rpdk-config'
[2022-03-04T19:38:08Z] INFO     - Validating your resource specification...
[2022-03-04T19:38:08Z] WARNING  - Explicitly specify value for insertionOrder for array: WhitelistedNames
[2022-03-04T19:38:08Z] WARNING  - Explicitly specify value for tagging
[2022-03-04T19:38:08Z] DEBUG    - Rewriting refs in '<BASE>' (file:///private/tmp/foo/brian-foo-me.json)
[2022-03-04T19:38:08Z] WARNING  - Resource schema is valid.
[2022-03-04T19:38:08Z] INFO     - Validating your resource schema...
[2022-03-04T19:38:08Z] DEBUG    - Writing Execution Role CloudFormation template: /private/tmp/foo/resource-role.yaml
[2022-03-04T19:38:08Z] DEBUG    - Overwriting '/private/tmp/foo/resource-role.yaml'
[2022-03-04T19:38:08Z] DEBUG    - Generate started
[2022-03-04T19:38:08Z] DEBUG    - Removing generated sources: /private/tmp/foo/target/generated-sources/rpdk
[2022-03-04T19:38:08Z] DEBUG    - Removing generated tests: /private/tmp/foo/target/generated-test-sources/rpdk
[2022-03-04T19:38:08Z] DEBUG    - Making generated folder structure: /private/tmp/foo/target/generated-sources/rpdk/com/brian/foo/me
[2022-03-04T19:38:08Z] DEBUG    - Making generated tests folder structure: /private/tmp/foo/target/generated-test-sources/rpdk/com/brian/foo/me
[2022-03-04T19:38:08Z] DEBUG    - generate_resource started
[2022-03-04T19:38:08Z] DEBUG    - Writing handler wrapper: /private/tmp/foo/target/generated-sources/rpdk/com/brian/foo/me/HandlerWrapper.java
[2022-03-04T19:38:08Z] DEBUG    - Overwriting '/private/tmp/foo/target/generated-sources/rpdk/com/brian/foo/me/HandlerWrapper.java'
[2022-03-04T19:38:08Z] DEBUG    - Writing handler wrapper: /private/tmp/foo/target/generated-sources/rpdk/com/brian/foo/me/HandlerWrapperExecutable.java
[2022-03-04T19:38:08Z] DEBUG    - Overwriting '/private/tmp/foo/target/generated-sources/rpdk/com/brian/foo/me/HandlerWrapperExecutable.java'
[2022-03-04T19:38:08Z] DEBUG    - Writing base configuration: /private/tmp/foo/target/generated-sources/rpdk/com/brian/foo/me/BaseConfiguration.java
[2022-03-04T19:38:08Z] DEBUG    - Overwriting '/private/tmp/foo/target/generated-sources/rpdk/com/brian/foo/me/BaseConfiguration.java'
[2022-03-04T19:38:08Z] DEBUG    - Writing base handler: /private/tmp/foo/target/generated-sources/rpdk/com/brian/foo/me/BaseHandler.java
[2022-03-04T19:38:08Z] DEBUG    - Overwriting '/private/tmp/foo/target/generated-sources/rpdk/com/brian/foo/me/BaseHandler.java'
[2022-03-04T19:38:08Z] DEBUG    - Writing 3 POJOs
[2022-03-04T19:38:08Z] DEBUG    - ResourceModel POJO: /private/tmp/foo/target/generated-sources/rpdk/com/brian/foo/me/ResourceModel.java
[2022-03-04T19:38:08Z] DEBUG    - Overwriting '/private/tmp/foo/target/generated-sources/rpdk/com/brian/foo/me/ResourceModel.java'
[2022-03-04T19:38:08Z] DEBUG    - Cookies POJO: /private/tmp/foo/target/generated-sources/rpdk/com/brian/foo/me/Cookies.java
[2022-03-04T19:38:08Z] DEBUG    - Unhandled exception
Traceback (most recent call last):
  File "/private/tmp/foo/env/lib/python3.9/site-packages/rpdk/core/cli.py", line 100, in main
    args.command(args)
  File "/private/tmp/foo/env/lib/python3.9/site-packages/rpdk/core/generate.py", line 15, in generate
    project.generate(args.endpoint_url, args.region, args.target_schemas)
  File "/private/tmp/foo/env/lib/python3.9/site-packages/rpdk/core/project.py", line 558, in generate
    self._plugin.generate(self)
  File "/private/tmp/foo/env/lib/python3.9/site-packages/rpdk/java/codegen.py", line 39, in wrapper
    result = func(*args, **kwargs)
  File "/private/tmp/foo/env/lib/python3.9/site-packages/rpdk/java/codegen.py", line 449, in generate
    self.generate_resource(src, project)
  File "/private/tmp/foo/env/lib/python3.9/site-packages/rpdk/java/codegen.py", line 39, in wrapper
    result = func(*args, **kwargs)
  File "/private/tmp/foo/env/lib/python3.9/site-packages/rpdk/java/codegen.py", line 526, in generate_resource
    contents = pojo_template.render(
  File "/private/tmp/foo/env/lib/python3.9/site-packages/jinja2/environment.py", line 1090, in render
    self.environment.handle_exception()
  File "/private/tmp/foo/env/lib/python3.9/site-packages/jinja2/environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "/private/tmp/foo/env/lib/python3.9/site-packages/jinja2/_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "/private/tmp/foo/env/lib/python3.9/site-packages/rpdk/java/templates/generate/POJO.java", line 22, in top-level template code
    private {{ type|translate_type }} {{ name|lowercase_first_letter|safe_reserved }};
  File "/private/tmp/foo/env/lib/python3.9/site-packages/rpdk/java/resolver.py", line 21, in translate_type
    primitive_format = PRIMITIVE_TYPES[resolved_type.type][
TypeError: unhashable type: 'OrderedSet'

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
benbridtscommented, Mar 6, 2022

Hi Brian,

Other models solve this by putting the oneOf around required, that does mean that you would not be able to define what is required based on the value of another property. Additionally, I think you have to move the Cookies definition to the definitions section (nested properties are not allowed).

I see some difficulties with allowing oneOf in properties (especially for strongly typed languages). It might be solvable, but I think the generated code would become rather complex (technically it’s allowed by the schema though, it would be nice if that changes so cfn validate catches this).

As an example: what code would you expect to be generated if you use oneOf to define a different type for one property in two different cases?

In the meantime, I think you can either only make Forward required, or do something like this, where you deviate more from the underlying API (there might be clearer ways to express the same idea)

{
  "typeName": "brian::foo::me",
  "description": "An example resource schema demonstrating some basic constructs and validation rules.",
  "sourceUrl": "https://github.com/aws-cloudformation/aws-cloudformation-rpdk.git",
  "definitions": {
    "Cookies": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "ForwardAll": {
          "description": "Set to True to forward all cookies. Defaults to False",
          "type": "boolean"
        },
        "WhitelistedNames": {
          "description": "Whitelist of cookies to forward, ForwardAll must not be set to True.",
          "items": {
            "type": "string"
          },
          "minItems": 1,
          "type": "array"
        }
      },
      "oneOf": [
        {
          "required": [
            "ForwardAll"
          ]
        },
        {
          "required": [
            "WhitelistedNames"
          ]
        }
      ]
    }
  },
  "properties": {
    "Identifier": { "type": "string" },
    "Cookies": {
      "description": "Cookie configuration.",
      "$ref": "#/definitions/Cookies"
    }
  },
  "additionalProperties": false,
  "required": [],
  "primaryIdentifier": ["/properties/Identifier"],
  "readOnlyProperties": ["/properties/Identifier"],
  "handlers": {
    "create": { "permissions": [] },
    "read": { "permissions": [] },
    "update": { "permissions": [] },
    "delete": { "permissions": [] },
    "list": { "permissions": [] }
  }
}

Edit: I think in the example, you would end up not having anything that’s required, but I’m leaving it like that, because it shows how to do “X or Y” is required

0reactions
brianterrycommented, Mar 15, 2022

@benbridts, that’s interesting.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Improve handling of oneOf · Issue #15 · OpenAPITools ...
In my opinion (for java) the Schema containing only oneOf entries ... OpenApi Client generation fails witcom-gmbh/service-access-api#10.
Read more >
Federation error codes - Apollo GraphQL Docs
If Apollo Gateway encounters an error, composition fails. This document lists subgraph validation and composition error codes, along with their root causes.
Read more >
Swagger UI freezes after API fetch and browser crashes
Show activity on this post. We had a "Point" class from NetTopologySuite. Geometries namespace that crashed the swagger. Save this answer.
Read more >
FlatBuffers: Using the schema compiler - Google
This may crash flatc given a mismatched schema. --size-prefixed : Input binaries are size prefixed buffers. --proto : Expect input files to be...
Read more >
Troubleshooting errors in AWS Glue
An ETL job must have access to an Amazon S3 data store used as a source or target. ... If AWS Glue fails...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found