how to use path variable in californium CoAP server? - java

Similar with Restful syntax in Jersey or other framework, I could fetch the variable in the Restful uri path like that:
#Path("/users/{username}")
public class UserResource {
#GET
#Produces("text/xml")
public String getUser(#PathParam("username") String userName) {
...
}
}
but in californium, the syntax is different, I try these codes but it is not correct:
class usersextends CoapResource {
public users() {
super("users/{username}");
}
#Override
public void handleGET(CoapExchange exchange) {
exchange.respond("The username is "+ ???????);
}
}
How could I use the same function as first piece of code did? Another thing is where I can find official document introduce the API? I just saw the source code and try to find the solution now.

Create your own MessageDeliverer and change findResource method:
public class MyMessageDeliverer implements MessageDeliverer {
private final Resource root;
public MyMessageDeliverer(Resource root) {
this.root = root;
}
/* You can use implementation of methods from ServerMessageDeliverer */
#Override
public void deliverRequest(Exchange exchange) {
}
#Override
public void deliverResponse(Exchange exchange, Response response) {
}
/* method returns last known Resource instead of null*/
private Resource findResource(List<String> list) {
LinkedList<String> path = new LinkedList<String>(list);
Resource current = root;
Resource last = null;
while (!path.isEmpty() && current != null) {
last = current;
String name = path.removeFirst();
current = current.getChild(name);
}
if (current == null) {
return last;
}
return current;
}
}
Use your MessageDeliverer:
server = new CoapServer();
server.setMessageDeliverer(new MyMessageDeliverer(server.getRoot()));
Add your Resource to server:
server.add(new Users());
Request /users/{username} will be delivered to your Users resource. Fetch the variable from request URI:
public class Users extends CoapResource {
public Users() {
super("users");
}
public void handleGet(CoapExchange exchange) {
List<String> uri = exchange.getRequestOptions().getUriPath();
uri.remove("users");
String username = uri.remove(0);
//for query params:
Map<String, String> params = new HashMap<String, String>();
for (String p : exchange.getRequestOptions().getUriQuery()) {
String[] parts = p.split("=");
params.put(parts[0], parts[1]);
}
String param = params.get("param");
}
}

Related

How to override a gRPC list method for implementation in a Java service

