Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ private static void configurePlayer(HierarchicalConfiguration<ImmutableNode> src
}
dst.setPlayerCache(
cache.getBoolean("cacheEnabled", ResourcesConfiguration.PLAYER_CACHE_ENABLED),
cache.getInt("cacheSize", ResourcesConfiguration.PLAYER_CACHE_SIZE)
cache.getInt("cacheSize", ResourcesConfiguration.PLAYER_CACHE_SIZE),
cache.getString("urlPattern", null)
);

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
import org.restcomm.media.bootstrap.ioc.provider.AudioPlayerPoolProvider;
import org.restcomm.media.bootstrap.ioc.provider.AudioRecorderFactoryProvider;
import org.restcomm.media.bootstrap.ioc.provider.AudioRecorderPoolProvider;
import org.restcomm.media.bootstrap.ioc.provider.CachedRemoteStreamProvider;
import org.restcomm.media.bootstrap.ioc.provider.DirectRemoteStreamProvider;
import org.restcomm.media.bootstrap.ioc.provider.remotestream.CachedRemoteStreamProvider;
import org.restcomm.media.bootstrap.ioc.provider.remotestream.DirectRemoteStreamProvider;
import org.restcomm.media.bootstrap.ioc.provider.DtlsSrtpServerProviderProvider;
import org.restcomm.media.bootstrap.ioc.provider.DtmfDetectorFactoryProvider;
import org.restcomm.media.bootstrap.ioc.provider.DtmfDetectorPoolProvider;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.restcomm.media.bootstrap.ioc.provider.remotestream;

import org.apache.commons.lang3.StringUtils;
import org.restcomm.media.core.configuration.MediaServerConfiguration;

import com.google.inject.Inject;
import com.google.inject.Provider;
import org.restcomm.media.resource.player.audio.*;
import org.restcomm.media.resource.player.audio.DirectRemoteStreamProvider;

