abstractlist protobuf java - java

I have an object containing a list sent from a C# client to a Java server. The serialization with protobuf work perfectly and the object is received perfectly in Java. But the class generated with protoc.exe (can we call it a proto class?) have a list that i can't modify. Basically, I have to add some values in it before returning it to C#, but when I try to add a value, i have an exception :
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
...
Here's how i'm adding values:
MyProtoObject.MyResult result = MyProtoObject.MyResut.NewBuilder()
.setId(1)
.setValue(9.135)
.build();
MyObject.getResultList().add(result);
How can i insert values in it?

Maybe it's somewhat of a workaround, but you could try this:
List<MyResult> l = new ArrayList<MyResult>(MyObject.getResultList());
l.add(result);
MyObject.setResultList(l);

Ok after regenerating the proto class, it appears some methods was missing (I probably made mistakes in first generation). So now i can add values in the list :
MyObjectProto.MyObject o = MyObjectProto.MyObject.newBuilder()
.addAllResults(listOfCalculations)
.build();
listOfCalculation is a List of results objects
or just :
MyObjectProto.MyObject o = MyObjectProto.MyObject.newBuilder()
.addResult(calculationResult)
.build();
CalculationResult is a single result object
Thanks to Flavio

Related

Vert.x - Not able to decode json to list of objects

I'm using the latest version of Vert.x (4.3.2) and I wrote and handler for a route that serves a POST method.
Below my code to convert the JSON body of that method to a List of objects:
Class<List<CartLineItem>> cls = (Class<List<CartLineItem>>)(Object)List.class;
List<CartLineItem> itemsToAdd = rc.body().asPojo(cls);
Unforntunately whenever I try to iterate over itemsToAdd I get the exception: java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class com.acme.CartLineItem.
How can I fix this issue without using any other library except Vert.x (I mean .. using Jackson I would provide a TypeReference<List> object)?
In Vert.x 3 there was method that you could use:
Json.decodeValue(result.bodyAsString(), new TypeReference<List<ConditionDTO>>() {});
Since in Vert.x 4 this was removed you will need to use specific class DatabindCodec:
io.vertx.core.json.jackson.DatabindCodec.fromString(result.bodyAsString(), new TypeReference<List<SimpleDTO>>() {})
If you don't want to use external libraries there is an option to iterate over an jsonArray that you have in body assuming body is something like this:
[{"name":"Lazar", "age":27},{"name":"Nikola", "age":33}]
List<SimpleDTO> list = routingContext.body().asJsonArray()
.stream()
.map(json -> Json.decodeValue(json.toString(), SimpleDTO.class))
.collect(Collectors.toList());

How to validate list body in Javalin

My DELETE request accepts a list of Items that should be deleted.
I want to validate that the request body is a valid list of Item objects.
The example given in the Javalin docs doesn't mention lists.
In order to get the code to compile, I had to do this:
TypedValidator<List> requestValidator = ctx.validatedBodyAsClass(List.class);
List<Item> items = requestValidator.getOrThrow();
logger.info("Received delete request for {}", Arrays.toString(items.toArray()));
logger.info("items is type {}", items.getClass());
for (Item item : items) {
logger.info("Deleting {}", item.name);
}
The validation passes and the ctx body is printed correctly in the following line.
The problem is, there is an unchecked assignment at getOrThrow() and indeed the loop doesn't work:
[qtp1679441380-34] INFO com.myorg.MyClass - Received delete request for [{name=FooName, type=BarType}]
[qtp1679441380-34] INFO com.ericsson.cdzm.ws.controllers.ScheduleController - items is type class java.util.ArrayList
[qtp1679441380-34] WARN io.javalin.core.ExceptionMapper - Uncaught exception
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.myorg.Item
at com.myorg.MyClass.deleteItems(MyClass.java:51)
Edit: The java.util.LinkedHashMap seems to be because actually, items is of type ArrayList<LinkedHashMap<String,String>>. In other words, Javalin didn't parse or validate the body contents at all! It only converted the Json name=value mappings into a Java Map.
What would be a better way to validate the incoming Json and parse it to a list of Items?
I've tested on Javalin 2.6.0 and 2.8.0.
What I had missed, and can't find in the Javalin docs, was that I have to use array types rather than parameterized Collection types. This works:
TypedValidator<Item[]> requestValidator = ctx.bodyValidator(Item[].class);
List<Item> items = Arrays.asList(requestValidator.get());
Still, would love to know why this is - I suspect it is related to Java's type system somehow?
I could also directly access the Jackson ObjectMapper object and use it like you would use Jackson. The drawback is that I don't benefit from Javalin's automatic throwing of BadRequestResponse etc. I think using array types is a small price to pay for this.
try {
List<ScheduleRequest> items = JavalinJackson.getObjectMapper().readValue(ctx.body(), new TypeReference<List<ScheduleRequest>>(){});
} catch (IOException e) {
throw new BadRequestResponse(e.getMessage());
}

Error reading objects from Gemalto smartcard using IAIK pkcs11wrapper

