Transaction in pending state everytime - hyperledger

I am trying to perform an operation but it is not getting executed
intkey set MyKey 99
Response after performing this
{
"link": "http://127.0.0.1:8008/batch_statuses?id=59ce07c44962ed9ff56103909ab6f050bb8f4886651e5d3840a211b7604e215251448743d69362b6ee3479563d3f0967a76d5b7c63356b9e5206a0046913c341"
}
The Complete Response
{
"data": [
{
"id": "63c93b07c96199f13e493a7bd3b5fc38c281b2156868cf09b9f8165ed81704ae54dbcf5e9b42ca14a2bbf999cd3425824f9323208a18688fb0af05b9b2ec8f58",
"invalid_transactions": [],
"status": "PENDING"
}
],
"link": "http://127.0.0.1:8008/batch_statuses?id=63c93b07c96199f13e493a7bd3b5fc38c281b2156868cf09b9f8165ed81704ae54dbcf5e9b42ca14a2bbf999cd3425824f9323208a18688fb0af05b9b2ec8f58"
}
The Rest API SAYS
[2018-11-29 15:27:49.470 INFO helpers] POST /batches HTTP/1.1: 202 status, 348 size, in 0.004132 s
Settings TP
2018-11-29 15:27:08.987 INFO core] register attempt: OK
[2018-11-29 15:27:08.997 INFO handler] Setting setting
sawtooth.settings.vote.authorized_keys changed from None to 03a42a2930130b5aea1c6e753bac90467d1e4c5a774fd4713ca80ef0fabac8a8f6
Instead of 200 i am getting 202 and i have waited a long time for it to get executed but it is still in pending state

Related

ValidationTokens Missing in Notification received from Microsoft Graph Webhook

We are using Microsoft Graph (beta) Webhooks to get notified about presence changes in Microsoft Teams and have currently an issue at our customer.
When we receive the presence change notification from the Graph API it does not contain the validationTokens property, thus the validation and subsequent processing fails.
Our code is similar to the sample provided by Microsoft.
The (simplified/shortened) content of the received request at the customer looks like the following:
{
"value": [
{
"subscriptionId": "...",
"clientState": "...",
"changeType": "updated",
"resource": "communications/presences?$filter=id+in+(...)",
"subscriptionExpirationDateTime": "2021-04-22T02:06:56.2872368-07:00",
"resourceData": {
"#odata.id": "communications/presences?$filter=id+in+(...)",
"#odata.type": "#Microsoft.Graph.presence",
"id": "..."
},
"tenantId": "...",
"encryptedContent": {
"data": "...",
"dataSignature": "...",
"dataKey": "...",
"encryptionCertificateId": "3",
"encryptionCertificateThumbprint": "..."
}
}
]
}
Compared to our lab the request body is missing the validationTokens property:
{
"value": [
{
"subscriptionId": "...",
"clientState": "...",
"changeType": "updated",
"resource": "communications/presences?$filter=id+in+(...)",
"subscriptionExpirationDateTime": "2021-04-26T00:07:08.9251516-07:00",
"resourceData": {
"#odata.id": "communications/presences?$filter=id+in+(...)",
"#odata.type": "#Microsoft.Graph.presence",
"id": "..."
},
"tenantId": "...",
"encryptedContent": {
"data": "...",
"dataSignature": "...",
"dataKey": "...",
"encryptionCertificateId": "3",
"encryptionCertificateThumbprint": "..."
}
}
],
"validationTokens": [
"..."
]
}
According to the doc, validationTokens are only provided for change notifications with resource data - which is the case here, so we guess the validationTokens should be present?
Any hints are welcome.
Edit
Here is a shortened code snipped used to deserialize the request body/handle the notification request:
<HttpPost("/Notification/{connectorId}/{apiLinkId}")>
Public Async Function Listen(connectorId As Guid, apiLinkId As Guid, <FromQuery> Optional validationToken As String = Nothing) As Task(Of IActionResult)
If Not String.IsNullOrEmpty(validationToken) Then
' Validate the new subscription by sending the token back to Microsoft Graph.
' This response is required for each subscription.
Return Content(WebUtility.HtmlEncode(validationToken))
End If
Try
' Parse the received notifications.
Dim options As New JsonSerializerOptions With {.PropertyNameCaseInsensitive = True}
options.Converters.Add(New JsonStringEnumConverter(JsonNamingPolicy.CamelCase))
Dim plainNotifications As New Dictionary(Of String, ChangeNotification)()
Dim notificationCollection = Await JsonSerializer.DeserializeAsync(Of ChangeNotificationCollection)(Request.Body, options)
notificationCollection.Value _
.Where(Function(x) x.EncryptedContent Is Nothing) _
.ForEach(Sub(notification)
Dim subscription = Stores.TeamsPresenceSubscriptionStore.Instance.GetValueOrDefault(notification.SubscriptionId.Value)
' Verify the current client state matches the one that was sent.
If subscription Is Nothing OrElse notification.ClientState <> subscription.SecretClientState Then
Log.msg(Category.TEAMS, "Error: Failed to verify notification")
Return
End If
' Just keep the latest notification for each resource. No point pulling data more than once.
plainNotifications(notification.Resource) = notification
End Sub)
If plainNotifications.Count > 0 Then
' Query for the changed messages
GetChangedMessages(plainNotifications.Values)
End If
If notificationCollection.ValidationTokens IsNot Nothing AndAlso notificationCollection.ValidationTokens.Any() Then
' -> notificationCollection.ValidationTokens is not set at the customer
End If
Catch ex As Exception
' Still return a 202 so the service doesn't resend the notification.
End Try
Return Accepted()
End Function
The code to create the subscription is
Subscription = graphApi.Client.Subscriptions.Request().AddAsync(New Subscription() With
{
.Resource = $"/communications/presences?$filter=id in ({String.Join(",", userIds.Select(Function(id) $"'{id}'"))})",
.ChangeType = "updated",
.NotificationUrl = $"{publicNotificationEndpoint}/Notification/{connectorid}/{Me.GraphApi.Link.Id}",
.LifecycleNotificationUrl = $"{publicNotificationEndpoint}/LifecycleNotification/{connectorid}/{Me.GraphApi.Link.Id}",
.ClientState = SecretClientState,
.ExpirationDateTime = DateTime.UtcNow.Add(MAX_SUBSCRIPTION_LIFETIME),
.EncryptionCertificate = Convert.ToBase64String(encryptionCertificate.Export(X509ContentType.Cert)),
.EncryptionCertificateId = encryptionCertificate.Version.ToString(),
.IncludeResourceData = True
}).Result
I think this is what you are looking for subscribing to the presence API using the Change Notification API, We have developed samples in csharp and node js which have the capability to notify user when presence is updated, You can take a look at following github sample code repo graph-change-notification for your scenario.
Its kind of a late reply but the validationToken will only send to the webhook at the time of Subscription creation, after that Microsoft start sending the chang notifications and there won't be any validationToken send with the change notification. This is done just to ensure that the Notification endpoint is valid/active.
Notification endpoint validation
SS taken from: https://learn.microsoft.com/en-us/graph/webhooks

