TL;DR: What is the correct way to send a GET Request to do a pull subscription from a Pub/Sub server. What is the correct URL to use?
I am running a local Google Pub/Sub fake using gcloud beta emulators pubsub start
, I have been able to successfully publish to it using a ruby script I wrote, however I have been unable to do a pull subscription.
I am aiming to accomplish this just using a GET request, not a script. One of the issues I've found is there's tons of documentation on doing pull subscriptions with a client or gcloud, but very little on how to access the server by URL. Perhaps I am misunderstanding what is possible - but I want to publish a message to pub/sub using a ruby client, and then use Postman to do a GET request to the pub/sub server to retrieve the message.
I am fairly certain the issue is with how I am making a get request, but I have reproduced everything else below for context
Ruby Publishing Code
require "google/cloud/pubsub"
require 'json'
class Publisher
def publish(event)
puts "1==============>>>>>>>> publishing..."
pubsub = Google::Cloud::PubSub.new(
project_id: "grpc-demo-proj",
emulator_host: "localhost:8085"
)
topic_id = "event_topic"
topic = pubsub.topic topic_id
begin
topic.publish_async "receive_event#event",
event: JSON.generate(event) do |result|
raise "Failed to publish the message." unless result.succeeded?
puts "2==============>>>>>>>> Message published asynchronously."
end
# Stop the async_publisher to send all queued messages immediately.
topic.async_publisher.stop.wait!
rescue StandardError => e
puts "3==============>>>>>>>> Received error while publishing: #{e.message}"
end
end
end
This seems to work, as I get
1==============>>>>>>>> publishing...
DEBUG GRPC : calling localhost:8085:/google.pubsub.v1.Publisher/GetTopic
DEBUG GRPC : calling localhost:8085:/google.pubsub.v1.Publisher/Publish
2==============>>>>>>>> Message published asynchronously.
In my terminal.
I also have the Pub/Sub server running using the following shell scripts.
#!/bin/bash
# Kill the existing process if it's already running
if [ "$(lsof -i:8085)" ]; then
kill $(lsof -t -i:8085)
fi
# Kick off the new process
gcloud beta emulators pubsub start --project=grpc-demo-proj
# Connect to environment variables
$(gcloud beta emulators pubsub env-init)
PubSub Setup Script
#!/bin/bash
# Wait for the pubsub emulator to boot up
sleep 7
while [[ ! "$(lsof -i:8085)" ]]
do
echo '#===> PUBSUB EMULATOR SETUP: Waiting for PubSub Emulator to start...'
sleep 3
done
# Create topics
curl --header "Content-Type: application/json" \
--request PUT \
http://localhost:8085/v1/projects/grpc-demo-proj/topics/event_topic
# Create test subscriptions for each topic
curl --header "Content-Type: application/json" \
--request PUT \
--data '{"topic": "projects/grpc-demo-proj/topics/event_topic"}' \
http://localhost:8085/v1/projects/grpc-demo-proj/subscriptions/event_topic.test_sub1
Again. These seem to work well.
Where I have trouble... is doing a pull subscription from the pub/sub server using a GET request (Either from PostMan, or just in browser's URL bar)
http://localhost:8085/v1/projects/grpc-demo-proj/subscriptions/event_topic.test_sub1:pull
Returns
{
"error": {
"code": 400,
"message": "Invalid [subscriptions] name: (name=projects/grpc-demo-proj/subscriptions/event_topic.test_sub1:pull)",
"status": "INVALID_ARGUMENT"
}
}
But the subscription name is valid, as
http://localhost:8085/v1/projects/grpc-demo-proj/subscriptions/event_topic.test_sub1
returns
{
"name": "projects/grpc-demo-proj/subscriptions/event_topic.test_sub1",
"topic": "projects/grpc-demo-proj/topics/event_topic",
"pushConfig": {},
"ackDeadlineSeconds": 10,
"messageRetentionDuration": "604800s"
}
Which would seem to confirm the server is working, and the topics and subscriptions have been successfully created.
Although -NOT- the solution I am looking for, I tried using gcloud in command line:
bgc@jadzia:~$ gcloud beta pubsub subscriptions pull test_sub1
ERROR: (gcloud.beta.pubsub.subscriptions.pull) NOT_FOUND: Resource not found (resource=test_sub1).
Even though other sources seem to confirm this subscription does exist.
While it could possibly be an issue with Ruby incorrectly saying it successfully published the message, or something is wrong with the server. I suspect I'm just not doing the GET request correctly. I've tried several variations on the above GET request but won't list them all here.
So, without using a script - how can I get a message back from the pub/sub server? Ideally a URL for a GET request I can plug into PostMan, but command-line based solutions may also work here.
I did reproduce your local fake Pub/sub server using the all the scripts you posted. As you commented I used POST instead of GET and got a response. Pub/Sub subscriptions pull reference
POST request for subscriptions pull:
curl --header "Content-Type: application/json" \
--request POST \
--data "{
"maxMessages": "1"
}" \
http://localhost:8085/v1/projects/my-project/subscriptions/event_topic.test_sub1:pull
Pubsub Message is encoded in base 64. Take note that I ran everything (creation of pubsub server, topics, subscriber, publish of message, pulling of message) in the Google cloud shell.
EDIT 1:
As Brian mentioned, this is the request that is working for him. This works on my testing as well!
curl --header "Content-Type: application/json" \
--request POST \
localhost:8085/v1/projects/my-prject/subscriptions/event_topic.test_sub1:pull?maxMessages=5