Code Monkey home page Code Monkey logo

ari4java's Introduction

ARI4Java

The Asterisk REST Interface (ARI) bindings for Java.

Maven Central javadoc Build

Description

ARI is an interface available on Asterisk 11+ that lets you write applications that run externally and control call flow through REST calls while receiving events on a websocket.

In order to support different versions of the API, what we do is we maintain concrete implementations for each version of the API, but we also have general interfaces that are used to work with objects across different versions.

Getting started

Simply add the library and an SLF4J logger to your package config, here is an example using Gradle

repositories {
    mavenCentral()
}

dependencies {
    implementation 'io.github.ari4java:ari4java:+'
    implementation 'ch.qos.logback:logback-classic:1.2.10'
}

Due to the sun setting of JCenter the jar is now publish through Sonatype to Maven Central but under a new groupId. The groupId is now io.github.ari4java make sure you update your build files if you used ch.loway.oss.ari4java.

Documentation

Licensing

The library is released under the GNU LGPL (see LICENSE file). Files under codegen-data come from the Asterisk project and are licensed under the GPLv2 (see LICENSE.asterisk file therein). They are only used to build the classes and are not distributed in any form with ARI4Java.

ari4java's People

Contributors

bweschke avatar grahambrown11 avatar guss77 avatar jbreitung avatar l3nz avatar naamagertel avatar pell-je avatar rattenburg avatar sebmurrayqi avatar vladimirbelyakof avatar workingintheblackforest avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ari4java's Issues

Throws exception on successful (201) HTTP response code

I'm using ARI 1.8.0 on Asterisk 13.5.0 and I noticed I was getting an exception thrown every time I tried to play an audio file, but the play was successful. When I ngrep'd the traffic, I saw this was the response:

HTTP/1.1 201 Created
Server: Asterisk/13.5.0
Date: Wed, 23 Sep 2015 17:49:51 GMT
Connection: close
Cache-Control: no-cache, no-store
Location: /playback/3kH7iFgvjn
Content-type: application/json
Content-Length: 144

{
  "id": "3kH7iFgvjn",
  "media_uri": "sound:tt-weasels",
  "target_uri": "channel:1443030590.10",
  "language": "en-us",
  "state": "queued"
}

In classes/ch/loway/oss/ari4java/tools/http/NettyHttpClient.java, the code explicitly checks for OK (200) and NO_CONTENT (204), but a 201 will fall through to the exception throwing code. I assume this is new behavior on behalf of Asterisk, but a 201 should still be considered successful.

Test byte[] results

Since Asterisk 14 we have

// byte[] getStoredFile String
/**********************************************************
 * Get the file associated with the stored recording.
 * 
 * 
 * @since ari_1_10_0
 *********************************************************/
public byte[] getStoredFile(String recordingName) throws RestException;

As it was never used, it would make sense to test drive this and confirm it does work.

See issue #45

Connections as IM_FEELING_LUCKY should autodetect version

When you connect as IM_FEELING_LUCKY, you should have a way to know which version is actually in use.
If you connect to an Asterisk that uses a newer version of the ARI, it should use the latest interface; while if you connect using a specific token, it should abort on the wrong version.

Better error message on unimplemented methods

At the moment we have a very opaque error message - this comes from Channel in ARI 1.0.0

  • @SInCE ari_1_5_0
    *********************************************************/
    public void snoopChannel(String channelId, .....){
    throw new UnsupportedOperationException("Method availble from ...");
    }

It should be something like:
Method available since ARI_1_5_0 but remote end is ARI_1_0_0

So it makes more sense.

FindBugs: inconsistent synchronization

Code Warning

IS Inconsistent synchronization of ch.loway.oss.ari4java.tools.BaseAriAction.forcedResponse; locked 80% of time

IS Inconsistent synchronization of ch.loway.oss.ari4java.tools.BaseAriAction.wsUpgrade; locked 50% of time

Javadocs: misc warnings to be fixed

