How catch exception using Iteratee.foreach in Future - future

I'm using Play Framework 2.2 and ReactiveMongo. I'm iterating trough all received entries from ReactiveMongo, and getting some property from single entry. Sometimes it throws Exception of inexistent property, how should I catch it, for now using simple "recover" doesn't work.
val cursor:Cursor[JsObject] = // QUERY FOR DATA
val processingData = cursor.enumerate().apply(Iteratee.foreach { doc =>
(doc \ "property")
}
processingData.map { data =>
Logger.info(s"$data")
None
}.recover {
case e =>
Logger.error(s"Error during parsing $e")
None
}

Iteratee.foreach always return Unit type, so value processingData will not contain data and enumerator apply some Iteratee only attach iteratee to emumerator, but don't run it. I think, this must solve your problem:
val cursor:Cursor[JsObject] = // QUERY FOR DATA
val getData = Enumeratee.mapM[JsObject]{doc =>
Future(doc \ "property") //use future to catch exception here
}
val processingData: Future[scala.List[JsObject]] = cursor.enumerate() &> getData .run Iteratee.getChunks

Related

How to Jenkins Groovy scripting for live fetching of Docker image + authentication

I have a script groovy, this script for live fetching of docker image,
I want to add the authentication function with the private repository, but I am not familiar with groovy, who can help me, thanks
import groovy.json.JsonSlurper
// Set the URL we want to read from, it is MySQL from official Library for this example, limited to 20 results only.
docker_image_tags_url = "https://registry.adx.abc/v2/mysql/tags/list"
try {
// Set requirements for the HTTP GET request, you can add Content-Type headers and so on...
def http_client = new URL(docker_image_tags_url).openConnection() as HttpURLConnection
http_client.setRequestMethod('GET')
// Run the HTTP request
http_client.connect()
// Prepare a variable where we save parsed JSON as a HashMap, it's good for our use case, as we just need the 'name' of each tag.
def dockerhub_response = [:]
// Check if we got HTTP 200, otherwise exit
if (http_client.responseCode == 200) {
dockerhub_response = new JsonSlurper().parseText(http_client.inputStream.getText('UTF-8'))
} else {
println("HTTP response error")
System.exit(0)
}
// Prepare a List to collect the tag names into
def image_tag_list = []
// Iterate the HashMap of all Tags and grab only their "names" into our List
dockerhub_response.results.each { tag_metadata ->
image_tag_list.add(tag_metadata.name)
}
// The returned value MUST be a Groovy type of List or a related type (inherited from List)
// It is necessary for the Active Choice plugin to display results in a combo-box
return image_tag_list.sort()
} catch (Exception e) {
// handle exceptions like timeout, connection errors, etc.
println(e)
}
The problem has been resolved, thank you everyone for your help
// Import the JsonSlurper class to parse Dockerhub API response
import groovy.json.JsonSlurper
// Set the URL we want to read from, it is MySQL from official Library for this example, limited to 20 results only.
docker_image_tags_url = "https://registry.adx.vn/v2/form-be/tags/list"
try {
// Set requirements for the HTTP GET request, you can add Content-Type headers and so on...
def http_client = new URL(docker_image_tags_url).openConnection() as HttpURLConnection
http_client.setRequestMethod('GET')
String userCredentials = "your_user:your_passwd";
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userCredentials.getBytes()));
http_client.setRequestProperty ("Authorization", basicAuth);
// Run the HTTP request
http_client.connect()
// Prepare a variable where we save parsed JSON as a HashMap, it's good for our use case, as we just need the 'name' of each tag.
def dockerhub_response = [:]
// Check if we got HTTP 200, otherwise exit
if (http_client.responseCode == 200) {
dockerhub_response = new JsonSlurper().parseText(http_client.inputStream.getText('UTF-8'))
} else {
println("HTTP response error")
System.exit(0)
}
// Prepare a List to collect the tag names into
def image_tag_list = []
// Iterate the HashMap of all Tags and grab only their "names" into our List
dockerhub_response.tags.each { tag_metadata ->
image_tag_list.add(tag_metadata)
}
// The returned value MUST be a Groovy type of List or a related type (inherited from List)
// It is necessary for the Active Choice plugin to display results in a combo-box
return image_tag_list.sort()
} catch (Exception e) {
// handle exceptions like timeout, connection errors, etc.
println(e)
}
here is the result

unable to understand why validateOpt will return `None` instead of `JsError`