I have the following schema in my messages.proto file:
message Person {
string id = 1;
string first_name = 2;
string last_name = 3;
string email = 4;
string alias = 5;
}
//CREATE, DELETE, UPDATE RESPONSES AND REQUESTS Messages
message ListPersonsRequest {
ListOptions options = 1;
}
message ListPersonsResponse {
repeated Person person = 1;
string total_count = 2;
string total_pages = 3;
string next_page_token = 4;
}
I have the following schema in my services.proto file:
service PersonService {
//rpc methods to create, update, delete...
rpc ListPersons (ListPersonsRequest) returns (ListPersonsResponse) {
option (google.api.http) = {
get: "/person"
};
}
}
In my class 'ServiceImp':
#GrpcService
#AllArgsConstructor(onConstructor = #__(#Autowired))
public class PersonServiceImpl extends PersonServiceImplBase
{
private PersonRepository personRepository;
#Override
public void getPerson(GetPersonRequest request, StreamObserver<GetPersonResponse> responseObserver)
{
try
{
Person person = personRepository.findById(UUID.fromString(request.getId())).orElseThrow(() -> new EntityNotFoundException());
Person personProto = Person
.newBuilder()
.setId(person.getId().toString())
.setFirstName(person.getFirstName())
.setLastName(person.getLastName())
.setEmail(person.getEmail())
.setAlias(person.getAlias()).build();
GetPersonResponse response = GetPersonResponse.newBuilder().setPerson(personProto).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
catch (EntityNotFoundException e)
{
responseObserver.onError(Status.NOT_FOUND.withCause(e).asException());
}
}
#Override
public void createPerson(CreatePersonRequest request, StreamObserver<CreatePersonResponse> responseObserver)
{
Person person = Person.builder().firstName(request.getPerson().getFirstName()).lastName(request.getPerson().getLastName()).email(request.getPerson().getEmail()).alias(request.getPerson().getAlias())
.build();
person = personRepository.save(person); // probably should handle errors
Person personProto = Person.newBuilder().setId(person.getId().toString()).setFirstName(person.getFirstName())
.setLastName(person.getLastName()).setEmail(person.getEmail()).setAlias(person.getAlias()).build();
CreatePersonResponse response = CreatePersonResponse.newBuilder().setPerson(personProto).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
#Override
public void listPersons(ListPersonsRequest request, StreamObserver<ListPersonsResponse> responseObserver){
}
}
I'm trying to response a object which contains a list of all the created items, but I'm confused with how to implement it in my listPerson method, that I'm overriding from the created serviceGRPC
private static volatile io.grpc.MethodDescriptor<grpc.generated.ListPersonsRequest,
grpc.generated.ListPersonsResponse> getListPersonsMethod;
#io.grpc.stub.annotations.RpcMethod(
fullMethodName = SERVICE_NAME + '/' + "ListPersons",
requestType = grpc.generated.ListPersonsRequest.class,
responseType = grpc.generated.ListPersonsResponse.class,
methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
public static io.grpc.MethodDescriptor<grpc.generated.ListPersonsRequest,
grpc.generated.ListPersonsResponse> getListPersonsMethod() {
io.grpc.MethodDescriptor<grpc.generated.ListPersonsRequest, grpc.generated.ListPersonsResponse> getListPersonsMethod;
if ((getListPersonsMethod = PersonServiceGrpc.getListPersonsMethod) == null) {
synchronized (PersonServiceGrpc.class) {
if ((getListPersonsMethod = PersonServiceGrpc.getListPersonsMethod) == null) {
PersonServiceGrpc.getListPersonsMethod = getListPersonsMethod =
io.grpc.MethodDescriptor.<grpc.generated.ListPersonsRequest, grpc.generated.ListPersonsResponse>newBuilder()
.setType(io.grpc.MethodDescriptor.MethodType.UNARY)
.setFullMethodName(generateFullMethodName(SERVICE_NAME, "ListPersons"))
.setSampledToLocalTracing(true)
.setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
grpc.generated.ListPersonsRequest.getDefaultInstance()))
.setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
grpc.generated.ListPersonsResponse.getDefaultInstance()))
.setSchemaDescriptor(new PersonServiceMethodDescriptorSupplier("ListPersons"))
.build();
}
}
}
return getListPersonsMethod;
}
#Override
public void listPersons(ListPersonsRequest request, StreamObserver<ListPersonsResponse> responseObserver){
//Heres were implement is cofused
}
I know that using a stream you are returning an iterator and that means you can start processing the Items on client even before the server has finished the gRPC response, but I'm using the entire object. Is there a way to return it with the stored values? How?
You don't need to do any streaming here. All you need to do is return your result by calling responseObserver.onNext(myListPersonsResponse) after constructing the response object.

How to create a domain object from a Json element?

