I’m using Hyperledger Fabric Java SDK to get a transaction by txId. The return object includes Transaction Information.
TransactionInfo txInfo = channel.queryTransactionByID(txId);
Common.Envelope envelope = txInfo.getEnvelope();
Common.Payload payload = Common.Payload.parseFrom(envelope.getPayload());
The Payload message includes headers and data. I can parse headers by using Common.Header.ChannelHeader and Common.Header.SignatureHeader.
Common.ChannelHeader channelHeader = Common.ChannelHeader.parseFrom(payload.getHeader().getChannelHeader());
Common.SignatureHeader signatureHeader = Common.SignatureHeader.parseFrom(payload.getHeader().getSignatureHeader());
The problem is, I cannot see any message type to get data from Payload.
My expectation would be like,
SomeMessage someMsg = SomeMessage.parseFrom(payload.getData());
What is the ideal approach to get a data object?
Thanks to Driden Myung's tip, Finally found a way to parse QSCC responses into TxReadWriteSet or even KVRWSet !!
Here is an example:
TransactionInfo txInfo = channel.queryTransactionByID(txId);
Common.Envelope envelope = txInfo.getEnvelope();
Common.Payload payload = Common.Payload.parseFrom(envelope.getPayload());
FabricTransaction.Transaction transaction = FabricTransaction.Transaction.parseFrom(payload.getData());
FabricTransaction.TransactionAction action = transaction.getActionsList().get(0); // 0 is a index
FabricTransaction.ChaincodeActionPayload chaincodeActionPayload = FabricTransaction.ChaincodeActionPayload.parseFrom(action.getPayload());
FabricProposalResponse.ProposalResponsePayload prp = FabricProposalResponse.ProposalResponsePayload.parseFrom(chaincodeActionPayload.getAction().getProposalResponsePayload());
FabricProposal.ChaincodeAction ca = FabricProposal.ChaincodeAction.parseFrom(prp.getExtension());
Rwset.TxReadWriteSet txrws = Rwset.TxReadWriteSet.parseFrom(ca.getResults());
TxReadWriteSetInfo txrwsInfo = new TxReadWriteSetInfo(txrws);
KvRwset.KVRWSet kvrwSet = txrwsInfo.getNsRwsetInfo(0).getRwset();
KvRwset.KVWrite kvWrite = kvrwSet.getWrites(0);
String writeVal = kvWrite.getValue().toStringUtf8();
I found the answer.
FabricTransaction.Transaction transaction = FabricTransaction.Transaction.parseFrom(payload.getData());
After that,
FabricTransaction.TransactionAction action = transaction.getActionsList().get(index);
FabricTransaction.ChaincodeActionPayload chaincodeActionPayload = FabricTransaction.ChaincodeActionPayload.parseFrom(action.getPayload());
chaincodeActionPayload.getAction().getEndorsementsList().forEach(endorsement -> {
// This is my current point
???? endorser = ????.parseFrom(endorsement.getEndorser());
});
Let me add if I can find more. Anybody add comments welcome.
We have faced a similar problem to get the request data from a transaction.
The following code will help to get the transaction request data of a transaction
Fabric SDK version : 2.1.4
// get transaction from transaction ID
TransactionInfo txInfo = channel.queryTransactionByID(txId);
// transaction is stored inside the envelope containing the payload and signature
Common.Envelope envelope = txInfo.getEnvelope();
// parse payload from the envelope
Common.Payload payload = Common.Payload.parseFrom(envelope.getPayload());
// payload contains Header and Data. We are parsing data to get the transaction
TransactionPackage.Transaction transaction = TransactionPackage.Transaction.parseFrom(payload.getData());
// get first action from the transaction action list. it contains input and other details
TransactionPackage.TransactionAction action = transaction.getActionsList().get(0); // 0 is a index
// chaincode action payload contains input parameters. So we are taking the action payload
TransactionPackage.ChaincodeActionPayload chaincodeActionPayload = TransactionPackage.ChaincodeActionPayload.parseFrom(action.getPayload());
// chaincode ProposalPayload contains Input and TransientMap. We are parsing actionPayload to proposalPayload
ProposalPackage.ChaincodeProposalPayload prp = ProposalPackage.ChaincodeProposalPayload.parseFrom(chaincodeActionPayload.getChaincodeProposalPayload());
// parse the input to chaincodeInvocationSpec so that we can unmarshal the input
Chaincode.ChaincodeInvocationSpec chaincodeInvocationSpec = Chaincode.ChaincodeInvocationSpec.parseFrom(prp.getInput());
// get the input and parse the arg list and get input arguments
chaincodeInvocationSpec.getChaincodeSpec().getInput().getArgsList().get(ChaincodeInput.ARGS_FIELD_NUMBER).toStringUtf8();
Related
I'm implementing a data extraction from Google Analytics using Java and I'm following this example: https://developers.google.com/analytics/devguides/reporting/core/v4/quickstart/service-java
I managed to extract the data I need but I can't figure out how to set the start-index using its client. Below you can see the changed I made to the default implementation. I can set the page size but I can't find out how to set the start-index.
public GetReportsResponse getReport(String dateStart, String dateEnd) throws IOException {
String[] metricsArr = {"ga:users", "ga:newUsers", "ga:sessions", "ga:totalEvents"};
String[] dimensionsArr = {"ga:eventLabel","ga:eventCategory","ga:eventAction", "ga:country", "ga:countryIsoCode", "ga:dateHourMinute"};
// Create the DateRange object.
DateRange dateRange = new DateRange();
dateRange.setStartDate(dateStart);
dateRange.setEndDate(dateEnd);
// Create the Metrics object.
ArrayList<Metric> metrics = new ArrayList<Metric>();
for(String item : metricsArr){
Metric m = new Metric().setExpression(item).setAlias(item.replace("ga:", ""));
metrics.add(m);
}
ArrayList<Dimension> dimensions = new ArrayList<Dimension>();
for(String item : dimensionsArr){
Dimension d = new Dimension().setName(item);
dimensions.add(d);
}
// Create the ReportRequest object.
ReportRequest request = new ReportRequest()
.setViewId(this.VIEW_ID)
.setDateRanges(Arrays.asList(dateRange))
.setMetrics(metrics)
.setDimensions(dimensions)
.setFiltersExpression("ga:eventCategory=#NOTICE,ga:eventCategory==Document,ga:eventCategory==Document reader")
.setPageSize(10000);
ArrayList<ReportRequest> requests = new ArrayList<ReportRequest>();
requests.add(request);
// Create the GetReportsRequest object.
GetReportsRequest getReport = new GetReportsRequest().setReportRequests(requests);
// Call the batchGet method.
GetReportsResponse response = service.reports().batchGet(getReport).execute();
// Return the response.
return response;
}
How can I achieve that so I can navigate through all pages and extract all items?
The Reporting API V4 uses page tokens. The reply from the reporting API will return the next page's token, see nextPageToken. Using that you can make the exact same call but updating the pageToken in the request with the nextpagetoken from the previous reply. Note that the first call you make the reporting API will not have a page token attached to the request and the last page will not have the nextpagetoken set.
I hope that helps.
I'm using Katalon Studio and using it to send an API request. The request is basically returning information I want to use in the HTTP Header. I can use Groovy or Java to extract this but not sure how I can do it.
I've tried create_game_response.getHeadewrFields(GameCode) in order to get the GameCode but it won't work.
Here is the code I use
WS.sendRequest(findTestObject('UserRestService/Create Game'))
WS.verifyResponseStatusCode(create_game_response, 201)
def header_text = create_game_response.getHeaderFields()
println(header_text)
def game_code = create_game_response.getHeaderFields();
String game_code_list = game_code.toString()
println(game_code_list)
And this is the response:
{GameCode=[1jwoz2qy0js], Transfer-Encoding=[chunked], null=[HTTP/1.1 201 Created]}
I'm trying to extract "1jwoz2qy0js" from the game code and use it as a string, how can I do this?
getHeaderFields() returns a Map of the headers where each header is a List. Rather than converting that to a String and attempting to parse it, just get the field you want:
Map headers = create_game_response.getHeaderFields()
List gameCodes = headers["GameCode"]
And then select the first one, if that's all there is:
assert gamesCodes[0] == "1jwoz2qy0js"
Groovy code below:
str = '{GameCode=[1jwoz2qy0js], Transfer-Encoding=[chunked], null=[HTTP/1.1 201 Created]}'
left_idx = str.indexOf('[') + 1
right_idx = str.indexOf(']')
print str.substring(left_idx,right_idx)
Output:
1jwoz2qy0js
I'm tring to do a mapping in order to pass some data from the Elastic Search Engine to some Java object, using this SearchHit.getAt(i).getFields(); to get a Map<String,SearchHitField>.
Problem is, I get an empty map, so I have a null value on SearchHitField (with adresseField for example).
This is my code at the moment:
SearchResponse response = searchCriteria(client,"001","Actif");
List<EsClient> esClientList = new ArrayList<EsClient>();
// get all Hits of response
SearchHits searchHits = response.getHits();
for(int i=0;i<response.getHits().getTotalHits()-1;i++) {
// get fields of response(hits) (fieldName/value)
Map<String,SearchHitField> responseFields = searchHits.getAt(i).getFields();
// get required field
SearchHitField adresseField = responseFields.get("Complement_adresse");
SearchHitField nomField = responseFields.get("Nom");
SearchHitField prenomField = responseFields.get("Prenom");
SearchHitField libelleQuartierField = responseFields.get("Libille_quartier");
System.out.println(adresseField.getValue());
}
Anyone could help me ? Thanks in advance.
UPDATE :
response debug value
searchHist debug value
According to Facebook Docs
If your app is making enough calls to be considered for rate limiting by our system, we return an X-App-Usage HTTP header. [...] When any of these metrics exceed 100 the app will be rate limited.
I am using Facebook4J to connect my application to the Facebook API. But I could not find any documentation about how I can get the X-App-Usage HTTP header after a Facebook call, in order to avoid being rate limited. I want to use this header to know dinamically if I need to increase or decrease the time between each API call.
So, my question is: using Facebook4J, is possible to check if Facebook returned the X-App-Usage HTTP header and get it? How?
There is a getResponseHeader method for the response of BatchRequests in facebook4j see Facebook4j code examples
You could try getResponseHeader("X-App-Usage")
// Executing "me" and "me/friends?limit=50" endpoints
BatchRequests<BatchRequest> batch = new BatchRequests<BatchRequest>();
batch.add(new BatchRequest(RequestMethod.GET, "me"));
batch.add(new BatchRequest(RequestMethod.GET, "me/friends?limit=50"));
List<BatchResponse> results = facebook.executeBatch(batch);
BatchResponse result1 = results.get(0);
BatchResponse result2 = results.get(1);
// You can get http status code or headers
int statusCode1 = result1.getStatusCode();
String contentType = result1.getResponseHeader("Content-Type");
// You can get body content via as****() method
String jsonString = result1.asString();
JSONObject jsonObject = result1.asJSONObject();
ResponseList<JSONObject> responseList = result2.asResponseList();
// You can map json to java object using DataObjectFactory#create****()
User user = DataObjectFactory.createUser(jsonString);
Friend friend1 = DataObjectFactory.createFriend(responseList.get(0).toString());
Friend friend2 = DataObjectFactory.createFriend(responseList.get(1).toString());
I have a hosted domain on AWS Route53. Under that domain I have an 'A' record for a subdomain.
I would like to be able to update the IP address of the 'A' record using the Java API. However, when looking at the setAction method of the com.amazonaws.services.route53.model.Change class, it only accepts the CREATE or DELETE values. This seems to match the allowed values in the XML message that the Java API sends behind the scenes.
Is there any way to just update the IP address, or do I have to delete the original record and then create it again?
Thanks
It worked for me using this piece of code:
ResourceRecord record = new ResourceRecord(loadBalancer);
List<ResourceRecord> records = new ArrayList<ResourceRecord>();
records.add(record);
ResourceRecordSet recordsSet = new ResourceRecordSet();
recordsSet.setResourceRecords(records);
recordsSet.setType(RRType.CNAME);
recordsSet.setTTL(900L);
recordsSet.setName(subdomain + ".");
Change change = new Change(ChangeAction.CREATE, recordsSet);
List<Change> changes = new ArrayList<Change>();
changes.add(change);
ChangeBatch batch = new ChangeBatch(changes);
ChangeResourceRecordSetsRequest request = new ChangeResourceRecordSetsRequest();
request.setChangeBatch(batch);
request.setHostedZoneId(hostedZoneId);
ChangeResourceRecordSetsResult result = getRoute53Client().changeResourceRecordSets(request);
System.out.println(result);
Just replace the variables I used with proper data. (subdomain, loadBalancer and hostedZoneId). The method getRoute53Client() returns an instance of the AmazonRoute53Client class from the AWS API.
ResourceRecord rr = new ResourceRecord(IPAdress); // IPAddress will be String variable that has IP value
List<ResourceRecord> rrList = new ArrayList<ResourceRecord>();
rrList.add(rr);
// Create a ResourceRecordSet
ResourceRecordSet resourceRecordSet = new ResourceRecordSet();
resourceRecordSet.setName(domainName); //domainName is String value of your domain
resourceRecordSet.setType(RRType.A); //type of ResourceRecordSet
resourceRecordSet.setTTL(new Long(300));
resourceRecordSet.setWeight(new Long(0));
resourceRecordSet.setResourceRecords(rrList);
// Create a change
Change change = new Change(ChangeAction.CREATE, resourceRecordSet);
List<Change> changesList = new ArrayList<Change>();
changesList.add(change);
// Create a change batch
ChangeBatch changeBatch = new ChangeBatch(changesList);
// Create ChangeResourceRecordSetRequest.
ChangeResourceRecordSetsRequest request = new ChangeResourceRecordSetsRequest(hostedZoneID, changeBatch); //hostedZoneId is variable that is the id of HostedZone
// Send the request and get the response.
ChangeResourceRecordSetsResult result = amazonRoute53Client.changeResourceRecordSets(request);
// Print the result
System.out.println(result.getChangeInfo());
The only way is to use DELETE / CREATE sequence as mentioned here.
Creating a Change Batch Request
To create a change batch request, use the ChangeResourceRecordSets
action ChangeBatch element. You use CREATE and DELETE actions within
the ChangeBatch element for each record that you want to update. If
you are only creating records, then you will only use CREATE actions.
hostedzoneId = "hosted zone id from the route53"
aliasTargetHostedzoneId = "zone id of the connected resource such as loadbalancer, cloudfront etc.."
Route53Client route53Client = Route53Client.builder()
.credentialsProvider(StaticCredentialsProvider.create(awsCreds))
.region(Region.AWS_GLOBAL)
.build();
AliasTarget aliasTarget = AliasTarget.builder()
.dnsName(loadBalancerDomain)
.evaluateTargetHealth(false)
.hostedZoneId(aliasTargetHostedzoneId)
.build();
// Create a ResourceRecordSet
ResourceRecordSet resourceRecordSet = ResourceRecordSet.builder()
.name(fullDomainName+".")
.type(RRType.A)
.aliasTarget(aliasTarget)
.build();
// Create a change
Change change = Change.builder()
.action(ChangeAction.CREATE)
.resourceRecordSet(resourceRecordSet)
.build();
List<Change> changesList = new ArrayList<Change>();
changesList.add(change);
// Create a change batch
ChangeBatch changeBatch = ChangeBatch.builder()
.changes(changesList)
.build();
// Create ChangeResourceRecordSetRequest.
ChangeResourceRecordSetsRequest request = ChangeResourceRecordSetsRequest.builder()
.hostedZoneId(hostedzoneId)
.changeBatch(changeBatch)
.build();
// Send the request and get the response.
ChangeResourceRecordSetsResponse result = route53Client.changeResourceRecordSets(request);