In the following code, I am unable to understand why validateOpt might return value JsSuccess(None) instead of JsError
def getQuestion = silhouette.UserAwareAction.async{
implicit request => {
val body: AnyContent = request.body
val jsonBodyOption: Option[JsValue] = body.asJson
jsonBodyOption.map((jsonBody:JsValue) => { //body is json
val personJsonJsResultOption = jsonBody.validateOpt[Person]//check that json structure is correct
personJsonJsResultOption match {
case personSuccessOption: JsSuccess[Option[Person]] => { //json is correct
val personOption = personSuccessOption.getOrElse(None) //why would getOrElse return None??
personOption match {
case Some(person) => {
... }
case None =>{ //I am not sure when this will be triggered.
...
}
}
}
}
case e: JsError => {
...
}
}
}
})
.getOrElse(//body is not json
...)
}
}
validateOpt by design considers success to be not only when body provides actual Person but also when Person is null or not provided. Note how documentation explains why JsSuccess(None) is returned:
/**
* If this result contains `JsNull` or is undefined, returns `JsSuccess(None)`.
* Otherwise returns the result of validating as an `A` and wrapping the result in a `Some`.
*/
def validateOpt[A](implicit rds: Reads[A]): JsResult[Option[A]]
Seems like your requirement is that Person must always be provided to be considered successful, so in this case validate should be used instead of validateOpt.

How to get all transaction history against a chaincode in Hyperledger fabric

I am able to do transactions in Hyperledger (fabric implementation). I want to see all the transactions and its payload details initiated by a user by passing the user's key.
for example:
A transfers 10 units to B
A transfers 5 units to C
D transfers 8 units to A
When I pass A's key then fabric must provide me all the transactions of A.
Is there any way? Or which fabric API function call should I use?
/chain/blocks/{Block} endpoint carries ordered list of transactions in a specified block.
Use /chain endpoint to get the height (number of blocks) of your chain, and then retrieve transactions from each block using /chain/blocks/{Block} REST endpoint.
You can develop the proper indexing and query function in your chaincode.
Meaning for each transaction you store its details in the internal key/value store (stub.PutState) with the user as key and return all the transactions associated to a user in your query (stub.GetState).
The best and simplest way is to use the shim package function
GetHistoryForKey(key string)
As the documentation says:
GetHistoryForKey function can be invoked by a chaincode to return a history of key values across time.
GetHistoryForKey is intended to be used for read-only queries.
IF anyone need Java SDk and go chaincode combination. There you go
answered here similar question
Java code
public List<HistoryDao> getUFOHistory(String key) throws Exception {
String[] args = { key };
Logger.getLogger(QueryChaincode.class.getName()).log(Level.INFO, "UFO communication history - " + args[0]);
Collection<ProposalResponse> responses1Query = ucc.getChannelClient().queryByChainCode("skynetchaincode", "getHistoryForUFO", args);
String stringResponse = null;
ArrayList<HistoryDao> newArrayList = new ArrayList<>();
for (ProposalResponse pres : responses1Query) {
stringResponse = new String(pres.getChaincodeActionResponsePayload());
Logger.getLogger(QueryChaincode.class.getName()).log(Level.INFO, stringResponse);
newArrayList = gson.fromJson(stringResponse, new TypeToken<ArrayList<HistoryDao>>() {
}.getType());
}
if (null == stringResponse)
stringResponse = "Not able to find any ufo communication history";
return newArrayList;
}
and you go chancode implemetation is as follows
Go code
func (t *SmartContract) getHistoryForUFO(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
if len(args) < 1 {
return shim.Error("Incorrect number of arguments. Expecting 1")
}
ufoId := args[0]
resultsIterator, err := APIstub.GetHistoryForKey(ufoId)
if err != nil {
return shim.Error(err.Error())
}
defer resultsIterator.Close()
var buffer bytes.Buffer
buffer.WriteString("[")
bArrayMemberAlreadyWritten := false
for resultsIterator.HasNext() {
response, err := resultsIterator.Next()
if err != nil {
return shim.Error(err.Error())
}
// Add a comma before array members, suppress it for the first array member
if bArrayMemberAlreadyWritten == true {
buffer.WriteString(",")
}
buffer.WriteString("{\"TxId\":")
buffer.WriteString("\"")
buffer.WriteString(response.TxId)
buffer.WriteString("\"")
buffer.WriteString(", \"Value\":")
// if it was a delete operation on given key, then we need to set the
//corresponding value null. Else, we will write the response.Value
//as-is (as the Value itself a JSON)
if response.IsDelete {
buffer.WriteString("null")
} else {
buffer.WriteString(string(response.Value))
}
buffer.WriteString(", \"Timestamp\":")
buffer.WriteString("\"")
buffer.WriteString(time.Unix(response.Timestamp.Seconds, int64(response.Timestamp.Nanos)).String())
buffer.WriteString("\"")
buffer.WriteString(", \"IsDelete\":")
buffer.WriteString("\"")
buffer.WriteString(strconv.FormatBool(response.IsDelete))
buffer.WriteString("\"")
buffer.WriteString("}")
bArrayMemberAlreadyWritten = true
}
buffer.WriteString("]")
fmt.Printf("- History returning:\n%s\n", buffer.String())
return shim.Success(buffer.Bytes())
}
Let me know if you question.
If you are using composer-client, you can simply use the Historian command.
var historian = await businessNetworkConnection.getHistorian();
historian.getAll().then(historianRecords => console.log(historianRecords));

