That should be really easy.
The GCP PubSub service lets you Publish a message to a pubsub topic via a simple REST call.
POST https://pubsub.googleapis.com/v1/projects/PROJECT_ID/topics/TOPIC_ID:publish
Content-Type: application/json
Authorization: Bearer $TOKEN
{
"messages": [ {
"data": "base64-encoded-data",
"attributes": {
"key": "value",
...
}
}]
}
So you just need a target endpoint that points there. This is what I used:
<TargetEndpoint name="target-1">
<PreFlow name="PreFlow">
<Request>
<Step>
<Name>AM-Pubsub-Post-Body</Name>
</Step>
</Request>
</PreFlow>
<HTTPTargetConnection>
<!-- tell Apigee to invoke this endpoint with a Google Access Token -->
<Authentication>
<GoogleAccessToken>
<Scopes>
<Scope>https://www.googleapis.com/auth/cloud-platform</Scope>
</Scopes>
</GoogleAccessToken>
</Authentication>
<SSLInfo>
<Enabled>true</Enabled>
<IgnoreValidationErrors>false</IgnoreValidationErrors>
</SSLInfo>
<Properties>
<Property name="success.codes">2xx</Property>
<Property name="request.retain.headers">User-Agent,Referer,Accept-Language</Property>
</Properties>
<URL>https://pubsub.googleapis.com/v1/projects/{propertyset.settings.pubsub-project-id}/topics/{propertyset.settings.pubsub-topic}:publish</URL>
</HTTPTargetConnection>
</TargetEndpoint>
Inside AM-Pubsub-Post-Body, you need to base64-encode whatever it is you want to publish. And also set “target.copy.pathsuffix” to false. Maybe like this:
<AssignMessage name='AM-Pubsub-Post-Body'>
<Set>
<Payload contentType='application/json'>
{
"messages": [ {
"data": "{encodeBase64(request.content)}",
"attributes": {
"source-proxy": "{apiproxy.name}",
"source-org": "{organization.name}",
"source-env": "{environment.name}"
}
}]
}
</Payload>
</Set>
<AssignVariable>
<Name>target.copy.pathsuffix</Name>
<Value>false</Value>
</AssignVariable>
</AssignMessage>
And then you can add in your settings in the resources/properties/settings.properties file:
pubsub-topic=example-topic
pubsub-project-id=gcp-project-that-holds-pubsub-topic
Deploy your proxy with a particular service account - that allows the Authentication element in the target endpoint to do its magic. And grant that SA the role : roles/pubsub.publisher on the topic.
That works for me.
You could parameterize the topic - allow the proxy to get it from the inbound request, rather than from the properties file.
But in that case you would need to apply the role roles/pubsub.publisher on the PROJECT resource, not the TOPIC resource, for the particular SA you are using. Or just have a finite set of topics, and grant the roles/pubsub.publisher role to all topics that would get messages.