Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hive Gateway subscriptons not working #7673

Open
4 tasks
klys-equinix opened this issue Sep 12, 2024 · 7 comments
Open
4 tasks

Hive Gateway subscriptons not working #7673

klys-equinix opened this issue Sep 12, 2024 · 7 comments

Comments

@klys-equinix
Copy link

Issue workflow progress

Progress of the issue based on the
Contributor Workflow

Make sure to fork this template and run yarn generate in the terminal.

Please make sure Mesh package versions under package.json matches yours.

  • 2. A failing test has been provided
  • 3. A local solution has been provided
  • 4. A pull request is pending review

Describe the bug

Graphql subscriptions do not work. If i try to run the subscription through GraphiQL, the response is 404
Screenshot 2024-09-12 at 10 09 13

The OpenTelemetry logs are as follows:

{
resource: {
attributes: {
'service.name': 'Gateway',
'telemetry.sdk.language': 'nodejs',
'telemetry.sdk.name': 'opentelemetry',
'telemetry.sdk.version': '1.25.1',
'process.pid': 6,
'process.executable.name': 'node',
'process.executable.path': '/usr/local/bin/node',
'process.command_args': [ '/usr/local/bin/node', '/serve/bin.mjs', 'supergraph' ],
'process.runtime.version': '22.8.0',
'process.runtime.name': 'nodejs',
'process.runtime.description': 'Node.js',
'process.command': '/serve/bin.mjs',
'process.owner': 'node',
'host.name': 'hive-gateway-external-66984f7fd-5w5hb',
'host.arch': 'amd64'
}
},
instrumentationScope: { name: 'gateway', version: undefined, schemaUrl: undefined },
traceId: '5a5a8607eaa73a972e9cf13cb7f104e7',
parentId: undefined,
traceState: undefined,
name: 'GET /gateway/graphql',
id: 'a2a1816dfb7b25ec',
kind: 1,
timestamp: 1726128168069000,
duration: 2460.951,
attributes: {
'http.method': 'GET',
'http.url': 'http://localhost/gateway/graphql?query=subscription+test%7BinventoryEvents%7B...on+CabinetStatusChangedEvent%7BeventId+cabinetId+previousStatusId+currentStatusId%7D...on+CageStatusChangedEvent%7BeventId+cageId+previousStatusId+currentStatusId%7D%7D%7D&operationName=test&extensions=%7B%7D',
'http.route': '/gateway/graphql',
'http.scheme': 'http:',
'net.host.name': 'localhost',
'http.host': 'localhost',
'http.client_ip': '10.249.0.4',
'http.user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:130.0) Gecko/20100101 Firefox/130.0',
'http.status_code': 404
},
status: { code: 2, message: 'Not Found' },
events: [],
links: []
} 

Queries for the same subgraph that provides this subscription work correctly.
Subscribing directly to subgraph works correctly


**To Reproduce** Steps to reproduce the behavior:

Run Hive Gateway with at least one subgraph implementing subscriptions using websocket transport.
Configure Hive Gateway with endpoint:

gateway.config.ts: |
import {defineConfig, type WSTransportOptions, createStdoutExporter} from '@graphql-hive/gateway'

export const gatewayConfig = defineConfig({
  transportEntries: {
    // use "*.http" to apply options to all subgraphs with HTTP
    '*.http': {
      options: {
        subscriptions: {
          kind: 'ws',
          location: '/graphql'
        } satisfies WSTransportOptions
      }
    }
  },
  openTelemetry: {
    exporters: [
      // A simple output to the console.
      // You can add more exporters here, please see documentation below for more examples.
      createStdoutExporter()
    ],
    spans: {
      http: true, // Whether to track the HTTP request/response
      graphqlParse: true, // Whether to track the GraphQL parse phase
      graphqlValidate: true, // Whether to track the GraphQL validate phase
      graphqlExecute: true, // Whether to track the GraphQL execute phase
      subgraphExecute: true, // Whether to track the subgraph execution phase
      upstreamFetch: true // Whether to track the upstream HTTP requests
    }
  }
})

**Expected behavior**

Subscriptions work correctly

**Environment:**

- OS:
- Hive Gateway Docker


@ardatan
Copy link
Owner

ardatan commented Sep 12, 2024

Could you give more details about your subgraphs?
Do they use graphql-ws protocol? Or maybe they use the legacy subscriptions-transport-ws?

@klys-equinix
Copy link
Author

There is only one subgraph serving subscriptions. It is based on graphql-ws protocol

