RangeError deploying bna file to composer-rest-server - hyperledger-composer

So I'm trying to deploy a new bna file to test with.
It's more so I can test the rest interface to create participants with some calling code I wrote than anything else - the javascript transaction processing file is pretty much empty at this juncture.
The .cto file has a couple of different participant types and a bunch of asset types which form a tree structure to represent the data.
Trying to start up a local rest server gives me the following error.
Discovering types from business network definition ... Discovered
types from business network definition Generating schemas for all
types in business network definition ... Exception: RangeError:
Maximum call stack size exceeded RangeError: Maximum call stack size
exceeded
at LoopbackVisitor.visitClassDeclarationCommon (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/codegen/fromcto/loopback/loopbackvisitor.js:352:23)
at LoopbackVisitor.visitAssetDeclaration (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/codegen/fromcto/loopback/loopbackvisitor.js:187:21)
at LoopbackVisitor.visit (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/codegen/fromcto/loopback/loopbackvisitor.js:74:25)
at AssetDeclaration.accept (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/introspect/classdeclaration.js:64:24)
at LoopbackVisitor.visitField (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/codegen/fromcto/loopback/loopbackvisitor.js:494:18)
at LoopbackVisitor.visit (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/codegen/fromcto/loopback/loopbackvisitor.js:86:25)
at Field.accept (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/introspect/property.js:48:24)
at classDeclaration.getProperties.forEach (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/codegen/fromcto/loopback/loopbackvisitor.js:373:66)
at Array.forEach (native)
at LoopbackVisitor.visitClassDeclarationCommon (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/codegen/fromcto/loopback/loopbackvisitor.js:370:42)
at LoopbackVisitor.visitAssetDeclaration (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/codegen/fromcto/loopback/loopbackvisitor.js:187:21)
at LoopbackVisitor.visit (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/codegen/fromcto/loopback/loopbackvisitor.js:74:25)
at AssetDeclaration.accept (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/introspect/classdeclaration.js:64:24)
at LoopbackVisitor.visitField (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/codegen/fromcto/loopback/loopbackvisitor.js:494:18)
at LoopbackVisitor.visit (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/codegen/fromcto/loopback/loopbackvisitor.js:86:25)
at Field.accept (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/introspect/property.js:48:24)
at classDeclaration.getProperties.forEach (/usr/local/lib/node_modules/composer-rest-server/node_modules/composer-common/lib/codegen/fromcto/loopback/loopbackvisitor.js:373:66)
A little quality time with google gave me the fact that it's an out of memory error and probably caused by over recursion but after that I'm stuck.
The same network works just fine in the playground fwiw.
EDIT:
There's no .qry file. This is as basic as it gets.
I was trying to see if I could add Par1 and Par2 samples from a REST call I'd knocked up.
The ACL file is the standard allow-all-to-do-all from the basic-network sample.
I've scrubbed the .cto file to partly obscure the source, but it appears to still recur with the following:
/**
* Sample business network definition.
*/
namespace xx.yy.zz
asset SomeTransmission identified by orderNumber {
o String orderNumber //Some order number
--> Par2 aa
--> Par1 bb
o SomeTransmission[] messages
}
participant Par1 identified by code {
o String mmm
o String name
o String prefix
o String code
o Boolean bool1
o Boolean bool2
o Boolean bool3
}
participant SomeSss identified by sss {
o String sss
o String mmm
--> Par1 bb
--> Par1 rep2
}
participant Par2 identified by id {
o String id
o String name
o String address
}
transaction UpdateOrderTransaction {
o String orderId
--> Par2 aa
--> Par1 bb
o SomeTransmission transmission
}
event UpdateOrderEvent {
--> SomeTransmission transmission
}
asset Some identified by uuid {
o String uuid //Unique identifier
}
asset AgencyOrder extends Some {
o AXZHDR agyhdr
o AXZDS1 agyds1
o AXZDS2 agyds2
o AXZDS3 agyds3
o AXZDS4 agyds4
o AXZSTD[] agystds
o AXZCOM[] agycoms
o AXZHIA[] agyhias
o BxblineTransmission[] bxblines
o AXZTLR agytlr
}
asset SomeRecord identified by uuid {
o String uuid
o String id
o Long orderNumber //Some order number
}
asset SomeModifier extends SomeRecord {
o Par2 tpar2
o Par1 tpar1
o String dt
o String sss
o String cn
o String rts
}
asset SomePreviousSssModifier extends SomeModifier {
o String previousSssCallLetters
}
asset SomeMultiple extends SomeRecord {
o String continuation
}
asset SomeComment extends SomeMultiple {
o String comment
}
asset AXZHDR extends SomePreviousSssModifier {
o String version //Some version number
o String routingCode
o String mdaCode
o String clientCode
o String prxOneCode
o String prxTwoCode
o String estimateNumber
o String startDate
o String endDate
o String cashOrTrade
o String scheduleType
o String scheduleStartDate
o Long billWeekStartDay
o String originalOrderNumber
o Long revisionNumber
}
asset AXZDS1 extends SomeRecord {
o String axyName
o String axyAddress
}
asset AXZDS2 extends SomeRecord {
o String clientName
o String estimateDescription
o String targetDmxx
o String[] extraDmxxs
}
asset AXZDS3 extends SomeRecord {
o String prxOneName
o String prxTwoName
}
asset AXZDS4 extends SomeRecord {
o String bxberCode
o String bxberName
o Long bxberTelephone
o String bxberExtension
}
asset AXZSTD extends SomeComment {
}
asset AXZCOM extends SomeComment {
}
asset AXZHIA extends SomeMultiple {
o String[] dates
}
asset AXZTLR extends SomeRecord {
o Long numberOfRecords
o Long totalOrderedSpx
o Long totalOrderedDollars
}
//Bxb record details
asset BxblineTransmission identified by uuid{
o String uuid
o BXBHDR bxbhdr
o BXBDEM bxbdem
o BXBORB[] bxborbs
o BXBCOM[] bxbcoms
o BXBDTL[] bxbdtls
}
asset SomeBxbRecord extends SomeRecord {
o Long sequenceNumber
o String sbx
o Long sbxStartDay
o Long startTime
o Long endTime
o Long totalspxyLength
o String lengthInUnits
o Long cost
o String costQualifier
o Long prxOneTimeShare
o String pppName
o String scheduleType
}
asset BXBHDR extends SomeBxbRecord {
o Long makegoodForBxbline
}
asset BXBDEM extends SomeRecord {
o Long[] demos
}
asset BXBORB extends SomeMultiple {
o String sbx
o Long sbxStartDay
o Long startTime
o Long endTime
o String pppName
}
asset BXBCOM extends SomeComment {
}
asset BXBDTL extends SomeMultiple {
o Long cost
o String startDate
o Long numberOfWeeks
o Long spxPerWeek
}