:javadoc
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/tools/MessageQueue.java:48: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/tools/MessageQueue.java:68: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/ARI.java:420: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/ARI.java:455: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/ARI.java:464: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/ARI.java:473: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/ARI.java:482: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/ARI.java:491: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/ARI.java:500: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/ARI.java:509: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/ARI.java:518: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/ARI.java:527: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/ARI.java:536: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/ARI.java:552: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/ARI.java:287: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/ARI.java:357: warning - @return tag has no arguments.
/Users/lenz/dev/github/ari4java/build/classes_subst/ch/loway/oss/ari4java/AriVersion.java:55: warning - @return tag has no arguments.
17 warnings
:javadocJar

"Inactive Stasis app 'AriStart' missed message" logs after ari.cleanup()

I'm getting log message "Inactive Stasis app 'AriStart' missed message" in Asterisk CLI after I close my ari app with ari.cleanup() method.

My 'AriStart' app subscribes to all events at the beginning. At the end, after cleanup is called everything seems to be fine, but later, every few minutes I'm getting 'inactive app' message. Here is CLI log:

Deactivating Stasis app 'AriStart'
== WebSocket connection from '192.168.0.67:56988' closed
-- Inactive Stasis app 'AriStart' missed message
-- Inactive Stasis app 'AriStart' missed message
-- Inactive Stasis app 'AriStart' missed message
...

I know what is missed message about - one SIP client is always producing PeerStatusChange event for some reason, but this is irrelevant here.

Do I miss something, should I call additionaly unsubscribe all somehow?

Leaked shutDownGroup = new NioEventLoopGroup()

Apps using NettyHttpClient won't terminate unless calling exit().

Thread shutDownGroup is still running after NettyHttpClient.destroy()

2 Threads pools are created by NeyytHttpClient's constructor: group and shutDownGroup.
public NettyHttpClient() {
group = new NioEventLoopGroup();
shutDownGroup = new NioEventLoopGroup();
}

On destroy by destroy(), only group is terminated using shutdownGracefully.
ShutDownGroup is left running.

public void destroy() {
    // use a different event group to execute the shutdown to avoid deadlocks
    shutDownGroup.schedule(new Runnable() {
        @Override
        public void run() {
            if (wsClientConnection != null) {
                try {
                    wsClientConnection.disconnect();
                } catch (RestException e) {
                    // not bubbling exception up, just ignoring
                }
            }
            if (group != null && !group.isShuttingDown()) {
                **group.shutdownGracefully(5, 10, TimeUnit.SECONDS).syncUninterruptibly();**
                group = null;
            }
        }
    }, 250L, TimeUnit.MILLISECONDS);
}

mailboxes.json not generated

Any reason why mailboxes.json is not processed by run.java

private static void loadAsteriskDefs( DefMapper dm, String srcVer ) throws IOException {

    String srcDir = SOURCES + srcVer + "/";

    dm.clean( srcVer );
    dm.parseJsonDefinition( new File(srcDir + "applications.json"), srcVer, false );
    dm.parseJsonDefinition( new File(srcDir + "asterisk.json"), srcVer, false );
    dm.parseJsonDefinition( new File(srcDir + "bridges.json"), srcVer, false );
    dm.parseJsonDefinition( new File(srcDir + "channels.json"), srcVer, false );
    dm.parseJsonDefinition( new File(srcDir + "endpoints.json"), srcVer, false );
    dm.parseJsonDefinition( new File(srcDir + "playbacks.json"), srcVer, false );
    dm.parseJsonDefinition( new File(srcDir + "recordings.json"), srcVer, false );
    dm.parseJsonDefinition( new File(srcDir + "sounds.json"), srcVer, false );
    dm.parseJsonDefinition( new File(srcDir + "deviceStates.json"), srcVer, false );
    dm.parseJsonDefinition( new File(srcDir + "events.json"), srcVer, true );

//??? dm.parseJsonDefinition( new File(srcDir + "mailboxes.json"), srcVer, false );

}

WS Reconnect

Hi

I have a problem with the websocket connection being closed by Asterisk then I no longer receive events... Is there a way I can test the connection and reset it?

Here is a stack trace that is printed out on the console, but the onFailure callback is not called

