I have tried to send messages to various connections via unification engine and it works fine. It's mentioned here (https://developer.unificationengine.com/) that its possible to send only one message to unification engine mentioning various connections and it sends it to respective social media apps. However, I am not able to find a way to get it to work. Please advise if anyone has tried.
Appreciate your help!
Thanks & Best Regards,
Anand Patil
It is possible to send same message to multiple connections via unification engine.
The following command will send the same messsage to two facebook connections and a twitter connection
curl -XPOST https://apiv2.unificationengine.com/v2/message/send --data "{ \"message\": {
\"receivers\": [
{\"name\": \"Me\", \"address\": \"\" , \"Connector\": \"UNIQUE_CONNECTION_IDENTIFIER_FACEBOOK_1\"},
{\"name\": \"Me\", \"address\": \"\" , \"Connector\": \"UNIQUE_CONNECTION_IDENTIFIER_FACEBOOK_2\"},
{\"name\": \"name\", \"address\": \"TWITTER_HANDLE\" , \"Connector\": \"UNIQUE_CONNECTION_IDENTIFIER_TWITTER_1\"}
],
\"parts\":
[{\"id\": \"1\",\"contentType\": \"text/plain\", \"data\":\"MESSAGE_BODY\" ,\"size\": MESSAGE_BODY_SIZE,\"type\": \"body\",\"sort\":0}]
}}" -u USER_ACCESSKEY:USER_ACCESSSECRET -k
Related
I have managed to deploy the appication with back4app as well as got it web-hosted there. However, I can't access the routes of my API (BookReadingApp). Every time I try to access any route I get an error: {"error": "unathorized"}
403 error persists no matter what type of request I'm trying to send to the server (get, post, put, patch, delete). The same thing applies to every error I get when trying to send the wrong request to the routes that don't exist (for testing purposes only).
Console logs show that "Database was connected successfully" and the server was launched with no errors (as I pointed out in my app.js file to know that api works as expected).
Please, help me to resolve this issue - any help is highly appreciated.
Kind Regards
Vladyslav
I tried testing API (with POSTMAN and in Chrome) intentionally sending the wrong requests - the error does not change: it's always 'unathorized' (403). The console of the application shows that the server started successfully and that DB was also connected.
unauthorized always said when something internally failed or when you use the cloud functions and didn't specify the keys in the header:
curl -X POST \
-H "X-Parse-Application-Id: key_here" \
-H "X-Parse-REST-API-Key: key_here" \
-H "Content-Type: application/json" \
-d "{}" \
https://parseapi.back4app.com/functions/hello
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 https://pubsub.googleapis.com/v1/{subscription}:pull
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
Output of subscriptions 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
Output:
Disclaimer: I have no prior experience in software development whatsoever and am tasked to develop a blockchain application since 4 months ago. Please forgive my lack of knowledge regarding most thing.
I am currently building a web application to interact with Hyperledger Fabric. I have managed to spin up docker containers for the peer, orderer nodes etc, each defined in the connection profile, with their own localhost ports.
I am also developing a simple front end and server side restAPI on the get go and has achieved functionality that allows the user to login and have their user context set and perform some application specific function.
For the Blockchain aspect of the project, I am trying to modify the "balance transfer" (https://github.com/hyperledger/fabric-samples/blob/release-1.4/balance-transfer/app.js) example in the fabric sample for my use case.
So far, I have managed to establish the "Channel Creation" endpoint to allow an administrator on the web application to perform channel creation through the use Hyperledger fabric SDK by uploading the channel.tx file.
But I am lost when I have to join the peers to the channel. The fabric sample example has the following code.
// Join Channel
app.post('/channels/:channelName/peers', async function(req, res) {
logger.info('<<<<<<<<<<<<<<<<< J O I N C H A N N E L >>>>>>>>>>>>>>>>>');
var channelName = req.params.channelName;
var peers = req.body.peers;
logger.debug('channelName : ' + channelName);
logger.debug('peers : ' + peers);
logger.debug('username :' + req.username);
logger.debug('orgname:' + req.orgname);
if (!channelName) {
res.json(getErrorMessage('\'channelName\''));
return;
}
if (!peers || peers.length == 0) {
res.json(getErrorMessage('\'peers\''));
return;
}
let message = await join.joinChannel(channelName, peers, req.username, req.orgname);
res.send(message);
});
According to a snippet from the testAPI.sh script
(https://github.com/hyperledger/fabric-samples/blob/release-1.4/balance-transfer/testAPIs.sh)
echo "POST request Join channel on Org1"
echo
curl -s -X POST \
http://localhost:4000/channels/mychannel/peers \
-H "authorization: Bearer $ORG1_TOKEN" \
-H "content-type: application/json" \
-d '{
"peers": ["peer0.org1.example.com","peer1.org1.example.com"]
}'
echo
echo
echo "POST request Join channel on Org2"
echo
curl -s -X POST \
http://localhost:4000/channels/mychannel/peers \
-H "authorization: Bearer $ORG2_TOKEN" \
-H "content-type: application/json" \
-d '{
"peers": ["peer0.org2.example.com","peer1.org2.example.com"]
}'
echo
echo
It seems that the peer names (which have to be specified in the connection profile) are provided as request to join the peers to the channel. Which does not quite make sense to me, since I envision peers to be like "users of different IP" accessing the web application. Specifying which peers to join the channel by providing their connection profile reference name appears to be a static (hard-coded, non-dynamic) approach.
What I do not understand is: How can I assign the authenticated user to their individual peer context, and with their own peer context set on the web application, the users are able to join the channel on their own?
The fabric tutorials only perform the switching of peer context through CLI, and join the peers to channel through CLI as well.
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin#org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:9051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt peer channel join -b mychannel.block
How can I achieve switching of peer context through the Hyperledger Fabric SDK? or even 1 peer context to 1 authenticated user, and logging in as another user will mean that the peer context is changed to the other user that is currently authenticated.
I can't seem to wrap my head around what is a peer in physical sense in such a decentralized setup. Please provide detailed and laymen explanation for me to understand the concept as much as possible. Much thanks!
think of the blockchain network, as a backend database(ledger DB) that your web application (remote, in a network IP context, to the peers that write to the ledger) needs to interact with. What your application needs to know is: - what is the connection info (profile), how do I connect, what is the smart contract to interact with, and what transaction function(s) (in that contract) do I want to invoke, to write to the ledger (or query, to read etc).
The balance transfer app is largely a sample application/exercise in using the Fabric SDK to demonstrate (programatically) basic functionalities of a H/Fabric blockchain network, such as creating channel(s), installing chaincode (smart contract) , instantiating chaincode , invoking chaincode and querying chaincode.
Your web application wants to interact with your running Fabric blockchain network (backend). So with that, I suggest to look at the following resources to get a better understanding of what you're trying to achieve.
1) Read the documentation at https://hyperledger-fabric.readthedocs.io/en/release-1.4/write_first_app.html to grasp the concepts and read the logical flow of the writing your first application using Hyperledger Fabric 1.4 new programming model (designed to make writing apps easier without having to have specialist 'blockchain' dev knowledge).
2) Try out the sample Fabcar application as introduced here (elements include the contract, the network, and the SDK APIs interacting (eg. submit txns, query the ledger) with the contract deployed to the peers) -> https://hyperledger-fabric.readthedocs.io/en/release-1.4/understand_fabcar_network.html . The actual Fabcar sample app is here -> https://github.com/hyperledger/fabric-samples/tree/release-1.4/fabcar (and the connection profile provided, connects to the Fabric BYFN network 'stood up' using startFabric.sh there).
3) Once your web application is able to interact (without application level authentication initially), you can proceed to implement your authentication strategy of choice for your web app/front end. Once authenticated in your app, the application users use wallets (containing an X509 cert/key combo) to interact with the blockchain. This sample out on Github https://github.com/IBM/build-blockchain-insurance-app should assist you with understanding the app architecture and what components belong where.
After couchdb upgrade it was no longer possible to create new databases or update _security of old databases.
I've just run into this with CouchDB 2.1.1. My problem was that the security object I was attempting to pass in was malformed.
From https://issues.apache.org/jira/browse/COUCHDB-2326,
Attempts to write security objects where the "admins" or "members" values are malformed will result in an HTTP 500 response with the following body:
{"error":"error","reason":"no_majority"}
This should really be an HTTP 400 response with a "bad_request" error value and a different error reason.
To reproduce:
$ curl -X PUT http://localhost:15984/test
{"ok":true}
$ curl -X PUT http://localhost:15984/test/_security -d '{"admins":[]}'
{"error":"error","reason":"no_majority"}
Yet another reason could be that old nodes were lingering in _membership configuration.
I.e., _membership showed:
{
"all_nodes": [
"couchdb#localhost"
],
"cluster_nodes": [
"couchdb#127.0.0.1",
"couchdb#localhost"
]
}
when it should show
{
"all_nodes": [
"couchdb#localhost"
],
"cluster_nodes": [
"couchdb#localhost"
]
}
Doing a deletion of the bad cluster node as described in docs helped.
Note, that _nodes might not be available on port 5984, but on 5986 only.
For a PUT to /db/_security, if the user is not a a db or server admin, the response is HTTP status 500 with {"error":"error","reason":"no_majority"} but the server logs are more informative, including: {forbidden,<<"You are not a db or server admin.">>}
One reason could be couchdb process reached its maximum number of open files, which lead to read errors and (wrongly) no_majority errors.
Another reason could be that the server switched from single node configuration to multiple node configuration (for example during an upgrade).
Changing back number of nodes to 1 helped
How to send a push notification to a channel in unificationengine?
If a user is already created the channel via UE.
Example for pushing messages to UE
curl -XPOST https://apiv2.unificationengine.com/v2/push/notification -u CONNECTOR_KEY:CONNECTOR_SECRET –data “{ \"channel\”: \“6d2d2111-d3b6-4ac9-8e67-55980a141fdd_sms\”, \“data\”: \“test message\”}“ -k
The documentation for push messages is given in Connector section in https://developer.unificationengine.com.