The issue is:
asset SomeTransmission identified by orderNumber {
o String orderNumber //Some order number
--> Par2 aa
--> Par1 bb
o SomeTransmission[] messages
}
The SomeTransmission[] messages causes the code to recurse, attempting to introspect the SomeTransmission class when it is already in the process of introspecting it.
It seems unusual to want to have an asset that contains an array of its own asset type. What are you trying to achieve, perhaps there's another way of modelling this?
I have created the issue https://github.com/hyperledger/composer/issues/2193 to fix this.

Related

Parse log entries with least possible overhead

I have some log format with entries like this:
log_entry_no1 := "2021-11-03 7:7:51 hal9000 evil_app heartbeat C99 I am sorry Dave"
Those "fields" are separated by space except the last one called message which is just log data and can contain spaces.
My question is. Is there better way to process those entries without first splitting whole sentence and then join'ing that last part (message) with less overhead using go?
type LogData struct {
d Date // yyyy-mm-dd Mandatory
t Time // hh:mm:ss Mandatory
hostname string // Mandatory
app_id string // Mandatory
etype string // enum based string Mandatory
level string // Optional base on etype
message string // Mandatory
}
log_fields := strings.Split(log_entry_no1, " ")
var log_data = LogData{}
log_data.d = parseTime(log_entry_no1[0])
log_data.t = parseTime(log_entry_no1[1])
//...
if log_fields[4] == "heartbeat" {
log_data.level = log_fields[5]
log_data.message = strings.Join(log_fields[6:], " ")
} else {
log_data.message = strings.Join(log_fields[5:], " ")
}
Use strings.SplitN.
func SplitN(s, sep string, n int) []string
The docs say if n is greater than zero: it returns at most n substrings; the last substring will be the unsplit remainder.

Sonar issue Assignments should not be redundant (squid:S4165)

