Skip to content

Commit

Permalink
Merge pull request #73 from wisdom-framework/encoding-implem
Browse files Browse the repository at this point in the history
First steps to add encoding capability to outbound traffic
  • Loading branch information
cescoffier committed Feb 28, 2014
2 parents 301a993 + 45447e0 commit d28e7c0
Show file tree
Hide file tree
Showing 31 changed files with 1,560 additions and 83 deletions.
14 changes: 9 additions & 5 deletions akka-system/src/main/java/org/wisdom/akka/AkkaSystemService.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package org.wisdom.akka;

import akka.actor.ActorSystem;
import java.io.InputStream;
import java.util.concurrent.Callable;

import org.wisdom.api.http.Context;
import org.wisdom.api.http.Result;

import scala.concurrent.ExecutionContext;
import scala.concurrent.Future;

import java.util.concurrent.Callable;
import akka.actor.ActorSystem;

/**
* A service to access the wisdom actor system and ease the dispatching of task.
Expand All @@ -24,15 +26,17 @@ public interface AkkaSystemService {
* @param context the context
* @return the future
*/
Future<Result> dispatch(Callable<Result> callable, Context context);
Future<Result> dispatchResultWithContext(Callable<Result> callable, Context context);

/**
* Dispatches the given task using an execution context preserving the current HTTP Context and the thread context
* classloader.
* @param callable the classloader
* @return the future
*/
Future<Result> dispatch(Callable<Result> callable);
Future<Result> dispatchResult(Callable<Result> callable);

Future<InputStream> dispatchInputStream(Callable<InputStream> callable);

/**
* Dispatches the given task. The task is executed using the given execution context.
Expand Down
29 changes: 22 additions & 7 deletions akka-system/src/main/java/org/wisdom/akka/impl/AkkaBootstrap.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
package org.wisdom.akka.impl;

import akka.actor.ActorSystem;
import akka.osgi.OsgiActorSystemFactory;
import com.typesafe.config.ConfigFactory;
import org.apache.felix.ipojo.annotations.*;
import java.io.InputStream;
import java.util.concurrent.Callable;

import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Instantiate;
import org.apache.felix.ipojo.annotations.Invalidate;
import org.apache.felix.ipojo.annotations.Provides;
import org.apache.felix.ipojo.annotations.Validate;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.wisdom.akka.AkkaSystemService;
import org.wisdom.api.http.Context;
import org.wisdom.api.http.Result;

import scala.concurrent.ExecutionContext;
import scala.concurrent.Future;
import akka.actor.ActorSystem;
import akka.osgi.OsgiActorSystemFactory;

import java.util.concurrent.Callable;
import com.typesafe.config.ConfigFactory;

@Component
@Provides
Expand Down Expand Up @@ -56,13 +63,21 @@ public ActorSystem system() {
}

@Override
public Future<Result> dispatch(Callable<Result> callable, Context context) {
public Future<Result> dispatchResultWithContext(Callable<Result> callable, Context context) {
return akka.dispatch.Futures.future(callable,
new HttpExecutionContext(system.dispatcher(), context, Thread.currentThread().getContextClassLoader()));
}

@Override
public Future<Result> dispatch(Callable<Result> callable) {
public Future<Result> dispatchResult(Callable<Result> callable) {
return akka.dispatch.Futures.future(callable,
new HttpExecutionContext(system.dispatcher(), Context.CONTEXT.get(),
Thread.currentThread().getContextClassLoader
()));
}

@Override
public Future<InputStream> dispatchInputStream(Callable<InputStream> callable) {
return akka.dispatch.Futures.future(callable,
new HttpExecutionContext(system.dispatcher(), Context.CONTEXT.get(),
Thread.currentThread().getContextClassLoader
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
package org.wisdom.configuration;

import org.apache.commons.configuration.ConfigurationConverter;
import java.io.File;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.MapConfiguration;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Instantiate;
import org.apache.felix.ipojo.annotations.Provides;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wisdom.api.configuration.Configuration;

import java.io.File;
import java.util.*;

/**
* Implementation of the configuration service reading application/conf and an external (optional) property.
Expand All @@ -24,9 +20,6 @@ public class ApplicationConfigurationImpl extends ConfigurationImpl implements o
.ApplicationConfiguration {

public static final String APPLICATION_CONFIGURATION = "application.configuration";
static final String ERROR_KEYNOTFOUND = "Key %s does not exist. Please include it in your application.conf. " +
"Otherwise this application will not work";
static final String ERROR_NOSUCHKEY = "No such key \"";
private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationConfigurationImpl.class);
private final Mode mode;
private final File baseDirectory;
Expand Down Expand Up @@ -145,6 +138,20 @@ public Boolean getBoolean(String key) {
}
return r;
}

/**
* @param key the key
* @return the property or null if not there or property no Long
*/
@Override
public Long getLong(String key) {
Long r = super.getLong(key);
if (r == null) {
LOGGER.error(ERROR_NOSUCHKEY + key + "\"");
return null;
}
return r;
}

/**
* Whether we are in dev mode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
* Unlike the main application configuration, this implementation does not used a logger.
*/
public class ConfigurationImpl implements Configuration {

private static final String ERROR_KEYNOTFOUND = "Key %s does not exist. Please include it in your application.conf. " +
"Otherwise this application will not work";
protected static final String ERROR_NOSUCHKEY = "No such key \"";

private org.apache.commons.configuration.Configuration configuration;

Expand Down Expand Up @@ -137,6 +141,39 @@ public Boolean getBooleanWithDefault(String key, Boolean defaultValue) {
return configuration.getBoolean(key, defaultValue);
}
}