java.io.IOException: java.util.concurrent.ExecutionException: java.io.IOException: Broken pipe
    at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:243)
    at org.apache.tomcat.websocket.WsSession.sendCloseMessage(WsSession.java:487)
    at org.apache.tomcat.websocket.WsSession.onClose(WsSession.java:441)
    at org.apache.tomcat.websocket.WsFrameBase.processDataControl(WsFrameBase.java:324)
    at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:270)
    at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:116)
    at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:54)
    at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:194)
    at org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:203)
    at org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:92)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:609)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1695)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.util.concurrent.ExecutionException: java.io.IOException: Broken pipe
    at org.apache.tomcat.websocket.FutureToSendHandler.get(FutureToSendHandler.java:102)
    at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:238)
    ... 16 common frames omitted
Caused by: java.io.IOException: Broken pipe
    at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
    at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47)
    at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
    at sun.nio.ch.IOUtil.write(IOUtil.java:65)
    at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:470)
    at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:128)
    at org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:185)
    at org.apache.coyote.http11.upgrade.NioServletOutputStream.doWriteInternal(NioServletOutputStream.java:94)
    at org.apache.coyote.http11.upgrade.NioServletOutputStream.doWrite(NioServletOutputStream.java:61)
    at org.apache.coyote.http11.upgrade.AbstractServletOutputStream.writeInternal(AbstractServletOutputStream.java:153)
    at org.apache.coyote.http11.upgrade.AbstractServletOutputStream.write(AbstractServletOutputStream.java:121)
    at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.onWritePossible(WsRemoteEndpointImplServer.java:94)
    at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite(WsRemoteEndpointImplServer.java:81)
    at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:393)
    at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessage(WsRemoteEndpointImplBase.java:287)
    at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:233)
    ... 16 common frames omitted 

BTW thank you for the API

Test of AriFactory connections

When we connect through the AriFactory, we should make sure that the connection actually works. Not sure which call to make, I wonder which is the most lightweight one.

Multiple ARI Objects

I am using ARI in an environment where there are multiple Asterisk servers that one stasis application is managing. This means I have multiple ARI objects. Also, as it turns out, Asterisk does not scale up very well. In Asterisk only a single thread manages one websocket connection, so for higher call volume multiple websockets are needed to even connect to one server.

When reconnecting a failed connection in this environment, the specific URL for the failed ARI needs to be known. To solve this I have added a url property to the ARI class.

Adding Event.Type enum for cleaner coding

At the moment, when you receive an event, you have to manually check its type and cast it.

Unfortunately Java does not support a syntax like:

switch ( myEvent.getClass ) {
case XXX:
do something....
}

so you have to resort to long lines of "if (x instanceof EVENT) else ..." that frankly suck.

I would like to have an Event.Type enum and a getType() method in the Event interface so that you can switch over them.

Larger maximum response

Since the underlying netty request is limited to 256 (code line 60) * 1024 KB (code line 87), the request of the list is too big.
To resolve the problem, you can double the size of
public static final int MAX_HTTP_REQUEST_KB = 256;
to
public static final int MAX_HTTP_REQUEST_KB = 512;
on line 60 in NettyHTTPClient.java and recompile.

FindBugs: expose internal representation (dates)

(Stoopid Java Date objects)

Malicious code vulnerability Warnings