the external web service returns me a Json file of the form
{"forecasts":[{"period_end":"2021-01-15T01:00:00.0000000Z","period":"PT30M","ghi90":0,"ghi":0,"ghi10":0},{"period_end":"2021-01-15T01:30:00.0000000Z","period":"PT30M","ghi90":0,"ghi":0,"ghi10":0},{"period_end":"2021-01-15T02:00:00.0000000Z","period":"PT30M","ghi90":0,"ghi":0,"ghi10":0}]}
Using RestRespone a transform an json element
RestResponse resp = rest.get(url)
resp.json instanceof JsonElement
How can I create a domain object from the Json element variable, knowing that my wrapper class is
class ForecastGhi {
static constraints = {
}
private ArrayList<IrradianciaGlobalHorizontal> forecast
ArrayList<IrradianciaGlobalHorizontal> getForecast() {
return forecast
}
void setForecast(ArrayList<IrradianciaGlobalHorizontal> forecast) {
this.forecast = forecast
}
}
and de persist domain class is
class IrradianciaGlobalHorizontal {
static constraints = {
}
#JsonProperty("all")
private def period_end
private def period
private def ghi90
private def ghi
private def ghi10
def getGhi() {
this.ghi
}
void setGhi(int ghi) {
this.ghi = ghi
}
def getGhi90() {
this.ghi90
}
void setGhi90(int ghi90) {
this.ghi90 = ghi90
}
def getGhi10() {
this.ghi10
}
void setGhi10(int ghi10) {
this.ghi10 = ghi10
}
def getPeriod_end() {
this.period_end
}
void setPeriod_end(Date period_end) {
this.period_end = period_end
}
def getPeriod() {
this.period
}
void setPeriod(String period) {
this.period = period
}
}
Help please; thanks a lot
This is an issue with your API implementation; The endpoint changed the domain field names &/or domain name. This will cause issues with bringing said data back in.
Either that or front-end is not matching the API docs for the endpoint.
Field names/domain names should match the domain/resource unless you are going for a level of obfuscation and then accept that you are going to need a middle layer to act as a translater (ie EDI).
You want output to be able to be read as input by the same endpoint by merely changing the request method.
My suggestion (easiest solution): change original endpoint to match domain/resource field names
If you have the opportunity to use Jackson library, you can do this:
ForecastGhi request = objectMapper.readValue(jsonAsText, ForecastGhi.class);
Create an objectMapper and configure to fail in case of unknown properties (just in case)
private String getJsonAsTextFromRest() {
String message = " {\"forecasts\":[{\"period_end\":\"2021-01-15T01:00:00.0000000Z\",\"period\":\"PT30M\",\"ghi90\":0,\"ghi\":0,\"ghi10\":0},{\"period_end\":\"2021-01-15T01:30:00.0000000Z\",\"period\":\"PT31M\",\"ghi90\":0,\"ghi\":0,\"ghi10\":0},{\"period_end\":\"2021-01-15T02:00:00.0000000Z\",\"period\":\"PT32M\",\"ghi90\":0,\"ghi\":0,\"ghi10\":0}]}";
return message;
}
#Override
public void run(String... arg0) throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
String jsonAsText = getJsonAsTextFromRest();
ForecastGhi request = objectMapper.readValue(jsonAsText, ForecastGhi.class);
request.getForecast().stream().forEach(it -> System.out.println(it.getPeriod() + " " + it.getGhi()));
}
public class IrradianciaGlobalHorizontal {
private Date period_end;
private String period;
private int ghi90;
private int ghi;
private int ghi10;
public int getGhi() {
return this.ghi;
}
public void setGhi(int ghi) {
this.ghi = ghi;
}
public int getGhi90() {
return this.ghi90;
}
public void setGhi90(int ghi90) {
this.ghi90 = ghi90;
}
public int getGhi10() {
return this.ghi10;
}
void setGhi10(int ghi10) {
this.ghi10 = ghi10;
}
public Date getPeriod_end() {
return this.period_end;
}
public void setPeriod_end(Date period_end) {
this.period_end = period_end;
}
public String getPeriod() {
return this.period;
}
public void setPeriod(String period) {
this.period = period;
}
}
ForecastGhi class.
import com.fasterxml.jackson.annotation.JsonProperty;
public class ForecastGhi {
private ArrayList<IrradianciaGlobalHorizontal> forecast;
#JsonProperty("forecasts")//It must be the same as the json property
public ArrayList<IrradianciaGlobalHorizontal> getForecast() {
return forecast;
}
#JsonProperty("forecasts")
public void setForecast(ArrayList<IrradianciaGlobalHorizontal> forecast) {
this.forecast = forecast;
}
}
Results:
PT30M 0
PT31M 0
PT32M 0
Dependencies Gradle:
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.12.1'
Or
Dependencies Maven:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.1</version>
</dependency>
Note: in your json example you use forecasts, but your java property name is forecast. In that case its necessary to decorate the property with #JsonProperty("forecasts"). If you dont do it, you get an error like this com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "forecasts"

