Skip to content

Commit

Permalink
added soap demo
Browse files Browse the repository at this point in the history
  • Loading branch information
martypitt committed Sep 5, 2023
1 parent 89f3276 commit f8199aa
Show file tree
Hide file tree
Showing 15 changed files with 1,375 additions and 1 deletion.
Binary file added github-banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions insurance-quotes-spring-boot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

## Demo request

Send a POST to `http:localhost:7020/quotes` containing:

```json
{
"quoteId" : "123",
"occupation" : "Developer",
"parkingLocation": "Street",
"postcode" : "SW11 1NR",
"licensePlate" : "CODEZ4U"
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ file {
changeDetectionMethod=WATCH
incrementVersionOnChange=false
pollFrequency=PT5S
projects=[]
recompilationFrequencyMillis=PT3S
projects=[
{
path: "./taxi",
isEditable: true
}
]
}
1 change: 1 addition & 0 deletions soap-demo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
orbital/
233 changes: 233 additions & 0 deletions soap-demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
![Orbital banner](../github-banner.png)

# Converting SOAP to JSON, and composing multiple requests into a single API

This demo focuses on:

* Taking an old SOAP API
* Reworking the endpoints to have smaller, more resource-oriented APIs
* Publishing as RESTful JSON

After showing you the features of this demo, there's a short section breaking down exactly [how this all works](#how-this-all-works).

This demo showcases the following Orbital features:

* [Embedding Taxi within a SOAP WSDL](#embedding-taxi-in-soap)
* [Exposing a TaxiQL query as an HTTP endpoint](#exposing-a-taxiql-query-as-an-api)

If you like this demo, please [Give us a Star](https://github.com/orbitalapi/orbital) on Github!

## Running this demo

1. Clone this repo, and cd into this directory

2. Run the following docker command to start Orbital, preconfigured with this project:

```bash
docker compose up -d
```

## Things to try
After 20 seconds or so, open https://localhost:9022, and you should see Orbital's UI.

### Combining SOAP requests - Querying in the UI
Head to the [Query Editor](http://localhost:9022/query/editor) and paste the following query:

```taxi
import com.orbitalhq.CurrencyName
import com.orbitalhq.CountryFlagUrl
import com.orbitalhq.CountryName
given { iso: IsoCountryCode = "NZ"}
find {
name: CountryName
flag: CountryFlagUrl
currency: CurrencyName
}
```

Click Run, and the query will execute. In the Results panel, on the Raw tab, you should see the following results:

```json
{
"name": "New Zealand",
"flag": "http://www.oorsprong.org/WebSamples.CountryInfo/Flags/New_Zealand.jpg",
"currency": "New Zealand Dollars"
}
```

Click on the Profiler to see lineage of the query:

![Query profiler](profiler.png)

Clicking in the second tab shows the sequence diagram of calls:

![Sequence diagram](sequence.png)

Clicking on any of the calls lets you drill into the actual traffic, and see the request / response payload.

![Call details](call-details.png)

### Combining SOAP Requests - as an HTTP request

Try opening a browser (or Postman) and sending requesting this url:

http://localhost:9022/api/q/countrydata/NZ

You'll get the following JSON back:

```json
[
{
"name": "New Zealand",
"flag": "http://www.oorsprong.org/WebSamples.CountryInfo/Flags/New_Zealand.jpg",
"currency": "New Zealand Dollars",
"capital": "Wellington"
}
]
```

This works because we have the following Taxi saved query defined in `CountryData.query.taxi`:

```taxi
@HttpOperation(url = '/api/q/countrydata/{countryCode}', method = 'GET')
query countrydata(@PathVariable("countryCode") countryCode : IsoCountryCode) {
given { countryCode }
find {
name : CountryName
flag: CountryFlagUrl
currency: CurrencyName
capital: CapitalCityName
}
}
```

## How this all works
Everything starts with our Docker Compose file, and the taxi project.

### Things of note in the docker-compose file
Our `docker-compose.yml` is pretty standard, containing:
* [Orbital](https://hub.docker.com/r/orbitalhq/orbital)
* [Postgres](https://hub.docker.com/_/postgres)

Orbital is actually stateless when executing queries (which means is scales well),
but uses a database for things like History and Profiling.

There's also the following config, which is annotated

```yaml
OPTIONS: >-
## Capture the actual responses from remote calls, useful for debugging
--vyne.analytics.persistRemoteCallResponses=true
## Capture the results of queries, useful for debugging.
--vyne.analytics.persistResults=true
## Database connection options
--vyne.db.username=orbital
--vyne.db.password=changeme
--vyne.db.host=postgres
## Load the workspace.conf file in this repository
--vyne.workspace.config-file=/opt/service/workspace/workspace.conf
```
### Our Taxi project
Orbital is using a [taxi](https://taxilang.org) project which adds [semantic metadata](https://orbitalhq.com/blog/2023-05-22-semantic-metadata-101)
to our [SOAP WSDL](#embedding-taxi-in-soap).
Taxi metadata assigns tags to fields, so we can understand how data relates. Once that's present, Orbital
can use the WSDL to call the required SOAP services we need, based on the data we ask for.
Our Taxi file in `taxi/src/CountryInfoDefinitions.taxi` defines a few simple tags:

```taxi
namespace com.orbitalhq
type CurrencyIsoCode inherits String
type CurrencyName inherits String
```

These get embedded in our WSDL, and then used later when we write a query

### Embedding Taxi in Soap
Taxi can be embedded directly into SOAP WSDLs, to declare the semantic meaning of each field:

For example:

```taxi
<xs:complexType name="tCurrency">
<xs:sequence>
<xs:element name="sISOCode" type="xs:string"
> taxi:type="com.orbitalhq.CurrencyIsoCode"/>
<xs:element name="sName" type="xs:string"
> taxi:type="com.orbitalhq.CurrencyName"/>
</xs:sequence>
</xs:complexType>
```

See the actual annotated SOAP WSDL in [CountryInfoServiceSpec.wsdl](/wsdl/CountryInfoServiceSpec.wsdl).

Read more about this in the [docs](https://orbitalhq.com/docs/describing-data-sources/soap)

### Querying for data
Once the WSDL is annotated with our Taxi metadata, we can use it to write a query, as we saw when we [queried from the ui](#combining-soap-requests---querying-in-the-ui).

```taxi
given { iso: IsoCountryCode = "NZ"}
find {
// Each field comes from a different SOAP service.
// But taxi keeps this nice and succinct, composing the services
// together we need on demand
name: CountryName
flag: CountryFlagUrl
currency: CurrencyName
}
```

Try adding the `captial city` to the request. Open the profiler, and you'll see an additional
request to another SOAP endpoint to grab the data:

```diff
import com.orbitalhq.CurrencyName
import com.orbitalhq.CountryFlagUrl
import com.orbitalhq.CountryName
given { iso: IsoCountryCode = "NZ"}
find {
name: CountryName
flag: CountryFlagUrl
currency: CurrencyName
+ captial: CapitalCityName
}
```

### Exposing a TaxiQL query as an API
This project exposes a query that combines multiple SOAP operations together:

```taxi
@HttpOperation(url = '/api/q/countrydata/{countryCode}', method = 'GET')
query countrydata(@PathVariable("countryCode") countryCode : IsoCountryCode) {
given { countryCode }
find {
name : CountryName
flag: CountryFlagUrl
currency: CurrencyName
capital: CapitalCityName
}
}
```

This query is available at `http://localhost:9022/api/q/countrydata/NZ` or `http://localhost:9022/api/q/countrydata/AUD` (or whatever country code interests you)

