Integration of ibm watson conversation - ibm-watson

I'm currently working on creating chatbots using ibm watson conversation. I have created my chatbot in bluemix with the necessary intents and dialog. NowI want to integrate it with a java application. Can anyone help me on this.?

import com.ibm.watson.developer_cloud.conversation.v1.Conversation;
import com.ibm.watson.developer_cloud.conversation.v1.model.*;
public class Conversation {
public static void main( String[] args ) throws Exception
{
String input ="Hello";
//To Call Conversation Api to print its welcome Message.
response = conversationAPI("",context);
context = response.getContext();
response = conversationAPI(input,context);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static MessageResponse conversationAPI(String input,Context context)
{
Conversation service = new Conversation("");
service.setUsernameAndPassword("", ""); //
MessageOptions newMessage = new MessageOptions.Builder().workspaceId("").input(new InputData.Builder(input).build()).context(context).build();
MessageResponse response = service.message(newMessage).execute();
int TextSize= response.getOutput().getText().size();
for(int x=0;x<TextSize;x++)
{
System.out.println(response.getOutput().getText().get(x));
}
return response;
}
}

Related

Topshelf: Issues using NancyFX with Topshelf 4.2.1

I am trying to develop a data access service using Visual Studio 2019, .Net Core 3.0. I am using NancyFX to handle http requests. this is working just fine as a console application. When I build and run, then in browser go to HTTP://localhost/, it returns the proper data. I have a working Nancy module to handle requests. Here is original Main code:
static void Main(string[] args)
{
Logger.LogInfo("NancyDataService starting...");
var uri = new Uri(ConfigurationManager.AppSettings["uri"]);
var hostConfig = new HostConfiguration();
hostConfig.UrlReservations.CreateAutomatically = true;
hostConfig.RewriteLocalhost = false;
using (var nancyHost = new NancyHost(uri, new AppBootstrapper(), hostConfig))
{
try
{
nancyHost.Start();
Console.WriteLine($"Nancy now listening on {uri}.\n\nPress any key to exit");
Logger.LogInfo($"Nancy now listening on {uri}...");
}
catch (Exception ex)
{
Logger.LogError(ex.Message);
Console.WriteLine("Error " + ex.Message + "\n\nPress any key to exit");
}
Console.ReadKey();
Logger.LogInfo("NancyDataService stopped...");
}
}
Now I want to make it a Windows Service. First try is with Topshelf. The following Main code is basically taken from Topshelf documentation and other articles about Topshelf.
static void Main(string[] args)
{
Logger.LogInfo("NancyDataService starting...");
var rc = HostFactory.Run(x =>
{
x.Service<DataService>(s =>
{
s.ConstructUsing(name => new DataService());
s.WhenStarted(tc => tc.Start());
s.WhenStopped(tc => tc.Stop());
});
x.RunAsLocalSystem();
x.StartAutomatically();
x.EnableServiceRecovery(r => r.RestartService(TimeSpan.FromSeconds(10)));
x.SetServiceName("NancyDataService");
});
var exitCode = (int)Convert.ChangeType(rc, rc.GetTypeCode()); //11
Environment.ExitCode = exitCode;
}
Here is my DataService class, basically built from the Topshelf docs and a couple of articles I found:
class DataService
{
public DataService()
{
}
private SemaphoreSlim _semaphoreToRequestStop;
private Thread _thread;
public void Start()
{
// start Nancy here
var uri = new Uri(ConfigurationManager.AppSettings["uri"]);
var hostConfig = new HostConfiguration();
hostConfig.UrlReservations.CreateAutomatically = true;
hostConfig.RewriteLocalhost = false;
using var nancyHost = new NancyHost(uri, new AppBootstrapper(), hostConfig);
try
{
nancyHost.Start();
Console.WriteLine($"Nancy now listening on {uri}...");
Logger.LogInfo($"Nancy now listening on {uri}...");
// spin thread here
_semaphoreToRequestStop = new SemaphoreSlim(0);
_thread = new Thread(DoWork);
_thread.Start();
}
catch (Exception ex)
{
Logger.LogError(ex.Message);
Console.WriteLine($"Error: {ex.Message}");
}
}
private void DoWork(object obj)
{
while (true)
{
Console.WriteLine("doing work..");
if (_semaphoreToRequestStop.Wait(500))
{
Console.WriteLine("Stopped");
break;
}
}
}
public void Stop()
{
Logger.LogInfo("NancyDataService stopping...");
_semaphoreToRequestStop.Release();
_thread.Join();
//return true;
}
}
So now when I run the project in design mode (which Topshelf says you should be able to do), it seems to start fine and Nancy seems to be listening on the right port. However, when I go to the browser and type in HTTP//localhost:8080/, I get "This site can't be reached. localhost refused to connect"
I have the latest version of Topshelf (4.2.1) and Topshelf.Log4Net packages.
Can anyone shed any light on this? Thanks...
Solved this issue. Turned out to be incorrect scoping of my NancyHost object. Works fine now.

Codename One WebSocket + Spring Boot

About the Codename One Websocket cn1lib, I saw your lesson on the Whatsapp clone, however the code you proposed is for a complete app. Could you provide a simpler self-enclosed example of use of Websocket cn1lib with client-side code (Codename One code to send and receive messages) and server-side code (Spring Boot Java 8 to receive and send messages)?
I’m particulary interested in a simple Spring Boot example that interacts with Codename One, as start point to better understand and learn websocket.
Thank you
It would look roughly like this on the server:
public class WebSocketServer extends TextWebSocketHandler {
private static final Object LOCK = new Object();
private Map<String, WebSocketSession> sessions = new HashMap<>();
#Override
protected void handleTextMessage(WebSocketSession session,
TextMessage message) throws Exception {
Gson gson = new Gson();
MyDTO parsed = gson.fromJson(message.getPayload(), MyDTO.class);
// ... do stuff with incoming message
synchronized(LOCK) {
if(!sessions.contains(parsed.getId()) {
sessions.put(parsed.getId(), session);
}
}
}
public boolean sendMessage(String destId, String json) {
Session s = null;
synchronized(LOCK) {
s = sessions.get(destId);
}
if (s != null && s.isOpen()) {
try {
s.sendMessage(new TextMessage(s));
return true;
} catch (IOException e) {
synchronized(LOCK) {
sessions.remove(destId);
}
}
}
return false;
}
}

Apache Camel - Create mock endpoint to listen to messages sent from within a processor

I have a route as follows:
from(fromEndpoint).routeId("ticketRoute")
.log("Received Tickets : ${body}")
.doTry()
.process(exchange -> {
List<TradeTicketDto> ticketDtos = (List<TradeTicketDto>) exchange.getIn().getBody();
ticketDtos.stream()
.forEach(t -> solaceMessagePublisher.sendAsText("BOOKINGSERVICE.TICKET.UPDATED", t));
ticketToTradeConverter.convert(ticketDtos)
.forEach(t -> solaceMessagePublisher.sendAsText("BOOKINGSERVICE.TRADE.UPDATED", t));
}).doCatch(java.lang.RuntimeException.class)
.log(exceptionMessage().toString() + " --> ${body}");
solaceMessagePublisher is a utility class in application which performs some action on passed object (second argument) and finally converts it to json string and sends to a jms topic (first argument).
SolaceMessagePublisher.java
public void sendAsText(final String destinationKey, Object payload) {
LOGGER.debug("Sending object as text to %s",destinationKey);
String destinationValue = null;
if (StringUtils.isNotEmpty(destinationKey)) {
destinationValue = properties.getProperty(destinationKey);
}
LOGGER.debug("Identified Destination Value = %s from key %s", destinationValue,destinationKey);
if (StringUtils.isEmpty(destinationValue)) {
throw new BaseServiceException("Invalid destination for message");
}
sendAsTextToDestination(destinationValue, payload);
}
public void sendAsTextToDestination(final String destinationValue, Object payload) {
if (payload == null) {
LOGGER.debug(" %s %s",EMPTY_PAYLOAD_ERROR_MESSAGE, destinationValue);
return;
}
final String message = messageCreator.createMessageEnvelopAsJSON(payload, ContextProvider.getUserInContext());
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Created message = " + message);
}
jmsTemplate.send(destinationValue, new MessageCreator() {
#Override
public Message createMessage(Session session) throws JMSException {
LOGGER.debug("Creating JMS Text Message");
return session.createTextMessage(message);
}
});
}
I am having a problem in creating a mock endpoint to listen to messages sent to this topic. Question is how to listen to the messages sent to a topic which is out of camel context?
I have tried in my Test using mock:jms:endpoint. It doesn't work.
My Test is as below
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = { SiteMain.class })
public class TicketRouteCamelTest extends CamelSpringTestSupport{
#Autowired
protected BaseMessageEnvelopCreator messageCreator;
private static final String MOCK_TICKET_UPDATED_QUEUE = "direct:mockTicketUpdated";
#Before
public void configureMockEndpoints() throws Exception {
//mock input
final AdviceWithRouteBuilder mockRouteAdvice = new AdviceWithRouteBuilder() {
#Override
public void configure() throws Exception {
replaceFromWith(MOCK_TICKET_UPDATED_QUEUE);
}
};
context().getRouteDefinition("ticketRoute").adviceWith(context(), mockRouteAdvice);
}
#Test
public void testTicketRouteWithListOfTickets() throws Exception {
//create test data
TradeTicketDto tradeTicketDto = TradeTestDataHelper.getTradeTicketDto();
//create an exchange and set its body with test data
List<TradeTicketDto> list = new ArrayList<>();
list.add(tradeTicketDto);
list.add(tradeTicketDto);
Exchange requestExchange = ExchangeBuilder.anExchange(context()).build();
requestExchange.getIn().setBody(list);
//create assert on the mock endpoints
MockEndpoint mockTicketUpdatedEndpoint = getMockEndpoint("mock:DEV/bookingservice/ticket/updated");
mockTicketUpdatedEndpoint.expectedBodiesReceived(
messageCreator.createMessageEnvelopAsJSON(list.get(0), ContextProvider.getUserInContext()),
messageCreator.createMessageEnvelopAsJSON(list.get(1), ContextProvider.getUserInContext()) );
MockEndpoint mockTradeUpdatedEndpoint = getMockEndpoint("mock:DEV/bookingservice/trade/updated");
mockTradeUpdatedEndpoint.expectedBodiesReceived(
messageCreator.createMessageEnvelopAsJSON(list.get(0).getTicketInstruments().get(0), ContextProvider.getUserInContext()),
messageCreator.createMessageEnvelopAsJSON(list.get(0).getTicketInstruments().get(1), ContextProvider.getUserInContext()),
messageCreator.createMessageEnvelopAsJSON(list.get(1).getTicketInstruments().get(0), ContextProvider.getUserInContext()),
messageCreator.createMessageEnvelopAsJSON(list.get(1).getTicketInstruments().get(1), ContextProvider.getUserInContext()));
//send test exchange to request mock endpoint
template.send(MOCK_TICKET_UPDATED_QUEUE, requestExchange);
//test the asserts
assertMockEndpointsSatisfied();
}
}
On running test actual bodies received on mockendpont is 0
Mock is NOT a queue for consumers/producers to exchange data. Its a sink for testing purpose where you can setup expectations on the mock.
If you want to simulate a JMS via some kind of other means, then take a look at the stub component: http://camel.apache.org/stub
Its also listed in the bottom of the testing docs at: http://camel.apache.org/testing

