category: Tutorial
name: example
method: POST
uri: /examples
routing_auto_generation_mode: true
spec:
  response:
    normal:
      codes:
      - 202
global_variables:
  hogeID:
    description: hoge resource ID
    initial: null
  name:
    description: resource name
    initial: null
  region:
    description: region name
    initial: null
transaction:
  async: true
  auto_response: false
  enable: true
commands:
- command: request_validation
  label: Order Validation
  kwargs:
    aspect_options:
      post:
        process: |-
          (name, region) = (context.request.body.name, context.request.body.region)
    body:
      properties:
        description:
          type: string
        name:
          pattern: ^[A-Z][a-zA-Z_0-9-]+$
          type: string
        region:
          enum:
          - jp1
          - jp2
          type: string
      required:
      - name
      - region
      type: object
    headers:
      properties:
        Content-Type:
          enum:
          - application/json
          type: string
      required:
      - Content-Type
      type: object
- command: script
  label: Create Hoge
  kwargs:
    code: |-
      faker("ExampleFaker")
      await atom.Example(**context.request.body.dictionary).save()

      faker("postHoge")
      r = await callout(path="/hoges", method="POST", body=dict(name=name, region=region))
      if r.error:
          raise Error(r.code, reason="POST failed")

      hogeID = MU(json.loads(r.body)).hogeID
      context.session.set_status(202)
      context.session.finish(dict(hogeID=hogeID))
    cancellation:
      cancellable: true
      actions:
      - action_type: script
        code: |-
          if hogeID:
              faker("getHoge")
              r = await callout(path="/hoges/{}".format(hogeID))
              if r.error and r.code != 404:
                  raise Error(r.code, reason="Unable to get hoge %r" % hogeID)
              if r.code!=404:
                  faker("deleteHoge")
                  r = await callout(path="/hoges/{}".format(hogeID), method="DELETE")
                  if r.error and r.code != 404:
                      raise Error(r.code, reason="Unable to delete hoge %r" % hogeID)

              for i in range(30):
                  faker("getHogeWaitForNotFound")
                  r = await callout(path="/hoges/{}".format(hogeID))
                  if r.error and r.code==404:
                      faker("ExampleFaker")
                      example = await atom.Example.load(name)
                      if example is not None:
                          faker("ExampleFaker")
                          await example.destroy()
                          return
                  await asyncio.sleep(1)
              raise Error(500, reason="Status poll retry over")
- command: script
  label: Wait for Active State
  kwargs:
    code: |-
      for i in range(30):
          faker("getHogeWaitForActive")
          r = await callout(path="/hoges/{}".format(hogeID))
          if r.error:
              continue
          hoge = MU(json.loads(r.body))
          if hoge.status == "Active":
              return
          elif hoge.status == "Error":
              raise Error(500, reason="Transited to Error state")
          await asyncio.sleep(1)
      raise Error(500, reason="Status poll retry over")
- command: script
  label: Update Order
  kwargs:
    code: |-
      faker("ExampleFaker")
      example = await atom.Example.load(name)
      (example.hogeID, example.createdAt) = (hogeID, clock.now())

      faker("ExampleFaker")
      await example.save()