Spring Batch FlatFileItemReader populating field value across all items/lines read

I am reading a flat file using spring batch FlatFileItemReader.
I have a requestId field which i need to populate with a unique value for all records read from the flat file.
eg: When i read file1. I want to set the requestId to 1 for all Item objects created at requestId field. For file2, i need to set requestId to 2.
my requestId is uniquely generated by a separate class.
How can I achieve this using spring batch?
there are some possible solutions
use an ResourceAware Item
public class MyItem implements ResourceAware {
private Resource resource;
public String getId() {
return createIdFromResource(resource);
}
private String createIdFromResource(final Resource resource) {
// create your ID here
return resource.getFilename();
}
#Override
public void setResource(final Resource resource) {
this.resource = resource;
}
}
use an Listener (here with interfaces, less verbose use of annotations is possible too)
public class TestListener implements StepExecutionListener, ItemReadListener<String> {
private StepExecution stepExecution;
private static final String CURRENT_ID = "currentId";
#Override
public void beforeStep(final StepExecution stepExecution) {
this.stepExecution = stepExecution;
}
#Override
public ExitStatus afterStep(final StepExecution stepExecution) {
return null;
}
#Override
public void beforeRead() {
}
#Override
public void afterRead(final String item) {
String currentId = null;
if (stepExecution.getExecutionContext().containsKey(CURRENT_ID)) {
currentId = stepExecution.getExecutionContext().getString(CURRENT_ID);
} else {
String fileName = stepExecution.getExecutionContext().getString("fileName");
// ... create ID from FileName
currentId = fileName + "foo";
stepExecution.getExecutionContext().put(CURRENT_ID, currentId);
}
}
#Override
public void onReadError(final Exception ex) {
}
}
in the above example the current fileName is avavailable in the stepExecutionContext, it might be you have to pull it from jobParameters and extract the filename
String paramValue = stepExecution.getJobExecution().getJobParameters().getString("paramName");
// extract fileName from paramValue

Adding methods to AuthenticatedWebSession in Wicket 7 by extension

I'm using Wicket 7 and extending AuthenticatedWebSession as a class called BasicAuthenticatedSession. While I'm doing this, I'd like to add a method that returns some additional information about the authenticated user.
In BasicAuthenticatedSession#authenticate, I get a Sysuser object which is a wrapper for a user in the database. I use some of the information in this object for the authentication, but want to have access to all of the info (firstname, lastname, etc.) throughout the session.
I was expecting to be able to create a new method call getUser which would return this database object to the caller.
However, this method, even though declared public, isn't visible when attempting to call it. I'm not sure if this is something to do with Wicket, or just a general misunderstanding on my part how inheritance works. ;)
BasicAuthenticatedWebSession.java
public class BasicAuthenticatedWebSession extends AuthenticatedWebSession {
public BasicAuthenticatedWebSession(Request request) {
super(request);
}
#Override
protected boolean authenticate(String username, String password) {
Sysuser[] sysusers;
try {
SysuserCriteria userCriteria = new SysuserCriteria();
userCriteria.username.eq(username);
sysusers = Sysuser.listSysuserByCriteria(userCriteria);
} catch (PersistentException e) {
e.printStackTrace();
return false;
}
if (sysusers.length == 0) {
return false;
}
this.username = username;
this.userid = sysusers[0].getId();
return password.compareTo(sysusers[0].getPasswd()) == 0;
}
public Roles getRoles() {
Roles roles = new Roles();
Sysuser[] sysusers;
if (isSignedIn()) {
roles.add("SIGNED_IN");
}
try {
SysuserCriteria sysuserCriteria = new SysuserCriteria();
sysuserCriteria.username.eq(username);
sysusers = Sysuser.listSysuserByCriteria(sysuserCriteria);
for (Object sysuser : sysusers) {
SysroleSetCollection sysroles = ((Sysuser) sysuser).sysrole;
for (Sysrole sysrole : sysroles.toArray()) {
roles.add(sysrole.getRolename().toUpperCase());
}
}
} catch (PersistentException e) {
e.printStackTrace();
}
return roles;
}
public Sysuser getSysuser() {
return sysuser;
}
}
Test.java This class fails to compile as the getSysuser method in BasicAuthenticatedSession is not found.
public class Test {
public Test() {
}
public void foo {
if(BasicAuthenticatedSession.get().isSignedIn()) {
Sysuser sysUser = BasicAuthenticatedSession.get().getSysuser();
System.out.println(sysuser.getFirstname);
}
}
}
Wicket project require specific "override" of static methods, I guess that You return original wicket API session. Edited copy from my project (session is Your classname)
public class BasicAuthenticatedWebSession extends AuthenticatedWebSession {
public static BasicAuthenticatedWebSession get() {
return (BasicAuthenticatedWebSession ) Session.get();
}
...
}
and in XxxxxApplication class
public class MyProject extends AuthenticatedWebApplication
{
...
#Override
public Session newSession(Request request, Response response) {
return new BasicAuthenticatedWebSession (request);
}
}