What's more, there's even a OpenAPI spec that's been automatically generated for us, available at http://localhost:9022/api/q/meta/countrydata/oas

Read more about Orbital creating OpenAPI specs in the [docs](https://orbitalhq.com/docs/querying/queries-as-endpoints#open-api).

## Summary
Orbital is combining multiple SOAP requests together for us, and packaging them together as a simple REST API.

There's no code involved, just a little sprinkle of semantic metadata!

This is only scratching the surface of what we can do. Orbital can also stitch this data together with other APIs (such as [REST](https://orbitalhq.com/docs/describing-data-sources/open-api) / [gRPC](https://orbitalhq.com/docs/describing-data-sources/protobuf)), call [serverless functions](https://orbitalhq.com/docs/describing-data-sources/aws-services#lambda), query our [Databases](https://orbitalhq.com/docs/describing-data-sources/databases), or [Kafka queues](https://orbitalhq.com/docs/describing-data-sources/connect-kafka-topic).

If you liked this demo, remember to [Star our Github Repo](https://github/orbitalapi/orbital), and [get started](https://oribtalhq.com/docs) with Orbital now.

Binary file added soap-demo/call-details.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions soap-demo/demo-queries.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
## Querying SOAP requests

## Get country info
```taxi
import com.orbitalhq.CurrencyName
import com.orbitalhq.CountryFlagUrl
import com.orbitalhq.CountryName
given { iso: IsoCountryCode = "NZ"}
find {
name: CountryName
flag: CountryFlagUrl
currency: CurrencyName
}
```

### Saved query
```taxi
import com.orbitalhq.CapitalCityName
import com.orbitalhq.CountryFlagUrl
import com.orbitalhq.CountryName
import com.orbitalhq.IsoCountryCode
@HttpOperation(url = '/api/q/country-info-query/{countryCode}', method = 'GET')
query countries(@PathVariable("countryCode") countryCode: IsoCountryCode) {
find {
name : CountryName
flag: CountryFlagUrl
capital: CapitalCityName
}
}
```

### OpenApi spec
Available at:

`http://localhost:9022/api/q/meta/countryinfo/oas`
45 changes: 45 additions & 0 deletions soap-demo/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
version: "3.3"

services:
orbital:
image: orbitalhq/orbital:${ORBITAL_VERSION:-latest}
environment:
JAVA_OPTS: >-
-Xms256m
-Xmx1024m
OPTIONS: >-
--vyne.analytics.persistRemoteCallResponses=true
--vyne.analytics.persistResults=true
--vyne.db.username=orbital
--vyne.db.password=changeme
--vyne.db.host=postgres
--vyne.workspace.config-file=/opt/service/workspace/workspace.conf
ports:
- "9022:9022"
expose:
- 9022
volumes:
- ~/.orbital/license/:/opt/var/vyne/license/
- .:/opt/service/workspace
depends_on:
- postgres
deploy:
resources:
limits:
memory: 2gb

postgres:
image: postgres:15
expose:
- 5432
ports:
- "25432:5432"
environment:
POSTGRES_DB: orbital
POSTGRES_USER: orbital
POSTGRES_PASSWORD: changeme
volumes:
- postgres_data:/var/lib/postgresql/data

volumes:
postgres_data:
Binary file added soap-demo/profiler.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added soap-demo/sequence.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions soap-demo/taxi/src/CountryData.query.taxi
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import com.orbitalhq.CapitalCityName
import com.orbitalhq.CurrencyName
import com.orbitalhq.CountryFlagUrl
import com.orbitalhq.CountryName
import com.orbitalhq.IsoCountryCode

@HttpOperation(url = '/api/q/countrydata/{countryCode}', method = 'GET')
query countrydata(@PathVariable("countryCode") countryCode : IsoCountryCode) {
given { countryCode }
find {
name : CountryName
flag: CountryFlagUrl
currency: CurrencyName
capital: CapitalCityName
}
}
9 changes: 9 additions & 0 deletions soap-demo/taxi/src/CountyInfoDefinitions.taxi
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace com.orbitalhq {
type CurrencyIsoCode inherits String
type CurrencyName inherits String

type CountryName inherits String
type IsoCountryCode inherits String
type CapitalCityName inherits String
type CountryFlagUrl inherits String
}
3 changes: 3 additions & 0 deletions soap-demo/taxi/taxi.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: com.orbitalhq/soap-demo
version: 0.2.0
sourceRoot: src/
20 changes: 20 additions & 0 deletions soap-demo/workspace.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

file {
projects = [
{
path: "./wsdl",
loader: {
packageType: Soap
identifier: {
organisation: "com.orbitalhq"
name: "CountryInfo"
version: "0.1.20"
},
}
}
{
path: "./taxi",
isEditable: true
}
]
}
Loading

0 comments on commit f8199aa

Please sign in to comment.