I'm trying to read the public certificate names from a smartcard to display to the user before they sign a file using a gemalto smartcard.
I've followed the getInfo example from iaikPkcs11Wrapper demos as below :
Module pkcs11Module = Module.getInstance(settings.getCryptoDll());
Slot[] slotList;
try{
slotList = pkcs11Module.getSlotList(true);
}catch(TokenException tex){//module is not initialised
tex.printStackTrace();
pkcs11Module.initialize(new DefaultInitializeArgs());
slotList = pkcs11Module.getSlotList(true);
}
for (Slot slot : slotList) {
Token token = slot.getToken();
iaik.pkcs.pkcs11.Session session = token.openSession(true, SessionReadWriteBehavior.RO_SESSION, null, null);
session.findObjectsInit(null);
Object[] objects = new Object[0];
try {
objects = session.findObjects(1);
This fails always at the line objects = findObjects(1); with a CKR_TEMPLATE_INCONSISTENT exception.
As I understand from the documentation session.findObjectsInit(null) should just return all accessible objects on the card and you can then compare them for type.
I have various smartcards and they all fail like this, I've also tried calling session.findObjectsInit(tempObj) with a GenericTemplate object and a X509PublicKeyCertificate which both return the same exception, and with an X509AttributeCertificate which returns no objects but does not throw the exception.
I'd appreciate any pointers anyone can give. Or do I need to create a matching template object using GenericTemplate? I'm unsure why I'm getting the exception as I thought passing the object into the getObjectInit method filtered for thet object so anything returned should match.
EDIT
I've subsequently tried with other templates and ones for objects not on the card just return an empty array- no exception and ones I think are on the cards just throw the ckr_template_inconsistent exception, any help would be gratefully received.
EDIT2
I've now tried with some new 'V3' cards, which do infact work, all my test cards work using another technique (we currently use capicom via com4J for signing), so maybe there is an issue with the iaik wrapper, or gclib.dll (or me).

java web service wsdl: Getting data out of a responce variable

Very new to web services (as you can tell from the Q) so i am pretty sure this is a basic question.
I am sending the request of to the server
ExecuteSQLQueryReq sqlParams = new ExecuteSQLQueryReq();
sqlParams.setSql(sqlState.getNoDevInDP("LIV_Phones_DP"));
and getting the response i expect:
ExecuteSQLQueryRes getSqlResult = axlPort.executeSQLQuery(sqlParams);
i can see all the data is there in the object from the eclipse debugging
but from the object "getSqlResult" i dont know how to pull the data out. The response is in the following format:
Any help would be great
Thanks
Alexis
EDIT:
Screen shot of "ExecuteSQLQueryRes". The only methods i see is to return a list of Objects, which i do and that the screenshot of the variables in eclipse you mention. Its the next step .... how to get from a generic Object the data out..
From the type signatures, I'd say you would invoke the service like so:
List<Object> rows = axlPort.executeSQLQuery(sqlParams)
.getReturn()
.getRow();
for(Object row : rows) {
Element rowElement = (Element) row;
// utilize DOM API
}
As far as I can tell from the information posted you're getting a List of Elements. In XML:
<row>?</row>
<row>?</row>
<row>?</row>
Since row is anyType nothing specific can be inferred about its structure. In the specific case, the first entry looks like this assuming a single child (text) node:
<row>339</row>
You can use the Java DOM APIs to access the data.
From the name onwards, this service looks like it just exposes the underlying database implementation. Consider adhering to stricter SOA principles if you have any influence over the service design.

how to read a list of objects from the configuration file in play framework

How can i read a list of users from the configuration file in play framework?
i have tried doing something like this:
users=[{uid:123,pwd:xyz},{uid:321,pwd:abc}]
from the play application
List<Object> uids = Play.application().configuration().getList("users");
will give me this a list of objects, if I iterate through the list i get each object as
{uid=123,pwd=xyz} and {uid=321,pwd=abc}
at this point i don't know how i can elegantly get the value of the uid, i can do some hacky job as omit the first and last bracket and parse for the before after equal sign, but it would be too ugly! any idea? (the application is written in java)
thanks
A Scala implementation that avoids the deprecated getConfigList method would rely on retrieving a Seq[Configuration] as follows:
case class UserConfig(uid: Int, pwd: String)
val userConfigs: Seq[UserConfig] = configuration.get[Seq[Configuration]]("users").map { userConfig =>
UserConfig(userConfig.get[Int]("uid"), userConfig.get[String]("pwd"))
}
Since I had recently the same problem and this is still unanswered,
here is my suggestion:
List<User> users = getConfig().getConfigList("users").stream().map(
config -> new User(config.getString("uid"), config.getBoolean("pwd"))
).collect(Collectors.toList());
As far as I know there are no tuples or anything in Java, you need to use either an object or a list with two elements. I decided to go for an object here, you can also return a list.
A list of uid's sounds to me like:
# List of UID's
users=[123,456,789] // every number represents a UID
Then you can get this list as:
List<Object> uids = Play.application().configuration().getList("users");
And then do what you want with this:
for (Iterator<Object> iterator = uids.iterator(); iterator.hasNext();) {
Object object = (Object) iterator.next();
System.out.println(object);
}
Is this what you are looking for?
BTW, you can read more about Play Framework configuration options: http://www.playframework.com/documentation/2.1.0/Configuration

Categories