Java client implementation for NGSI and ContextBroker communications - fiware

In order to not reinventing the wheel I am looking for some existing library for connecting to Orion Context Broker from Java code.
I have found that at fiware.org there is published sample code but I do not like it as it does not hide raw XML usage.
I have also found some code at github
Some people seems to have worked on it but I did not find the sources.
Is there some open library becoming popular reference on it? being API clean and easy to use and hiding low level things? (XML parsing, NGSI communications, REST, etc.)

We have build a NGSI V1 (JSON only) client library for the Fiware-Cepheus project.
In your pom.xml:
<dependency>
<groupId>com.orange.cepheus</groupId>
<artifactId>cepheus-ngsi</artifactId>
<version>4.4.3-SNAPSHOT</version>
</dependency>
In your code :
#Autowired
NgsiClient ngsiClient;
...
// Prepare UpdateContext
UpdateContext updateContext = new UpdateContext(UpdateAction.UPDATE);
ContextElement contextElement = new ContextElement();
contextElement.setEntityId(new EntityId("Room1", "Room", false));
ContextAttribute attr = new ContextAttribute("temp", "double", "20");
contextElement.setContextAttributeList(Collections.singletonList(attr);
updateContext.setContextElements(Collections.singletonList(contextElement));
// Synchronous call
ngsiClient.updateContext("http://broker:port", null, updateContext).get();
// Asynchronous call
ngsiClient.updateContext("http://broker:port", null, updateContext).addCallback(
updateContextResponse -> { /* success response */ },
throwable -> { /* error response */ });
This library is still under development (available as SNAPSHOT only on the Sonatype repository) and is not considered stable yet, but is fully tested.
It is missing support for many NGSI9 requests, but if your main use is NGSI10, you should be covered.

Related

Apache camel with spring DSL and Junit Coverage

I am completely new to apache camel.
I got some basic understanding about it.
Now I am going through some videos and documents to get some ideas for implementing junit test cases for apache camel spring DSL based spring boot application but it's not clear to me since there are many ways to implement or in very high level.
I am confused.. which one to follow and what is actually happening in those junits
Does anyone have example or link or videos which explains junit coverage for apache camel spring DSL based spring boot application?
I am particularly looking for junits.
also If you know someone good tutorials about apache camel let me know.
JUnit and Camel doesn't work the same as JUnit and "normal" code and as far as I am aware there's only fairly rudimentary ways to get coverage of a camel route from JUnit. Camel routes are a processing model that is essentially an in memory model of the various steps that need to run, so you can't use code coverage tools to track what parts get executed.
Consider this route (in a subclass of RouteBuilder ):
public void configure() throws Exception {
from("jms:queue:zzz_in_document_q")
.routeId("from_jms_to_processor_to_jms")
.transacted()
.log(LoggingLevel.INFO, "step 1/3: ${body}")
.bean(DocBean.class)
.log(LoggingLevel.INFO, "step 2/a3 - now I've got this: ${body}")
.process(new DocProcessor())
.log(LoggingLevel.INFO, "step 3/3 - and finally I've got this: ${body}")
.to("jms:queue:zzz_out_document_q");
}
and an associated test case, in a class that extends CamelBaseTestSupport:
#Test
public void testJmsAndDbNoInsert() throws Exception {
long docCountBefore = count("select * from document");
template.sendBody("jms:queue:zzz_in_document_q", new Long(100));
Exchange exchange = consumer.receive("jms:queue:zzz_out_document_q", 5000);
assertNotNull(exchange);
Document d = exchange.getIn().getBody(Document.class);
assertNotNull(d);
long docCountAfter = count("select * from document");
assertEquals(docCountAfter, docCountBefore);
}
When the unit test runs the app context will run the configure method, so I've got 100% coverage of my route before I even put a message on the queue! Except I don't, because all it's done is created the execution model in the camel route system and the various components and processors are now all going to run in the right order.
Beans and Processors will get included in the coverage reports, but if you have complex logic in the routes it's not going to give you coverage on this.
There is this capability, delivered around 2017 - https://issues.apache.org/jira/browse/CAMEL-8657 - but I haven't used it and am not sure how it will go working with whatever coverage tooling you use.

Can the ConfigurationAPI in Liferay DXP be used for Plugin sdk portlet?

I have followed given 2 tutorials to use COnfigurationAPI in a Liferay dxp plugins SDK portlet built using Ant/Ivy.
COnfiguration API 1
COnfiguration API 2.
Below is the configuration class used:
package com.preferences.interfaces;
import com.liferay.portal.configuration.metatype.annotations.ExtendedObjectClassDefinition;
import aQute.bnd.annotation.metatype.Meta;
#ExtendedObjectClassDefinition(
category = "preferences",
scope = ExtendedObjectClassDefinition.Scope.GROUP
)
#Meta.OCD(
id = "com.preferences.interfaces.UnsupportedBrowserGroupServiceConfiguration",
name = "UnsupportedBrowser.group.service.configuration.name"
)
public interface UnsupportedBrowserGroupServiceConfiguration {
#Meta.AD(deflt = "", required = false)
public String displayStyle();
#Meta.AD(deflt = "0", required = false)
public long displayStyleGroupId(long defaultDisplayStyleGroupId);
}
Post following the steps,I am getting the below error:
ERROR [CM Configuration Updater (ManagedService Update: pid=[com.preferences.interfaces.UnsupportedBrowserGroupServiceConfiguration])][org_apache_felix_configadmin:97] [org.osgi.service.cm.ManagedService, id=7082, bundle=297//com.liferay.portal.configuration.settings-2.0.15.jar?lpkgPath=C:\dev\Liferay\osgi\marketplace\Liferay Foundation.lpkg]: Unexpected problem updating configuration com.preferences.interfaces.UnsupportedBrowserGroupServiceConfiguration {org.osgi.service.cm.ConfigurationAdmin}={service.vendor=Apache Software Foundation, service.pid=org.apache.felix.cm.ConfigurationAdmin, service.description=Configuration Admin Service Specification 1.2 Implementation, service.id=56, service.bundleid=643, service.scope=bundle}
Caused by: java.lang.IllegalArgumentException: wrong number of arguments
So,does this process need a osgi module as mandatory or can we do it using plusings sdk portlet built using ant as well?
Without disecting the error message Caused by: java.lang.IllegalArgumentException: wrong number of arguments:
The way you build your plugin (Ant, Maven, Gradle, manually) doesn't make a difference, as long as you build a plugin that will be understood by the runtime. aQute.bnd.annotation.metatype.Meta points firmly into the OSGi world, and makes it almost certain that you'll need an OSGi module. You can build this with Ant, of course. Even in Ant you can embed tools like bnd, or you can write the proper Manifest.mf to include in your module manually (just kidding - you don't want to do it manually, but it would work).
Recommendation: Instead of moving everything over: Try to reproduce this with a minimal example in gradle or better Liferay Workspace (which is gradle based), just to get all the automatic wiring in. Check if it makes a difference and compare the generated output from your Ant build process with the workspace output. Pay specific attention to the Manifest.
In order to build the proper Manifest, you want to use bnd - if the Manifest turns out to be your issue: Find a way to embrace bnd - if that's by saying goodby to Ant, or by tweaking your build script remains your decision.

How to use Hystrix with Spring WebFlux WebClients?

I'm using Spring WebFlux with functional endpoints to create an API. To provide the results I want, I need to consume an external RESTful API, and to do that in a async way I'm using a WebClient implementation. It works well and goes like this:
public WeatherWebClient() {
this.weatherWebClient = WebClient.create("http://api.openweathermap.org/data/2.5/weather");
}
public Mono<WeatherApiResponse> getWeatherByCityName(String cityName) {
return weatherWebClient
.get()
.uri(uriBuilder -> uriBuilder
.queryParam("q", cityName)
.queryParam("units", "metric")
.queryParam("appid", API_KEY)
.build())
.accept(APPLICATION_JSON)
.retrieve()
.bodyToMono(WeatherApiResponse.class);
}
As this performs network access, it's a good use case for NetFlix OSS Hystrix. I've tried using spring-cloud-starter-netflix-hystrix, adding #HystrixCommand to the method above, but there's no way to make it trip the circuit, even if I set a bad URL (404) or wrong API_KEY (401).
I thought this could be a problem of compatibility with the WebFlux itself, but setting property #HystrixProperty(name="circuitBreaker.forceOpen", value="true") indeed forces the fallback method to run.
Am I missing something? Is this approach incompatible with Spring WebClients?
Thanks!
#HystrixCommand won't really work, because Hystrix doesn't threat Mono/Flux any different from Java primitives.
Hystrix doesn't monitor content of Mono, but only the result of call public Mono<WeatherApiResponse> getWeatherByCityName(String cityName).
This result is always OK, because reactive-call-chain creation will always succeed.
What you need, is to make Hystrix threat Mono/Flux differently.
In Spring Cloud, there is a builder, to wrap Mono/Flux with HystrixCommand.
Mono<WeatherApiResponse> call = this.getWeatherByCityName(String cityName);
Mono<WeatherApiResponse> callWrappedWithHystrix = HystrixCommands
.from(call)
.fallback(Mono.just(WeatherApiResponse.EMPTY))
.commandName("getWeatherByCityName")
.toMono();

How to send messages from server to client?

I am going to implement something similar to Facebook notification and this website (StackOverflow's notification which is notifying us if anyone write a comment/answer etc for our question). Please note users are going to use my application as a website not mobile application.
I came across following answer which fetch the results, but I need to push the results not fetch.
Based on suggestions I have created a simple method in my entity class and added the #PostPersist to it but it has not worked so based on this answer I added the persistence.xml file to define the listeners but after session.save(user) the aftersave method does not get triggered.
User.java
#Entity
public class User{
.....
#PostPersist
public void aftersave(){
System.err.println("*****this is post persist method****");
}
}
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!--
To change this template, choose Tools | Templates
and open the template in the editor.
-->
<property name="hibernate.ejb.event.pre-insert" value="my.hibernate.events.listeners.Listener" />
<property name="hibernate.ejb.event.pre-update" value="my.hibernate.events.listeners.Listener" />
<property name="hibernate.ejb.event.pre-delete" value="my.hibernate.events.listeners.Listener" />
<property name="hibernate.ejb.event.post-insert" value="my.hibernate.events.listeners.Listener" />
<property name="hibernate.ejb.event.post-update" value="my.hibernate.events.listeners.Listener" />
<property name="hibernate.ejb.event.post-delete" value="my.hibernate.events.listeners.Listener" />
pom.xml
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.2.1.Final</version>
<type>jar</type>
</dependency>
Sounds like a task for WebSockets. It is part of Java EE 7 so the Glassfish should be one of the first AS that will support it.
For intercepting the DB access you can use #PostUpdate and #PostPersist. Here is related question.
There are many ways to do the so called Server Push for notifying the connected clients:
polling (the link you've provided in the question ("Are we there yet? Are we there yet? ..."))
long polling (smarter way of polling - long-lived HTTP technique using keepalive messages)
WebSockets (JSR 356)
piggy-backing
SPDY(wiki)
Server-Sent Events (related answer, wiki)
EDIT: In the Java world, there are couple of frameworks where server push (reverse ajax) is implemented out-of-the box. If you are familiar with GWT, I would suggest Errai. Other alternative is the Atmospere. The downside of the Atmospere is the fact that it requires standalone running process next to your regular application server with your web app. I was playing with it a year ago so this may have been changed since then.
In general, it is hard to provide you with a concrete piece of code, because it depends on the framework you will choose. I am familiar with Errai so here is an example in it:
Server Side:
#ApplicationScoped
public class TickerService {
#Inject
private Event<Tick> tickEvent;
private void sendTick() {
tickEvent.fire(new Tick());
}
}
Client Side:
#EntryPoint
public class TickerClient {
public void tickHappened(#Observes Tick tick) {
// update the UI with the new data
}
}
Other benefits of using the Errai is having the CDI on the server and on the client out-of-the-box, another thing that is nice is using the web-sockets under the covers if it is supported and falling back to other solutions otherwise.
Whatever you choose, it should fit to your existing infrastructure and to your client side UI framework.
mqtt can be used for server pushing and message broadcasting.
There are more detail information in http://mqtt.org/.
======================================
Updated: Jul 11, 2013
Mqtt is a publish/subscribe, extremely simple and lightweight messaging protocol. If server is a publisher and client browser subscribe the topic which server publish to, then server can push message to client directly.
Some useful resource:
Mosquitto is an open sourced mqtt server. Easy to install and configure.
mqtt-client is a proven powerful java mqtt client.
Use Node JS and socket.io
This technology chooses the best transportation method based on the browser that the client is using.
For latest browsers it uses Web Sockets and for others it degrades gracefully to Flash Socket or Long Pooling. See more here
What you need to do is set up a server using these technologies. The server would run at a particular port. All clients would listen to that port and server would be able to push data to the client through that port.
Comet also known as Reverse Ajax, is a web application model in which a long-held HTTP request allows a web server to push data to a browser, without the browser explicitly requesting it.
Comet (AKA long lived http, server push) allows the server to start answering the browser's request for information very slowly, and to continue answering on a schedule dictated by the server. For more information about Comet, see the following:
Alex Russell's original post coining the term
The Wikipedia article on Comet
Comet Daily, a blog with regular posts on the subject
DWR is a Java library that enables Java on the server and JavaScript in a browser to interact and call each other as simply as possible.
With Reverse Ajax, DWR allows Java code running on a server to use client side APIs to publish updates to arbitrary groups of browsers. This allows interaction 2 ways - browser calling server and server calling browser. DWR supports Comet, Polling and Piggyback (sending data in with normal requests) as ways to publish to browsers.
DWR provides integration with Spring, Struts, Guice, Hibernate and others.
You can read more from here.
Other Comet and Reverse AJAX frameworks:
Grizzly Comet API
Atmosphere
AJAX push with ICEfaces
Asynchronous Servlet using Servlet 3.0
but after session.save(user) the aftersave method does not get triggered.
#PostPersist is a JPA callback.
session.save() is a non-JPA, hibernate proprietary method. JPA uses entityManager.persist().
you're using incompatible features
Check for update from server on every 30 Seconds or as per requirement.
window.setInterval(function(){
/// call your function here
//Make AJAX call
//Update Respective HTML Contact i,e, DIV
}, 30000);

Cannot Produce JSON with Maven quickstart grizzly Archetype

I've put some good hours trying to get my grizzly webserver to produce JSON.
Generated from maven archetype using Intellij, details:
groupId untitled3
artifactId untitled3
version 1.0-SNAPSHOT
archetypeGroupId org.glassfish.jersey.archetypes
archetypeArtifactId jersey-quickstart-grizzly2
archetypeVersion 2.0-m05
All online examples enable JSON using
rc.put(JSONConfiguration.FEATURE_POJO_MAPPING, true);
However, this does not work in jersey 2.x, put method does not exist.
In the application Main class, there is instructions on uncommenting a line of code to get JSON to work. When i uncomment this line of code, the method used does not exist.
public static HttpServer startServer() {
// create a resource config that scans for JAX-RS resources and providers
// in untitled2 package
final ResourceConfig rc = new ResourceConfig().packages("untitled2");
// uncomment the following line if you want to enable
// support for JSON on the service (you also have to uncomment
// dependency on jersey-media-json module in pom.xml)
// --
rc.addModule(org.glassfish.jersey.media.json.JsonJaxbModule);
// create and start a new instance of grizzly http server
// exposing the Jersey application at BASE_URI
return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
}
When i try to serve a JSON response from a POJO object i get this error:
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=application/json, type=class com.example.JsonPost, genericType=class com.example.JsonPost.
I've no idea where to begin to look really. I've googled, plown through documentation and looked through user groups...
Make sure you uncomment the dependency in the POM. Then change the addModule call to this:
rc.addModules(new org.glassfish.jersey.media.json.JsonJaxbModule());
and be sure to include the correct #Produces annotation on your resource:
#Produces(MediaType.APPLICATION_JSON)