https://docs.spring.io/spring-graphql/reference/transports.html#server.transports.websocket

But it seems like the gateway is not even trying to call it

@ardatan
Copy link
Owner

ardatan commented Sep 12, 2024

Have you tried to make the HTTP request with curl or some other http client?

@klys-equinix
Copy link
Author

klys-equinix commented Sep 12, 2024

I tried making a request with Postman GraphQL client.
There is says that gateway responded with incorrect response code 200 instead of 101
Screenshot 2024-09-12 at 18 23 45

Here are the logs from this request

{
resource: {
attributes: {
'service.name': 'Gateway',
'telemetry.sdk.language': 'nodejs',
'telemetry.sdk.name': 'opentelemetry',
'telemetry.sdk.version': '1.25.1',
'process.pid': 6,
'process.executable.name': 'node',
'process.executable.path': '/usr/local/bin/node',
'process.command_args': [ '/usr/local/bin/node', '/serve/bin.mjs', 'supergraph' ],
'process.runtime.version': '22.8.0',
'process.runtime.name': 'nodejs',
'process.runtime.description': 'Node.js',
'process.command': '/serve/bin.mjs',
'process.owner': 'node',
'host.name': 'hive-gateway-external-7664cc5d55-89g5m',
'host.arch': 'amd64'
}
},
instrumentationScope: { name: 'gateway', version: undefined, schemaUrl: undefined },
traceId: '4fce12dacd20a8c23d04f77f0cdddbf9',
parentId: undefined,
traceState: undefined,
name: 'GET /gateway/graphql',
id: 'c16e61a8e3b4aaaf',
kind: 1,
timestamp: 1726157965615000,
duration: 732.977,
attributes: {
'http.method': 'GET',
'http.url': 'http://localhost/gateway/graphql',
'http.route': '/gateway/graphql',
'http.scheme': 'http:',
'net.host.name': 'localhost',
'http.host': 'localhost',
'http.client_ip': '10.249.0.4',
'http.user_agent': 'PostmanClient/undefined (AppId=6217ee3f-4ef9-4f3d-b10a-c0582107b1ea)',
'http.status_code': 200
},
status: { code: 1, message: undefined },
events: [],
links: []
}

@klys-equinix
Copy link
Author

Can you give me an example of correct curl for querying subscription on gateway?

@ardatan
Copy link
Owner

ardatan commented Sep 12, 2024

curl 'http://localhost:4000/graphql' \
  -H 'accept: text/event-stream' \
  -H 'content-type: application/json' \
  --data-raw '{"query":"subscription OnProductPriceChanged { productPriceChanged { name price reviews { score } } }","operationName":"OnProductPriceChanged"}'

You can initiate an SSE connection as in here with curl.

Regarding the error in the screenshots you shared above;
In there, you are trying to connect the gateway via WebSockets not SSE.
We only support the actively developed graphql-ws only not deprecated subscriptions-transport-ws .
I am not sure which one Postman uses there.

@klys-equinix
Copy link
Author

Hi, I tried forming the request like in the curl you described.
This resulted in error:

event: next
data: {"errors":[{"message":"Cannot find package '@graphql-mesh/transport-ws' imported from /node_modules/.chunk/createGatewayRuntime-DfdVdZl2.mjs","locations":[{"line":1,"column":20}],"path":["inventoryEvents"]}]}

event: complete
data:

And in the logs:

[2024-09-13T09:21:43.876Z] DEBUG vdc-inventory-service - 430ed7d622f261c84c120254f2868472 subgraph-execute {
query: 'subscription test2{inventoryEvents{__typename ...on CabinetStatusChangedEvent{eventId}}}',
variables: {}
}
[2024-09-13T09:21:43.876Z] DEBUG Loading transport "ws" for subgraph vdc-inventory-service
[2024-09-13T09:21:43.877Z] HOOKS Trying default resolve for "@graphql-mesh/transport-ws"
[2024-09-13T09:21:43.879Z] DEBUG Processing GraphQL Parameters done.
[2024-09-13T09:21:43.878Z] HOOKS Trying default resolve for "@graphql-mesh/transport-ws" failed; trying alternatives
[2024-09-13T09:21:43.878Z] HOOKS Trying "@graphql-mesh/transport-ws.ts" 

This likely means two things:

  1. The docker image is missing the transport-ws package
  2. The GraphiQL provided with the Gateway is not compatible with how the Gateway handles subscriptions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants