lumnik. / scenarios All scenarios · Français

An old Spring MVC app returns the whole list at once and one line reads it

Goal Read the vets of Spring PetClinic, a Spring MVC app from before Spring Boot, without touching its code.

Spring PetClinic as it was before Spring Boot: a WAR on Tomcat. Its controller answers the whole list at once, no pages.

manifests/lab-docker-compose.yml
# The clinic's application: Spring PetClinic of before Spring Boot, a WAR on Tomcat 11.name: lumnik-legacy-petclinicservices:  petclinic:    build: ../run/petclinic    ports: ["127.0.0.1:${PETCLINIC_PORT:-9300}:8080"]   # this machine only
manifests/10-vets-xml.yaml
apiVersion: connectors.lumnik.io/v1kind: Connectormetadata:  name: scenario-legacy-petclinic-a  connector_type: rest-generic  scopes: [clinic]spec:  base_url: http://host.docker.internal:9300/petclinic  endpoints:    - id: vets      path: /vets.xml                                   # the address the clinic's team knows      method: GET      pagination: { kind: none, response_path: $.vetList }      target:        kind: hybrid        table: ext.scenario_legacy_petclinic_a        unique_key: $.id        promote:          - { name: first_name, path: $.firstName, type: text }          - { name: last_name, path: $.lastName, type: text }
$ lm source rest probe scenario-legacy-petclinic-a --endpoint /vets.json
# Drafted by lm source rest probe — review before applying
- id: vets-json
  method: GET
  path: /vets.json
  pagination: { kind: none, response_path: $.vetList }   # 6 items, no paging signal in the answer: if the source pages, declare how
  target:
    kind: hybrid
    table: ext.scenario_legacy_petclinic_a_vets_json
    unique_key: $.id
    promote:
      - { name: firstname, path: $.firstName, type: text }
      - { name: id, path: $.id, type: bigint }
      - { name: lastname, path: $.lastName, type: text }
      - { name: new, path: $.new, type: boolean }
      - { name: nrofspecialties, path: $.nrOfSpecialties, type: bigint }
manifests/20-vets-json.yaml
apiVersion: connectors.lumnik.io/v1kind: Connectormetadata:  name: scenario-legacy-petclinic-a  connector_type: rest-generic  scopes: [clinic]spec:  base_url: http://host.docker.internal:9300/petclinic  endpoints:    - id: vets      path: /vets.json                                  # the same controller, its JSON view      method: GET      pagination: { kind: none, response_path: $.vetList }   # the whole list in one answer      target:        kind: hybrid        table: ext.scenario_legacy_petclinic_a        unique_key: $.id        promote:          - { name: first_name, path: $.firstName, type: text }          - { name: last_name, path: $.lastName, type: text }          - { name: specialties, path: $.nrOfSpecialties, type: integer }

Limits

  • The hub does not read XML: here, the same app also answers JSON.
  • kind: none reads one request: if the source pages, declare how.
  • PetClinic's demo data: 6 vets.

Clinic · vets

The clinic runs on an old Spring app.

Its vets must be read, every night.

Spring PetClinic, from before Spring Boot

The problem

The app was written before modern APIs.

  • It answers XML or JSON.
  • The whole list at once, no pages.

What is not changed

The app stays as it is.

  • A WAR on Tomcat.
  • Spring MVC configured in XML.

The first try

The known address answers XML.

  • The hub reads JSON.
  • It refuses and says so, instead of reading 0 rows.

The probe

lm source rest probe … --endpoint /vets.json

The probe finds the list.

It drafts kind: none: no sign of pages in the answer.

What had to be written

pagination: { kind: none, response_path: $.vetList }

One line.

  • 6 vets, one request.
  • A 23-line connector.

The limit

The hub does not read XML.

  • Here, the same app also answers JSON.
  • If the source pages, declare how.

Try it

The scenario replays locally.

Every step is published with its output.

This scenario runs on lumnik Open, free and open source.

Try lumnik Open →