Search code examples
socketsguidewiregosu

How can I create a server-side web socket connection in Guidewire Insurance Suite applications using GOSU?


I am trying to create a web socket connection in Guidewire Insurance Suite so that my app can behave as the server and I can push messages to a socket. This socket will help with reading messages from PC in near real-time so a front end can listen to and display these messages. The challenge is that I could not find a recommended approach in the Insurance Suite documentation. JSR365 annotations like @ServerEndpoint("/scoket-url/") and @OnOpen do not work with Guidewire even though the javax jars and present in platform code. I think the issue is probably that the endpoint never gets registered.

I figured out another approach to get it to work. I know that Guidewire provides the ability to register custom servlets by using the servlets.xml file. We can also define root servlets by tweaking web.xml and I experiemented with it, but I ended up with the below aproach using servlets.

servlets.xml

<servlet
    class="acc.xxx.GWWebSocketServlet"/>

WebSocketServlet.gs

@Servlet("/socket")
class GWWebSocketServlet extends WebSocketServlet {

  override function configure(webSocketServletFactory : WebSocketServletFactory) {
    webSocketServletFactory.register(Class.forName("acc.xxx.GWSocketListener"))
  }
}

GWSocketListener.gs

class GWSocketListener implements WebSocketListener {
  var _session : Session
  private static final var LOGGER = LoggerFactory.getLogger(GWSocketListener)

  override function onWebSocketBinary(bytes : byte[], i : int, i1 : int) {
    print("Binary Object received: " + bytes)
    LOGGER.info("Binary object received")
  }

  override function onWebSocketText(s : String) {
    print("Socket Message: " + s)
    LOGGER.info("Text received")
  }

  override function onWebSocketClose(i : int, s : String) {
    LOGGER.info("Closing a WebSocket %s", s)
  }

  override function onWebSocketConnect(session : Session) {
    print("############ Socket connection started ###############")
    session.getRemote().sendString("You are connected to the websocket server!!!")
    LOGGER.info("WebSocket opened with ", session.Remote)
    _session = session
  }

  override function onWebSocketError(throwable : Throwable) {
    LOGGER.error("Error in WebSocket session: ", throwable)
  }
}

This approach works for me and I am able to connect to the socket using the below endpoint with two-way communication.

enter image description here

However, I am not satified with this solution and was wondering what is the recommended way to create sockets in Guidewire. In case you didn't get the idea, I'm trying to build something like a live chat with Insurance Suite. If you think a socket isn't the right way to go about it then please share alternative approaches.


Solution

  • The reason why this isn't a straight forward task is that generally this isn't advisable to use WebSockets technology - in fact from upgradability perspective it isn't allowed in the Cloud to use any integration patterns outside of the RestAPI/CloudAPI or Integration Gateway. Custom servlets are disallowed in the Cloud as per the "IS-INT-1268" Cloud Standard.

    So as much as the above would work for the self managed version it's not a good idea to bound your Guidewire implementation to this. An isolation practise that would be relatively "safe" would be to spin up a microservice that would open up the WebSocket but communicate with Guidewire core application through RestAPI.