Azure JSON subprotocol `json.webpubsub.azure.v1`to join a group fetch responses programmatically

I'm trying obtain programmatically if joining the group was successfully when using json.webpubsub.azure.v1 subprotocol to join a group with a sample.
My sample JSON below, which doesn't fetch outcome success response or error response:
Basically, I'm trying to identify if joining the group was successful with the json.webpubsub.azure.v1 subprotocol.
Sample request:
{
"type": "joinGroup",
"group": "group1",
}
Yes, you can, by add “ackId” when joining the group. When the request payload contains “ackId”, the service will return an ack response to the client containing the result for this action. Make sure you use incremental “ackId”s when sending different messages.
Sample request:
{
"type": "joinGroup",
"group": "group1",
"ackId" : 1
}
Sample success response:
{
"type": "ack",
"success": true,
"ackId" : 1
}
Sample error response:
{
"type": "ack",
"success": false,
"ackId" : 1,
"error":
{
"name": "Forbidden",
"description": "The client does not have permission to join group ‘group1’"
}
}

Aws step function timeout not catched by error handler

I have the following state where the timeout is not catch nevertheless there is the catch with "States.ALL". According to here https://docs.aws.amazon.com/step-functions/latest/dg/concepts-error-handling.html
it should be. Can you tell me what is wrong?
"PublishIotCmd&WaitTask": {
"Next": "SuccedTask",
"Retry": [
{
[..]
}
],
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"ResultPath": "$.error",
"Next": "ErrorHandlerTask"
}
],
"Type": "Task",
"TimeoutSeconds": 600,
"ResultPath": "$.cmdResult",
"Resource": "arn:aws:states:::lambda:invoke.waitForTaskToken",
"Parameters": {
"FunctionName": "xx",
"Payload": {
"token.$": "$$.Task.Token",
"request.$": "$.detail"
}
}
},
On the specific case the timeout is due to the task not getting the token with sendTaskSuccess. The error is, of course, this one but "ErrorHandlerTask" is not called, the state machine just hangs.
const publishIot = new tasks.LambdaInvoke(this, 'PublishIotCmd&WaitTask', {
lambdaFunction: iotSendCommandFn,
payload: sfn.TaskInput.fromObject({
token: sfn.JsonPath.taskToken,
//request: sfn.JsonPath.entirePayload,
request: sfn.JsonPath.stringAt('$.detail'),
}),
resultPath: '$.cmdResult',
integrationPattern: sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN,
timeout: Duration.minutes(TIMEOUT_WAIT_REPLY_SECONDS),
Thank you in advance
With task tokens, I believe you're supposed to use the Heartbeat timeout rather than a general timeout.
In the docs it calls out "The "HeartbeatSeconds": 600 field sets the heartbeat timeout interval to 10 minutes." and that "If the waiting task doesn't receive a valid task token within that 10-minute period, the task fails with a States.Timeout error name."
I think since it's a different service integration Heartbeat works here.
https://docs.aws.amazon.com/step-functions/latest/dg/connect-to-resource.html#connect-wait-token

Internal server error. No devices found exception

I get the following error for iOS when I tried to send push notification via MFP console
{
"code": "FPWSE0009E",
"message": "Internal server error. No devices found.",
"productVersion": "8.0.0.00-20170220-1900"
}
The device is active . The is the result from the "Devices" API
{
"productVersion": "8.0.0.00-20170220-1900",
"totalListSize": 4,
"items": [
{
"id": "0AC11F77-A89A-4616-9085-4F6009329F3",
"lastAccessed": "2017-07-12T16:13:56.985Z",
"status": "ACTIVE",
"deviceOs": "ios 10.2.1",
"deviceModel": "iPhone",
"applicationDeviceAssociations": [
{
"appName": "RandstadJobsiOS",
"appId": "com.randstadusa.randstadjobs$ios$2.0.1",
"certSerialNumber": "",
"deviceId": "0AC11F77-A89A-4616-9085-4F6009329F3",
"status": "ENABLED",
"deviceStatus": "ACTIVE"
}
]
},
..
Push is working for android.
The iOS push certification is valid and will expire in 2018. I used the same cert in prod and receive push notification
Additionally,I tried to debug in Xcode and it does the following
MFPPush.isPushSupported -- return true
MFPPush.initialize - return success
However, it does not execute the MFPPush.registerDevice in the code
** Update
#Vivin
When the the Subscription API is executed I get the result
{
"code": "FPWSE0001E",
"message": "Not Found - The target resource 'PushDevice' does not exist. Check the '0AC11F77-A89A-4616-9085-4F6009329F3' parameter.",
"productVersion": "8.0.0.00-20170220-1900"
}
Please let me know how to debug this issue

Submitting a transaction via RESTful API (how to handle transactionid and timestamp)

Problem:
I am unable to POST a transaction via the RESTful API generated by the composer-rest-server. I am receiving statusCode 422; the transaction instance is not valid. However, the same example works in the Playground.
Scenario:
I've set up a transaction called Offer in my .cto file which posts an offer to buy a house:
// Offer - Specifies an offer that a bidder places on a house listing with an associated price
transaction Offer {
o Double bidPrice
--> HouseListing listing
--> Person bidder
}
The composer-rest-server has generated an API with the following JSON string to post a transaction of type Offer:
{
"$class": "org.acme.purchasing.Offer",
"bidPrice": 0,
"listing": "string",
"bidder": "string",
"transactionId": "string",
"timestamp": "2017-07-21T13:37:09.460Z"
}
I've since replaced this with a sample transaction using the following JSON code derived from the above example:
{
"$class": "org.acme.purchasing.Offer",
"bidPrice": 1000,
"listing": "001",
"bidder": "RJOHNSON",
"transactionId": "1b9aa63c-dfad-4aad-a610-dfc80f2796b2",
"timestamp": "2017-07-21T13:37:09.460Z"
}
The response returned is error code 422:
{
"error": {
"statusCode": 422,
"name": "ValidationError",
"message": "The `Offer` instance is not valid. Details: `transactionId` can't be set (value: \"1b9aa63c-dfad-4aad-a610-d...6b2\").",
"details": {
"context": "Offer",
"codes": {
"transactionId": [
"absence"
]
},
"messages": {
"transactionId": [
"can't be set"
]
}
},
"stack": "ValidationError: The `Offer` instance is not valid. Details: `transactionId` can't be set (value: \"1b9aa63c-dfad-4aad-a610-d...6b2\").\n at /usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/dao.js:355:12\n at ModelConstructor.<anonymous> (/usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/validations.js:566:11)\n at ModelConstructor.next (/usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/hooks.js:93:12)\n at ModelConstructor.<anonymous> (/usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/validations.js:563:23)\n at ModelConstructor.trigger (/usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/hooks.js:83:12)\n at ModelConstructor.Validatable.isValid (/usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/validations.js:529:8)\n at /usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/dao.js:351:9\n at doNotify (/usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:155:49)\n at doNotify (/usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:155:49)\n at doNotify (/usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:155:49)\n at doNotify (/usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:155:49)\n at Function.ObserverMixin._notifyBaseObservers (/usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:178:5)\n at Function.ObserverMixin.notifyObserversOf (/usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:153:8)\n at Function.ObserverMixin._notifyBaseObservers (/usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:176:15)\n at Function.ObserverMixin.notifyObserversOf (/usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:153:8)\n at Function.ObserverMixin._notifyBaseObservers (/usr/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:176:15)"
}
}
Now the strange thing is that I've deployed the same BNA onto the Hyperledger Composer Playground and am able to execute transactions of type Offer successfully.
Note that in the Playground, "transactionId" and "timestamp" are not specified as the Playground appears to take care of these values. For example, this is what Playground proposes to me initially:
{
"$class": "org.acme.purchasing.Offer",
"bidPrice": 0,
"listing": "resource:org.acme.purchasing.HouseListing#id:7965",
"bidder": "resource:org.acme.purchasing.Person#id:4441"
}
Can anyone advise why it's saying the Offer instance is not valid? My first thought was that it's not liking the string I'm placing in "transactionId" but another Stack Overflow post points out that the transactionId is just an arbitrary UUIDv4 string which I've generated already.
Update #1: Failing even with default demo
In order to ensure by BNA is error-free, I've deployed the default carauction-demo (resembles my example closely) onto my local Hyperledger Fabric instance and deployed the composer-rest-server. I've also deployed the same BNA into the Playground. All assets and participants were created identical in both from the Explorer (local instance) and Playground. When it comes time to submit an Offer transaction:
{
"$class": "org.acme.vehicle.auction.Offer",
"bidPrice": 800,
"listing": "resource:org.acme.vehicle.auction.VehicleListing#L001",
"member": "resource:org.acme.vehicle.auction.Member#member3#acme.org"
}
This JSON was generated by the Playground and succeeds there. Copy/paste/executing into the Explorer yields a status 500 error.
{
"error": {
"statusCode": 500,
"name": "Error",
"message": "error trying invoke chaincode. Error: chaincode error (status: 500, message: Error: Object with ID 'string' in collection with ID 'Asset:org.acme.vehicle.auction.VehicleListing' does not exist)",
"stack": "Error: error trying invoke chaincode. Error: chaincode error (status: 500, message: Error: Object with ID 'string' in collection with ID 'Asset:org.acme.vehicle.auction.VehicleListing' does not exist)\n at _initializeChannel.then.then.then.then.catch (/usr/lib/node_modules/composer-rest-server/node_modules/composer-connector-hlfv1/lib/hlfconnection.js:806:34)"
}
}
I'm still at a lost as to what is wrong here.
After much experimentation and some searching, I've concluded that the problem was that NPM was installed using sudo (as root). I redid the installation as non-root and the problem has now been solved. Everything is working as expected.
Composer updates the transactionId itself as its generated, you cannot do this in your JSON and hence why you get the error. This is a Loopback -> Swagger conversion issue as it should not appear in a /POST REST operation - captured here https://github.com/hyperledger/composer/issues/663
So I have successfully executed Offer transactions (/POST). I think the '500' error is because there is a missing field ('string' type), or relationship in your Offer transaction via REST.
Using the example of the Car Auction network https://github.com/hyperledger/composer-sample-networks/blob/master/packages/carauction-network/models/auction.cto
Either of these Offer transactions using /POST were successful in Explorer:
{
"$class": "org.acme.vehicle.auction.Offer",
"bidPrice": 20,
"listing": "org.acme.vehicle.auction.VehicleListing#100",
"member": "org.acme.vehicle.auction.Member#a#b.com"
}
OR
{
"$class": "org.acme.vehicle.auction.Offer",
"bidPrice": 20,
"listing": "org.acme.vehicle.auction.VehicleListing#100",
"member": "org.acme.vehicle.auction.Member#a#b.com",
"timestamp": "2017-07-28T14:07:02.558Z"
}
responded with a 200 (SUCCESS) and a transactionId in Explorer:
{
"$class": "org.acme.vehicle.auction.Offer",
"bidPrice": 20,
"listing": "org.acme.vehicle.auction.VehicleListing#100",
"member": "org.acme.vehicle.auction.Member#a#b.com",
"transactionId": "e75b9934-1f08-4daf-90db-702bbe4b8fa1"
}
This is my VehicleListing asset JSON for #100 above
{
"$class": "org.acme.vehicle.auction.VehicleListing",
"listingId": "100",
"reservePrice": 50,
"description": "string",
"state": "FOR_SALE",
"offers": [
{
"$class": "org.acme.vehicle.auction.Offer",
"bidPrice": 50,
"listing": "100",
"member": "resource:org.acme.vehicle.auction.Member#a#b.com",
"transactionId": "string123",
"timestamp": "2017-07-28T14:07:02.825Z"
}
],
"vehicle": "resource:org.acme.vehicle.auction.Vehicle#123"
}
And I created asset for Vehicle 123 as well as Member a#b.com

Resources