private void updateEmployee(String employeeCode, UpdateUserDto updateUserDto){
Employee emp = getEmpDetails(employeeCode);
emp = updateMobile&Email(emp, updateUserDto.getMobile(), updateUserDto.getMail());
// Remove this useless assignment; "emp" already holds the assigned value along all execution paths.
...
...
emp.setisActive(updateUserDto.getIsActive());
empRepo.save(emp);
}
private Employee updateMobile&Email(Employee emp, String mobile, String mail){
if(emp.getMobile() == null && (mobile != null || mobile.isBlank())){
emp.setMobile(mobile);
}
if(emp.getMail() == null && (getMail != null || getMail.isBlank())){
emp.setMail(mail);
}
return emp;
}
Due to connectivity complexity I made some functions. Above one is just for example, the code is bigger
Remove this useless assignment; "emp" already holds the assigned value along all execution paths.
At line 2 of updateEmployee()
Sonar issue details
Assignments should not be redundant (squid:S4165)
Noncompliant
a = b;
c = a;
b = c; // Noncompliant: c and b are already the same
Compilant
a = b;
c = a;
The emp parameter will be passed by reference into the updateMobile&Email method, meaning the line 2 assignment is unnecessary.
I suggest updating updateMobile&Email to have a void return type.

Is this a bug in lua, or a feature unknown to me?

I'm trying to teach a friend of mine how to lua, basically, and he comes to me with this code, and it stumps my head:
a = {name = "aaa"}
function a:new()
self.x = "sss"
o = {}
setmetatable(o, self)
self.__index = self
return o
end
function a:some()
return "[ " .. self.name .. " ]"
end
b = a:new()
print(b:some())
print(b.x)
which prints
[ aaa ]
sss
both shouldnt be possible, since they were never set to o inside a:new
after some debugging, i look into it, and here some interesting things happen:
a = {name = "aaa", x = "sss"}
function a:new()
o = {}
print(o.x, self.x)
-- nil sss
setmetatable(o, self)
print(o.x, self.x, o, self, self.__index, o.__index)
-- nil sss table: 0x1001280 table: 0x1001320 table: 0x1001320 nil
self.__index = self
print(o.x, self.x, o, self, self.__index, o.__index)
-- sss sss table: 0x1001280 table: 0x1001320 table: 0x1001320 table: 0x1001320
return o
end
Note how on the third print, it returns the .x value of self, but it was called from o, which has no "relationship" with self, how is this possible?
You've set table a as __index field in metatable for all tables that will be created with a:new(). When some non-existent field will be checked in the b table, value will be searched in a too. That's why you can find fields x or name in a table b, even if you didn't assign it explicitly.

In pig, how do I count the number of lines that contained a specific string?

Suppose I have a group of target words:
a b c d
and an input file:
a d f s g e
12399
c a d i f
a 2
then I should return:
a 3
b 0
c 1
d 2
How can I do that in pig? Thank you!
First remove the duplicate words from each line then run word count.
Pig steps:
REGISTER 'udf-1.0-SNAPSHOT.jar'
define tuple_set com.ts.pig.UniqueRecords();
data = load '<file>' using PigStorage();
remove duplicate words from each line
unique= foreach data generate tuple_set($0) as line;
words= foreach unique generate flatten(TOKENIZE(line,' ')) as word;
grouped = group words BY word;
count= foreach grouped GENERATE group, COUNT(words);
dump count;
Pig UDF sample code:
/**
* This udf removes duplicate words from line
*/
public class UniqueRecords extends EvalFunc<String> {
#Override
public String exec(Tuple tuple) throws IOException {
if (tuple == null || tuple.size() == 0)
return null;
String[] splits=tuple.get(0).toString().split(" ");
Set<String> elements = new HashSet<String>(Arrays.asList(splits));
StringBuilder sb = new StringBuilder();
for(String element:elements ){
sb.append(element+" ");
}
return sb.toString();
}
}

Why Kotlin doesn't implement Int.plus(value: String)?

It causes discomfort when you can do that:
val string = " abc "
val integer = 8
val result = string + integer
and can't do:
val result = integer + string
It has hidden meaning or it's an omission?
Kotlin is static typed language and in basicly you can't add String to Integer. But there are possible to overload operators, so we can now.
In case when we want add any object to string, it's clear: every object can be implicitly converted to String (Any#toString())
But in case of Int + smthg it's not so clear, so only Int + kotlin.Number is defined in standard library.
I suggest to use string interpolation:
val result = "${integer}${string}"
Or define own overloaded plus operator:
operator fun Int.plus(string: String): String = string + this

Resources