/**
* Created by achikin on 6/3/16.
*/
public class CachedRemoteStreamProvider implements Provider<org.restcomm.media.resource.player.audio.RemoteStreamProvider> {

private static org.restcomm.media.resource.player.audio.RemoteStreamProvider instance;

@Inject
public CachedRemoteStreamProvider(MediaServerConfiguration config) {
String pattern = config.getResourcesConfiguration().getPlayerCacheUrlPattern();
org.restcomm.media.resource.player.audio.RemoteStreamProvider cached = new org.restcomm.media.resource.player.audio.CachedRemoteStreamProvider(config.getResourcesConfiguration().getPlayerCacheSize());
if (StringUtils.isEmpty(pattern) || "*".equals(pattern) || ".*".equals(pattern)) {
instance = cached;
} else {
instance = new PatternRemoteStreamProvider(pattern, new DirectRemoteStreamProvider(), cached);
}
}

@Override
public org.restcomm.media.resource.player.audio.RemoteStreamProvider get() {
return instance;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.restcomm.media.bootstrap.ioc.provider;
package org.restcomm.media.bootstrap.ioc.provider.remotestream;

import com.google.inject.Provider;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ public void testLoadConfiguration() throws Exception {

Assert.assertEquals(100, resources.getPlayerCacheSize());
Assert.assertEquals(true, resources.getPlayerCacheEnabled());
Assert.assertEquals(".*", resources.getPlayerCacheUrlPattern());
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.restcomm.media.bootstrap.ioc;

import com.google.inject.Guice;
import com.google.inject.Injector;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.restcomm.media.core.configuration.MediaServerConfiguration;
import org.restcomm.media.resource.player.audio.RemoteStreamProvider;

/**
* Created by hamsterksu on 3/15/17.
*/
public class RemoteStreamProviderTest {

@Test
public void testWildcard1() {

String[] patterns = new String[]{null, "*", ".*"};
for (String pattern : patterns) {
final MediaServerConfiguration config = new MediaServerConfiguration();
config.getResourcesConfiguration().setPlayerCache(true, 100, pattern);
final Injector injector = Guice.createInjector(new MgcpModule(), new MediaModule(), new CoreModule(config));

RemoteStreamProvider obj = injector.getInstance(RemoteStreamProvider.class);

Assert.assertEquals(org.restcomm.media.resource.player.audio.CachedRemoteStreamProvider.class, obj.getClass());
}
}

@Test
public void testPattern() {
final MediaServerConfiguration config = new MediaServerConfiguration();
config.getResourcesConfiguration().setPlayerCache(true, 100, "http://.*/static/*");
final Injector injector = Guice.createInjector(new MgcpModule(), new MediaModule(), new CoreModule(config));

RemoteStreamProvider obj = injector.getInstance(RemoteStreamProvider.class);

Assert.assertEquals(org.restcomm.media.resource.player.audio.PatternRemoteStreamProvider.class, obj.getClass());
}

@Test
public void testDirect() {

final MediaServerConfiguration config = new MediaServerConfiguration();
//not the java pattern, but it's suitable for us
config.getResourcesConfiguration().setPlayerCache(false, 100, "*");
final Injector injector = Guice.createInjector(new MgcpModule(), new MediaModule(), new CoreModule(config));

RemoteStreamProvider obj = injector.getInstance(RemoteStreamProvider.class);

Assert.assertEquals(org.restcomm.media.resource.player.audio.DirectRemoteStreamProvider.class, obj.getClass());
}
}
1 change: 1 addition & 0 deletions bootstrap/src/test/resources/mediaserver.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
<cache>
<cacheSize>100</cacheSize>
<cacheEnabled>true</cacheEnabled>
<urlPattern>.*</urlPattern>
</cache>
</player>
<dtmfDetector dbi="-25" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class ResourcesConfiguration {
private int dtmfGeneratorToneVolume;
private int dtmfGeneratorToneDuration;
private int playerCacheSize;
private String playerCacheUrlPattern;

public ResourcesConfiguration() {
this.dtmfDetectorDbi = DTMF_DETECTOR_DBI;
Expand Down Expand Up @@ -79,7 +80,7 @@ public void setDtmfGeneratorToneDuration(int dtmfGeneratorToneDuration) {
this.dtmfGeneratorToneDuration = dtmfGeneratorToneDuration;
}

public void setPlayerCache(boolean playerCacheEnabled, int playerCacheSize) {
public void setPlayerCache(boolean playerCacheEnabled, int playerCacheSize, String urlPattern) {
if (!playerCacheEnabled) {
this.playerCacheSize = 0;
return;
Expand All @@ -88,6 +89,7 @@ public void setPlayerCache(boolean playerCacheEnabled, int playerCacheSize) {
throw new IllegalArgumentException("Player cache size cannot be negative");
}
this.playerCacheSize = playerCacheSize;
this.playerCacheUrlPattern = urlPattern;
}

public int getPlayerCacheSize() {
Expand All @@ -98,4 +100,7 @@ public boolean getPlayerCacheEnabled() {
return this.playerCacheSize != 0;
}

public String getPlayerCacheUrlPattern() {
return playerCacheUrlPattern;
}
}
2 changes: 1 addition & 1 deletion network/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.0.34.Final</version>
<version>4.1.9.Final</version>
</dependency>
</dependencies>

Expand Down
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
<module>core</module>
<module>client</module>
<module>controls</module>
<module>docs</module>
<!--<module>docs</module>-->
<module>bootstrap</module>
</modules>

Expand Down Expand Up @@ -167,7 +167,7 @@
<module>core</module>
<module>controls</module>
<module>client</module>
<module>docs</module>
<!--<module>docs</module>-->
<module>bootstrap</module>
</modules>
<build>
Expand Down Expand Up @@ -197,7 +197,7 @@
</execution>
</executions>
</plugin>
<plugin>
<!--<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.8.1</version>
Expand All @@ -210,7 +210,7 @@
</goals>
</execution>
</executions>
</plugin>
</plugin>-->
</plugins>
</build>
</profile>
Expand Down
12 changes: 7 additions & 5 deletions resources/mediaplayer/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,19 @@
<artifactId>mbrola</artifactId>
<version>${version.freetts}</version>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.6</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.netty/netty-buffer -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
<version>4.1.9.Final</version>
</dependency>

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package org.restcomm.media.resource.player.audio;

import java.io.ByteArrayInputStream;
import com.google.common.cache.*;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.Unpooled;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.MemoryUnit;
import org.ehcache.sizeof.annotations.IgnoreSizeOf;
import java.util.Map;
import java.util.concurrent.Callable;

/**
* Created by achikin on 5/9/16.
Expand All @@ -24,70 +20,46 @@ public class CachedRemoteStreamProvider implements RemoteStreamProvider {

private final static Logger log = Logger.getLogger(CachedRemoteStreamProvider.class);

private CacheManager cacheManager;

private ByteStreamCache.ISizeChangedListener sizeChangedListener;
private Cache<String, ByteBuf> cache;

public CachedRemoteStreamProvider(int size) {
log.info("Create AudioCache with size: " + size + "Mb");
cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
.withCache("preConfigured",
CacheConfigurationBuilder.newCacheConfigurationBuilder(URL.class, ByteStreamCache.class,
ResourcePoolsBuilder.newResourcePoolsBuilder().heap(size, MemoryUnit.MB))
.build())
.build(true);
sizeChangedListener = new ByteStreamCache.ISizeChangedListener() {
cache = CacheBuilder.newBuilder().maximumWeight(size * 1024L * 1024L).weigher(new Weigher<String, ByteBuf>() {
@Override
public void onSizeChanged(final URL uri, final ByteStreamCache self) {
log.debug("onSizeChanged for " + uri);
getCache().put(uri, self);
public int weigh(String s, ByteBuf byteBuf) {
return byteBuf.capacity();
}
};
}

private Cache<URL, ByteStreamCache> getCache() {
return cacheManager.getCache("preConfigured", URL.class, ByteStreamCache.class);
}

public InputStream getStream(URL uri) throws IOException {
Cache<URL, ByteStreamCache> cache = getCache();

ByteStreamCache stream = cache.get(uri);
if (stream == null) {
stream = new ByteStreamCache();
ByteStreamCache exists = cache.putIfAbsent(uri, stream);
if (exists != null) {
stream = exists;
}).removalListener(new RemovalListener<String, ByteBuf>() {
@Override
public void onRemoval(RemovalNotification<String, ByteBuf> removalNotification) {
ByteBuf buf = removalNotification.getValue();
if (buf != null) {
buf.release();
}
}
}
return new ByteArrayInputStream(stream.getBytes(uri, sizeChangedListener));
}).build();
}

private static class ByteStreamCache {

@IgnoreSizeOf
private Lock lock = new ReentrantLock();

private volatile byte[] bytes;

public byte[] getBytes(final URL uri, final ISizeChangedListener listener) throws IOException {
if (bytes == null) {
lock.lock();
try {
//need to check twice
if (bytes == null) {
bytes = IOUtils.toByteArray(uri.openStream());
listener.onSizeChanged(uri, this);
}
} finally {
lock.unlock();
public InputStream getStream(final URL uri) throws IOException {
final String key = uri.toString();
try {
ByteBuf buf = cache.get(key, new Callable<ByteBuf>() {
@Override
public ByteBuf call() throws Exception {
byte[] bytes = IOUtils.toByteArray(uri.openStream());
return Unpooled.directBuffer(bytes.length).writeBytes(bytes);
}
}
return bytes;
});
return new ByteBufInputStream(buf.retainedDuplicate(), true);
} catch (Throwable e) {
throw new IOException(e);
}
}

interface ISizeChangedListener {
void onSizeChanged(URL uri, ByteStreamCache self);
public void dump() {
log.info("--- Cache dump ---");
for (Map.Entry<String, ByteBuf> e : cache.asMap().entrySet()) {
log.info(e.getKey() + "; " + e.getValue().refCnt());
}
}
}
Loading