ConnectionRequest when the app is in the background

I've tested Geofence example by cn1 where it sets local notification. When the app is closed(get destroyed), it still gives notification. But I want to get location through GPS and run connectionRequest to save them in the server. I replaced the connectionRequest code instead of LocalNotification in following code but it doesnot work. What should I do to run the connectionRequest when the app is closed(not when it is minimized but destroyed) so that once the user installs and close (destroys) it, the app sent his/her location data in the server forever untill the app is uninstalled.
Geofence gf = new Geofence("test", loc, 100, 100000);
LocationManager.getLocationManager().addGeoFencing(GeofenceListenerImpl.class, gf);
Geofence with localNotification:
public class GeofenceListenerImpl implements GeofenceListener {
#Override
public void onExit(String id) {
}
#Override
public void onEntered(String id) {
if(Display.getInstance().isMinimized()) {
Display.getInstance().callSerially(() -> {
Dialog.show("Welcome", "Thanks for arriving", "OK", null);
});
} else {
LocalNotification ln = new LocalNotification();
ln.setId("LnMessage");
ln.setAlertTitle("Welcome");
ln.setAlertBody("Thanks for arriving!");
Display.getInstance().scheduleLocalNotification(ln, 10, LocalNotification.REPEAT_NONE);
}
}
}
Why the following doesnot work? (it only work when the app is running or is minimized but not when it is destroyed.)
public class GeofenceListenerImpl implements GeofenceListener {
#Override
public void onExit(String id) {
System.out.println("geofence onExit");
}
#Override
public void onEntered(String id) {
if(Display.getInstance().isMinimized()) {
Display.getInstance().callSerially(() -> {
System.out.println("geofence isMinimized");
});
} else {
System.out.println("geofence when app is closed");
//I want to run connectionRequest here but is not working
}
}
}
PS. I've used background fetch but it only works when the app is minimized.
Update1: Demo of how I used connectionRequest outside of minimized() method...
public class GeofenceListenerImpl implements GeofenceListener {
#Override
public void onExit(String id) {
System.out.println("geofence onExit");
}
#Override
public void onEntered(String id) {
if(Display.getInstance().isMinimized()) {
Display.getInstance().callSerially(() -> {
});
} else {
System.out.println("geofence when app is closed");
Connection c = new Connection();
c.liveTrackConnectionMethod("22" , "23");
}
}
}
Connection class
public class Connection {
ArrayList<Map<String, Object>> response;
public void liveTrackConnectionMethod(String lat, String lon) {
ConnectionRequest cr = new ConnectionRequest() {
#Override
protected void readResponse(InputStream input) throws IOException {
JSONParser jSONParser = new JSONParser();
Map parser = jSONParser.parseJSON(new InputStreamReader(input));
response = null;
}
};
cr.setPost(true);
cr.setUrl("http://url.com");
cr.addArgument("userid", Preferences.get(AllUrls.userIdPreference, null));
cr.addArgument("lat", lat + "");
cr.addArgument("long", lon + "");
cr.addRequestHeader("Accept", "application/json");
NetworkManager.getInstance().addToQueueAndWait(cr);
}
}
I think an app will always return false for isMinimized() when the app is closed or minimized (i.e. not currently running in the foreground) I may be wrong about this.
Try calling your connectionRequest script outside the isMinimized(). After all, you will want to keep track of user location whether they are using the app or not.
Your first solution with LocalNotification will show users a notification by calling the else part, rather than the Dialog when they're using the app, because isMinimized() will be false.