Code Warning
EI ch.loway.oss.ari4java.generated.ari_0_0_1.models.Channel_impl_ari_0_0_1.getCreationtime() may expose internal representation by returning Channel_impl_ari_0_0_1.creationtime
EI ch.loway.oss.ari4java.generated.ari_0_0_1.models.Event_impl_ari_0_0_1.getTimestamp() may expose internal representation by returning Event_impl_ari_0_0_1.timestamp
EI ch.loway.oss.ari4java.generated.ari_0_0_1.models.StatusInfo_impl_ari_0_0_1.getLast_reload_time() may expose internal representation by returning StatusInfo_impl_ari_0_0_1.last_reload_time
EI ch.loway.oss.ari4java.generated.ari_0_0_1.models.StatusInfo_impl_ari_0_0_1.getStartup_time() may expose internal representation by returning StatusInfo_impl_ari_0_0_1.startup_time
EI ch.loway.oss.ari4java.generated.ari_1_0_0.models.Channel_impl_ari_1_0_0.getCreationtime() may expose internal representation by returning Channel_impl_ari_1_0_0.creationtime
EI ch.loway.oss.ari4java.generated.ari_1_0_0.models.Event_impl_ari_1_0_0.getTimestamp() may expose internal representation by returning Event_impl_ari_1_0_0.timestamp
EI ch.loway.oss.ari4java.generated.ari_1_0_0.models.StatusInfo_impl_ari_1_0_0.getLast_reload_time() may expose internal representation by returning StatusInfo_impl_ari_1_0_0.last_reload_time
EI ch.loway.oss.ari4java.generated.ari_1_0_0.models.StatusInfo_impl_ari_1_0_0.getStartup_time() may expose internal representation by returning StatusInfo_impl_ari_1_0_0.startup_time
EI2 ch.loway.oss.ari4java.generated.ari_0_0_1.models.Channel_impl_ari_0_0_1.setCreationtime(Date) may expose internal representation by storing an externally mutable object into Channel_impl_ari_0_0_1.creationtime
EI2 ch.loway.oss.ari4java.generated.ari_0_0_1.models.Event_impl_ari_0_0_1.setTimestamp(Date) may expose internal representation by storing an externally mutable object into Event_impl_ari_0_0_1.timestamp
EI2 ch.loway.oss.ari4java.generated.ari_0_0_1.models.StatusInfo_impl_ari_0_0_1.setLast_reload_time(Date) may expose internal representation by storing an externally mutable object into StatusInfo_impl_ari_0_0_1.last_reload_time
EI2 ch.loway.oss.ari4java.generated.ari_0_0_1.models.StatusInfo_impl_ari_0_0_1.setStartup_time(Date) may expose internal representation by storing an externally mutable object into StatusInfo_impl_ari_0_0_1.startup_time
EI2 ch.loway.oss.ari4java.generated.ari_1_0_0.models.Channel_impl_ari_1_0_0.setCreationtime(Date) may expose internal representation by storing an externally mutable object into Channel_impl_ari_1_0_0.creationtime
EI2 ch.loway.oss.ari4java.generated.ari_1_0_0.models.Event_impl_ari_1_0_0.setTimestamp(Date) may expose internal representation by storing an externally mutable object into Event_impl_ari_1_0_0.timestamp
EI2 ch.loway.oss.ari4java.generated.ari_1_0_0.models.StatusInfo_impl_ari_1_0_0.setLast_reload_time(Date) may expose internal representation by storing an externally mutable object into StatusInfo_impl_ari_1_0_0.last_reload_time
EI2 ch.loway.oss.ari4java.generated.ari_1_0_0.models.StatusInfo_impl_ari_1_0_0.setStartup_time(Date) may expose internal representation by storing an externally mutable object into StatusInfo_impl_ari_1_0_0.startup_time

Autodetection of Asterisk version

It would be nice to have a way to auto-detect the Asterisk version used - so that you simply point ari4java to a specific ARI interface and get a connection speaking the correct server language.

Handling of "plural" forms

Parameters that could be multiple are handled as only one item. I would like to have both ways, so that you do not have to create a List in the very common case that you need to pass only one parameter.

Received wrong object calling originate action

We are trying to use this library to execute a test for 100 calls. When we execute the "Originate" action and wait for the response:

public Channel originate(..) throws RestException {
buildOriginate(...);
String json = httpActionSync();
return deserializeJson( json, Channel_impl_ari_1_9_0.class );
}

In the "json" string variable arrives a Playback object of another channel instead of a Channel object of the initialized channel through originate(), so in the deserializeJson method is generated a exception while trying to unmarshal the Json based on the Channel class structure:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "media_uri" (Class ch.loway.oss.ari4java.generated.ari_1_9_0.models.Channel_impl_ari_1_9_0)

Using enum for fixed-set options

In https://github.com/l3nz/ari4java/blob/master/codegen-data/ari_1_6_0/bridges.json
See e.g.

    "defaultValue": "none",
    "allowableValues": {
        "valueType": "LIST",
        "values": [
            "none",
            "any",
            "*",
            "#"
        ]
    }

Issues:

  • How do we get a meaningful, short Enum name
  • If the Enum is null, the parameter is not added
  • The Enum name could be not a valid Java name. For example, TerminateOn.none is valid (though t might be better uppercased) while TerminateOn.# is not (so we must rename it to TerminateOn.POUND)