Breeze named saves do not work as expected

I tried to use the named saves as below and as explained in the release notes here, but it dosen't work and returns:
Uncaught Error: The 'entities' parameter is optional or it must be an array where each element must be an entity => breeze.debug.js:724
proto.check => breeze.debug.js:724
proto.saveChanges => breeze.debug.js:11150
sendEmail
The function is:
var sendEmail = function () {
var option = new breeze.SaveOptions({ resourceName: 'sendMail'})
return manager.saveChanges({ saveOptions: option })
.then(saveSucceeded)
.fail(saveFailed);
function saveSucceeded(saveResult) {
log('La email è stata invata.', saveResult, true);
}
function saveFailed(error) {
var msg = 'Invio della email è fallito: ' + getErrorMessages(error);
logError(msg, error);
error.message = msg;
throw error;
}
};
Any help appretiated!
The writeup in the release notes has the wrong syntax. I will have it fixed.
The first arg to EntityManager.saveChanges is always a list of entities, or it can be null to indicate all entities. The 2nd arg is an optional SaveOptions instance. See here. So your expression should be
var option = new breeze.SaveOptions({ resourceName: 'sendMail'})
return manager.saveChanges(null, option)

The youtube API sometimes throws error: Call to a member function children() on a non-object

When i launch the php script, sometime works fine, but many other times it retrieve me this errror
Fatal error: Call to a member function children() on a non-object in
/membri/americanhorizon/ytvideo/rilevametadatadaurlyoutube.php on line
21
This is the first part of the code
// set feed URL
$feedURL = 'http://gdata.youtube.com/feeds/api/videos/dZec2Lbr_r8';
// read feed into SimpleXML object
$entry = simplexml_load_file($feedURL);
$video = parseVideoEntry($entry);
function parseVideoEntry($entry) {
$obj= new stdClass;
// get nodes in media: namespace for media information
$media = $entry->children('http://search.yahoo.com/mrss/'); //<----this is the doomed line 21
UPDATE: solution adopted
for ($i=0 ; $i< count($fileArray); $i++)
{
// set feed URL
$feedURL = 'http://gdata.youtube.com/feeds/api/videos/'.$fileArray[$i];
// read feed into SimpleXML object
$entry = simplexml_load_file($feedURL);
if (is_object($entry))
{
$video = parseVideoEntry($entry);
echo ($video->description."|".$video->length);
echo "<br>";
}
else
{
$i--;
}
}
In this mode i force the script to re-check the file that caused the error
You are first of all calling a function:
$entry = simplexml_load_file($feedURL);
That function has a return value. You find it documented on the manual page of that function:
http://php.net/simplexml_load_file
Then you use that return value in form of a variable $entry without verifying that the function call was successful.
Because of that, you run into an error next. However your error/mistake is how you treat the return value of the function.
Not dealing with return values properly is like calling for trouble. Read about the function you use, check the return value(s) and proceed according to success or error conditions.
$entry = simplexml_load_file($feedURL);
if (FALSE === $entry)
{
// youtube not available.
}
else
{
// that's what I love!
}
Sometimes? Really?
Take a look at this:
<?php
$dummy; //IN FACT, this var is NULL now
// Will throw exactly the same error you get
$dummy->children();
Why? Because, we can call method from an object type.
So, if you wanna avoid errors like this one, next time you would call the method ensure that it's "possible".
<?php
if ( is_object($dummy) && method_exists($dummy, 'children') ){
//sure it works
$dummy->children();
}

Resources