Using OkHttp client via OKClient on Google App Engine throws a "java.lang.NoClassDefFoundError: java.net.ProxySelector" is a restricted class error

I am trying to use OKHTTP (version 2.4.0) along retrofit (1.9.0) on google app engine (1.9.22).
Here is the how i use it:
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setConnectTimeout(COMPOSER_MODULE_CONNECTION_TIMEOUT, TimeUnit.SECONDS);
okHttpClient.setReadTimeout(COMPOSER_MODULE_SOCKET_TIMEOUT, TimeUnit.SECONDS);
RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setConverter(new JacksonConverter())
.setEndpoint(ENDPOINT_PATH)
.setClient(new OkClient(okHttpClient))
.build();
This throws the following error:
java.lang.NoClassDefFoundError: java.net.ProxySelector is a restricted class. Please see the Google App Engine developer's guide for more details.
at com.google.apphosting.runtime.security.shared.stub.java.net.ProxySelector.<clinit>(ProxySelector.java)
at com.squareup.okhttp.OkHttpClient.copyWithDefaults(OkHttpClient.java:614)
at com.squareup.okhttp.Call.<init>(Call.java:50)
at com.squareup.okhttp.OkHttpClient.newCall(OkHttpClient.java:595)
at retrofit.client.OkClient.execute(OkClient.java:53)
I gather from the error that "java.net.ProxySelector" is not white-listed for use on google appengine.
Question 1)
Is it possible to use OKHTTP (version 2.4.0) along retrofit (1.9.0) on google app engine (1.9.22)? i.e, is there a work around for this error
if not,
Question 2)
Are there any other way to:
(a) use async HTTP calls with google appengine (with URLFetchService, for instance) ?
(b) set connection and socket timeouts for the client used from (a) ?
The links i have come across via search:
(1) Retrofit timeout configuration for clients
(2) Google App Engine URL Fetch Java API
You can use HttpUrlConnection with Retrofit2 to use it in Google APP Engine
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.servlet.http.HttpServletResponse;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;
public class RetrofitCall implements Call {
Request request;
RetrofitCall(Request request) {
this.request = request;
}
#Override
public Request request() {
return request;
}
#Override
public Response execute() throws IOException {
URL url = request.url().url();
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.setRequestMethod(request.method());
Headers headers = request.headers();
if (headers != null) {
for (int i = 0; i < headers.size(); i++) {
String name = headers.name(i);
connection.setRequestProperty(name, headers.get(name));
}
}
if (request.body() != null) {
BufferedSink outbuf;
outbuf = Okio.buffer(Okio.sink(connection.getOutputStream()));
request.body().writeTo(outbuf);
outbuf.close();
}
connection.connect();
final BufferedSource source = Okio.buffer(Okio.source(connection.getInputStream()));
if (connection.getResponseCode() != HttpServletResponse.SC_OK) {
throw new IOException("Fail to call " + " :: " + source.readUtf8());
}
Response response = new Response.Builder()
.code(connection.getResponseCode())
.message(connection.getResponseMessage())
.request(request)
.protocol(Protocol.HTTP_1_1)
.body(new ResponseBody() {
#Override
public MediaType contentType() {
return MediaType.parse(connection.getContentType());
}
#Override
public long contentLength() {
return connection.getContentLengthLong();
}
#Override
public BufferedSource source() {
return source;
}
})
.build();
return response;
}
#Override
public void enqueue(Callback responseCallback) {
}
#Override
public void cancel() {
}
#Override
public boolean isExecuted() {
return false;
}
#Override
public boolean isCanceled() {
return false;
}
public static class Factory implements Call.Factory {
#Override
public Call newCall(Request request) {
return new RetrofitCall(request);
}
}
}
You can use the following code snippet to run Retorifit2 with GAE limitations. It contains a lot of debugging stuffs free to remove in production and does not implement real async call.
okhttp3.Call.Factory gaeCallFactory = new okhttp3.Call.Factory() {
#Override
public okhttp3.Call newCall(final Request request) {
final URL url = request.url().url();
final String method = url.toString();
return new okhttp3.Call() {
#Override
public Request request() {
return request;
}
#Override
public Response execute() throws IOException {
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setUseCaches(false);
if (request.body() != null) {
//TODO ajust for different needs
connection.setRequestProperty("Content-Type", "application/json");
connection.setDoOutput(true);
BufferedSink outbuf;
ByteArrayOutputStream out = new ByteArrayOutputStream();
outbuf = Okio.buffer(Okio.sink(out));
request.body().writeTo(outbuf);
outbuf.close();
logger.info("Calling " + method + "\n" + new String(out.toByteArray()));
outbuf = Okio.buffer(Okio.sink(connection.getOutputStream()));
request.body().writeTo(outbuf);
outbuf.close();
} else {
logger.info("Calling " + method);
}
final BufferedSource source = Okio.buffer(Okio.source(connection.getInputStream()));
if (connection.getResponseCode() != HttpServletResponse.SC_OK) {
throw new IOException("Fail to call " + method + " :: " + source.readUtf8());
}
Response response = new Response.Builder()
.code(connection.getResponseCode())
.message(connection.getResponseMessage())
.request(request)
.protocol(Protocol.HTTP_1_1)
.body(new ResponseBody() {
#Override
public MediaType contentType() {
return MediaType.parse(connection.getContentType());
}
#Override
public long contentLength() {
return connection.getContentLengthLong();
}
#Override
public BufferedSource source() {
return source;
}
})
.build();
logger.info("Call response code: " + response.code() + " message: " + response.message());
return response;
}
#Override
public void enqueue(Callback responseCallback) {
try {
responseCallback.onResponse(this, execute());
} catch (IOException e) {
responseCallback.onFailure(this, e);
}
}
#Override
public void cancel() {
}
#Override
public boolean isExecuted() {
return false;
}
#Override
public boolean isCanceled() {
return false;
}
};
}
};
Retrofit retrofit = new Retrofit.Builder()
.callFactory(gaeCallFactory)
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(ENDPOINT_URI)
.build();
You need to use the Appengine URLFetchClient instead of the OkHttpClient. Like this:
import retrofit.appengine.UrlFetchClient;
RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setConverter(new JacksonConverter())
.setEndpoint(ENDPOINT_PATH)
.setClient(new UrlFetchClient())
.build();
Please note this only works with Retrofit1, this will not work with Retrofit2 because it's coupled directly to OkHttp as explained by Jake Wharton here

Resources