FindBugs: Correctness

UwF Unwritten field: ch.loway.oss.ari4java.tools.BaseAriAction$AriAsyncHandler.klazzType

Better exception text on REST error

At the moment you get a stacktrace like:

ch.loway.oss.ari4java.tools.RestException: {
"error": "Authentication required"
}
at ch.loway.oss.ari4java.tools.http.NettyHttpClient.makeException(NettyHttpClient.java:264)

That's not really nice :)

Jackson lib performance

I've noticed quite big CPU usage from my java app when handling > 100 concurrent calls. Asterisk has 2-3 times lower CPU usage than my java application which is unacceptable. I've made CPU sampling with Java VisualVM tool and it gave me the reason: jackson library doesn't seem to be very fast! Check out my snapshots.

CPU usage results ('top' is command from Debian 8 I have used):

  1. 10 concurrent calls:
  • java app: Java VisualVM 2-15%
  • java app: 'top' 5-20%
  • asterisk: 'top' 3-5%
  1. 100 calls:

  • java app: Java VisualVM 50-70%
  • java app: 'top' 80-120%
  • asterisk: 'top' 20-30%

Please notice that 'top' shows bigger value than Java VisualVM probably because additional CPU usage from Java VisualVM itself (RMI communication), when I stop it, results are more similar to ones taken from Java VisualVM.

I was googling it and found one interesting site for comparing json libs in java: http://blog.takipi.com/the-ultimate-json-library-json-simple-vs-gson-vs-jackson-vs-json/

Jackson seems to be the best for big json-s, but not for small ones. Since, I believe, json size is quite small here, Jackson doesn't seem to be the best choice here.

snapshot-100-calls-1
snapshot-100-calls-2
snapshot-100-calls-3
snapshot-100-calls-4

Any opinion?

ARI 1.7.0 - Language Field Return in Channel using Asterisk 13.1 Certified

Getting the following exception when running the following code. Seems language is now a property returned in the ARI channel. I will see about editing the channels.json file to add the property and see if works.

Map<String, String> orVar = new HashMap<String, String>();
Channel chan = ari.channels().originate("SIP/" + message.get("origin"), "", "", new Long(1), "bridge-dial", "inbound", message.get("destination"), 30, orVar, "", "");

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "language" (class ch.loway.oss.ari4java.generated.ari_1_6_0.models.Channel_impl_ari_1_6_0), not marked as ignorable (8 known properties: , "state", "connected", "dialplan", "accountcode", "caller", "name", "id", "creationtime"]) at [Source: java.io.StringReader@1ac9004; line: 20, column: 16](through reference chain: ch.loway.oss.ari4java.generated.ari_1_6_0.models.Channel_impl_ari_1_6_0["language"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:79)
at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:555)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:708)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1160)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:315)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
at ch.loway.oss.ari4java.tools.BaseAriAction.deserializeJson(BaseAriAction.java:240)
at ch.loway.oss.ari4java.generated.ari_1_6_0.actions.ActionChannels_impl_ari_1_6_0.originate(ActionChannels_impl_ari_1_6_0.java:79)

netty exception when closing websocket

WebSocket Client received closing
5-gen-2014 17.32.38 io.netty.util.concurrent.DefaultPromise notifyListener0
AVVERTENZA: An exception was thrown by ch.loway.oss.ari4java.tools.http.NettyHttpClient$2$1.operationComplete()
java.lang.NullPointerException
at ch.loway.oss.ari4java.tools.http.NettyHttpClient.makeException(NettyHttpClient.java:260)
at ch.loway.oss.ari4java.tools.http.NettyHttpClient.access$000(NettyHttpClient.java:58)
at ch.loway.oss.ari4java.tools.http.NettyHttpClient$2$1.operationComplete(NettyHttpClient.java:315)
at ch.loway.oss.ari4java.tools.http.NettyHttpClient$2$1.operationComplete(NettyHttpClient.java:305)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:621)
at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:548)
at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:389)
at io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:82)
at io.netty.channel.AbstractChannel$CloseFuture.setClosed(AbstractChannel.java:827)
at io.netty.channel.AbstractChannel$AbstractUnsafe.close(AbstractChannel.java:543)
at io.netty.channel.nio.NioEventLoop.closeAll(NioEventLoop.java:550)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:356)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:662)