How to read the WebMaster field with Rome

I am trying to use ROME to parse an RSS feed like this:
url = new URL("http://www.rssboard.org/files/sample-rss-2.xml");
XmlReader reader = new XmlReader(url);
SyndFeedInput input = new SyndFeedInput();
SyndFeed feed = input.build(reader);
System.out.println(feed.getAuthor());
However, I cannot find a method to get the "WebMaster" field or any other customized field.
I have read about the custom modules in Rome from here, but I couldn't figure out how to use it. I create a similar SamplleModule, SampleModuleImpl, and SampleModule Parser for webMaster field, but I don't know how to use it!
This the classes that I have implemented:
SamplleModule:
public interface SampleModule extends Module {
public static final String URI =
"http://www.rssboard.org/files/sample-rss-2.xml";
public String getWebMaster();
public void setWebMaster(String webMaster);
}
SampleModuleImpl:
public class SampleModuleImpl extends ModuleImpl implements SampleModule {
private static final long serialVersionUID = 1L;
private String _webMaster;
protected SampleModuleImpl() {
super(SampleModule.class, SampleModule.URI);
}
#Override
public void copyFrom(Object obj) {
SampleModule sm = (SampleModule) obj;
setWebMaster(sm.getWebMaster());
}
#Override
public Class getInterface() {
return SampleModule.class;
}
#Override
public String getWebMaster() {
return _webMaster;
}
#Override
public void setWebMaster(String webMaster) {
_webMaster = webMaster;
}
}
and SampleModuleParser:
public class SampleModuleParser implements ModuleParser {
private static final Namespace SAMPLE_NS = Namespace.getNamespace("sample",
SampleModule.URI);
#Override
public String getNamespaceUri() {
return SampleModule.URI;
}
#Override
public Module parse(Element dcRoot) {
boolean foundSomething = false;
SampleModule fm = new SampleModuleImpl();
Element e = dcRoot.getChild("webMaster");
if (e != null) {
foundSomething = true;
fm.setWebMaster(e.getText());
}
return (foundSomething) ? fm : null;
}
}
I have also added these module to rome.properties.
I just don't know how to use them in my reader method.
Any idea folks?
take a look here for an example of how do to this with the MRSS module:
http://ideas-and-code.blogspot.com/2009/07/media-rss-plugin-for-rome-howto.html
Basically you take a SyndEntry object and using the namespace for your module you get an instance of your module object from the entry if one exists, so in your case:
SampleModule myModule = (SampleModule)e.getModule( SampleModule.URI );
And then you can use it. I use groovy with rome for my parser and do things like this:
def mediaModule = entry.getModule("http://search.yahoo.com/mrss/")
if(mediaModule) {
mediaModule.getMediaGroups().each { group ->
group.contents.each { content ->
if(content.type != null && content.type.startsWith("image")) {
log.info "got an image"
String imgUrl = content.getReference().toString()
post.images.add(new MediaContent(type:'image',url:imgUrl))
}
}
}
}
HTH

Categories

Resources