@Override
public Long getLong(String key) {
Long v = Long.getLong(key);
if (v == null) {
try {
return configuration.getLong(key);
} catch (NoSuchElementException e) { //NOSONAR
return null;
}
} else {
return v;
}
}

@Override
public Long getLongWithDefault(String key, Long defaultValue) {
Long value = Long.getLong(key);
if (value == null) {
return configuration.getLong(key, defaultValue);
}
return value;
}

@Override
public Long getLongOrDie(String key) {
Long value = Long.getLong(key);
if (value == null) {
throw new IllegalArgumentException(String.format(ERROR_KEYNOTFOUND, key));
} else {
return value;
}
}

/**
* The "die" method forces this key to be set. Otherwise a runtime exception
Expand All @@ -150,7 +187,7 @@ public Boolean getBooleanOrDie(String key) {
Boolean value = getBoolean(key);

if (value == null) {
throw new IllegalArgumentException(String.format(ApplicationConfigurationImpl.ERROR_KEYNOTFOUND, key));
throw new IllegalArgumentException(String.format(ERROR_KEYNOTFOUND, key));
} else {
return value;
}
Expand All @@ -168,7 +205,7 @@ public Integer getIntegerOrDie(String key) {
Integer value = getInteger(key);

if (value == null) {
throw new IllegalArgumentException(String.format(ApplicationConfigurationImpl.ERROR_KEYNOTFOUND, key));
throw new IllegalArgumentException(String.format(ERROR_KEYNOTFOUND, key));
} else {
return value;
}
Expand All @@ -186,7 +223,7 @@ public String getOrDie(String key) {
String value = get(key);

if (value == null) {
throw new IllegalArgumentException(String.format(ApplicationConfigurationImpl.ERROR_KEYNOTFOUND, key));
throw new IllegalArgumentException(String.format(ERROR_KEYNOTFOUND, key));
} else {
return value;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package org.wisdom.configuration;

import org.junit.After;
import org.junit.Test;
import org.wisdom.api.configuration.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;

import java.io.File;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import org.junit.After;
import org.junit.Test;
import org.wisdom.api.configuration.ApplicationConfiguration;
import org.wisdom.api.configuration.Configuration;

/**
* Check the configuration management behavior.
Expand Down Expand Up @@ -84,6 +85,16 @@ public void testGetInteger() {
assertThat(configuration.getIntegerWithDefault("key.int.no", 2)).isEqualTo(2);
assertThat(configuration.get("key.int")).isEqualTo("1");
}

@Test
public void testGetLong() {
System.setProperty(ApplicationConfigurationImpl.APPLICATION_CONFIGURATION, "target/test-classes/conf/regular.conf");
ApplicationConfiguration configuration = new ApplicationConfigurationImpl();
assertThat(configuration).isNotNull();
assertThat(configuration.getLong("key.long")).isEqualTo(9999999999999L);
assertThat(configuration.getLongWithDefault("key.long", 2L)).isEqualTo(9999999999999L);
assertThat(configuration.getLongWithDefault("key.long.no", 2L)).isEqualTo(2L);
}

@Test
public void testGetBoolean() {
Expand Down Expand Up @@ -198,7 +209,7 @@ public void testEmptySubConfigurations() {

@Test
public void testAllAndProperties() {
final int numberOfPropertiesStartingWithKey = 8;
final int numberOfPropertiesStartingWithKey = 9;
System.setProperty(ApplicationConfigurationImpl.APPLICATION_CONFIGURATION, "target/test-classes/conf/regular.conf");
ApplicationConfigurationImpl configuration = new ApplicationConfigurationImpl();
assertThat(configuration).isNotNull();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ key.array = a,b,c

other.conf = a_file.txt

key.long = 9999999999999

5 changes: 5 additions & 0 deletions content-manager/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
<artifactId>wisdom-api</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
</dependency>

<dependency>
<groupId>org.apache.felix</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package org.wisdom.content.codecs;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.InflaterInputStream;

import org.apache.commons.io.IOUtils;
import org.wisdom.api.content.ContentCodec;

/**
* Abstract codec using an {@link DeflaterOutputStream} instance to encode and {@link InflaterInputStream} instance to decode.
* Subclasses of this two classes can also be used, for instance ({@link GZIPOutputStream and {@link GZIPInputStream}}
* <br/>
* Subclasses should implements {@link #getEncoderClass} and {@link #getDecoderClass} to return the chosen encoder classes.
* <br/>
* @see ContentCodec
*/
public abstract class AbstractDefInfCodec implements ContentCodec {

@Override
public InputStream encode(InputStream toEncode) throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();

OutputStream encoderout;
try {
encoderout = getEncoderClass().getConstructor(OutputStream.class).newInstance(bout);
encoderout.write(IOUtils.toByteArray(toEncode));
encoderout.flush();
encoderout.close();
}
catch (InstantiationException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
e.printStackTrace();
//TODO notify encoding has not been done
return toEncode;
}

toEncode.close();

bout.flush();
InputStream encoded = new ByteArrayInputStream(bout.toByteArray());
bout.close();
return encoded;
}

@Override
public InputStream decode(InputStream toDecode) throws IOException {
InputStream decoderin;
try {
decoderin = getDecoderClass().getConstructor(InputStream.class).newInstance(toDecode);
} catch (InstantiationException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
e.printStackTrace();
//TODO notify encoding has not been done
return toDecode;
}
return decoderin;
}

@Override
public abstract String getEncodingType();

@Override
public abstract String getContentEncodingHeaderValue();

/**
* @return Encoder class the codec use to encode data
*/
public abstract Class<? extends DeflaterOutputStream> getEncoderClass();

/**
* @return Decoder class the codec use to decode data
*/
public abstract Class<? extends InflaterInputStream> getDecoderClass();
}
Loading

0 comments on commit d28e7c0

Please sign in to comment.