This only happens if you use getWebsocketQueue()

Encoding... what a mess.

I am noticing that across code we use many approaches to encoding UTF-8, all of them slightly wrong :-)

StandardCharsets.UTF_8
Charset.defaultCharset()
CharsetUtil.UTF_8
"UTF-8"

and as additional goodness (?):

 build/classes_subst/ch/loway/oss/ari4java/ARI.java:        
       final String UTF8 = "UTF-8";

My suggestion would be to:

  • Define a constant ENCODING in ARI.java that is a Charset and not a String.
  • use that constant everywhere (especially where we default to the default encoding!)

Now, should we go for StandardCharsets.UTF_8 or CharsetUtil.UTF_8? what are the pros and cons?

Automagical WS reconnections

Based on the comments in #43 - it would be cool to have an option to have ARI trying reconnections automatically, up to a limit (eg 10 seconds), as not to have to explicitly code for the odd glitch.
See @grahambrown11

Publish artifact

Hello, I'm really happy to see this project. It would be great if you would publish to a maven repository, such as Sonatype OSS or Bintray (a lot easier).
I may be able to help somewhat if needed.

Thanks.

ActionChannels

I was using actionChannel on multiple threads but was facing

io.netty.util.concurrent.BlockingOperationException: DefaultChannelPromise@55661481(incomplete)
        at io.netty.util.concurrent.DefaultPromise.checkDeadLock(DefaultPromise.java:390) ~[netty-all-4.0.25.Final.jar!/:4.0.25.Final]
        at io.netty.channel.DefaultChannelPromise.checkDeadLock(DefaultChannelPromise.java:157) ~[netty-all-4.0.25.Final.jar!/:4.0.25.Final]
        at io.netty.util.concurrent.DefaultPromise.await(DefaultPromise.java:251) ~[netty-all-4.0.25.Final.jar!/:4.0.25.Final]
        at io.netty.channel.DefaultChannelPromise.await(DefaultChannelPromise.java:129) ~[netty-all-4.0.25.Final.jar!/:4.0.25.Final]
        at io.netty.channel.DefaultChannelPromise.await(DefaultChannelPromise.java:28) ~[netty-all-4.0.25.Final.jar!/:4.0.25.Final]
        at io.netty.util.concurrent.DefaultPromise.sync(DefaultPromise.java:218) ~[netty-all-4.0.25.Final.jar!/:4.0.25.Final]
        at io.netty.channel.DefaultChannelPromise.sync(DefaultChannelPromise.java:117) ~[netty-all-4.0.25.Final.jar!/:4.0.25.Final]
        at io.netty.channel.DefaultChannelPromise.sync(DefaultChannelPromise.java:28) ~[netty-all-4.0.25.Final.jar!/:4.0.25.Final]
        at ch.loway.oss.ari4java.tools.http.NettyHttpClient.httpActionSync(NettyHttpClient.java:203) ~[ari4java-0.4.4.jar!/:0.4.4]

So what is the best way to use ActionChannel
1- Create one per thread
2- Create one for each request
3- Should i close the ActionChannel in case one is created for each request

ari4java does not URL encode or escape out double quotes in originate request

Hi,

I've found that when trying to send e164 as destination and cli in an originate request, these are not url encoded when sent in the ari request - so the '+' is treated as space by Asterisk.

Also, when sending a value in the body on the variables list, if the value has double quotes in it they are not escaped in the actual ari request.

Many thanks

Simple String-in-loop concatenation issue

I see that findbugs says:

Performance Warnings

Code    Warning
SBSC    ch.loway.oss.ari4java.tools.http.NettyHttpClient.buildRequest(String, String, List, List, List) concatenates strings using + in a loop
SBSC    ch.loway.oss.ari4java.tools.http.NettyHttpClient.getWsHandshake(String, List) concatenates strings using + in a loop

I thing that neither one is a "real" performance issue, but we should remove them for having a clean build.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.