Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Easier disposable management #15

Closed
wants to merge 5 commits into from
Closed
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
5 changes: 5 additions & 0 deletions src/main/java/com/redhat/vertx/Engine.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.reactivex.core.AbstractVerticle;
import io.vertx.reactivex.core.Vertx;
import io.vertx.reactivex.core.eventbus.EventBus;
import io.vertx.reactivex.core.eventbus.MessageConsumer;

Expand Down Expand Up @@ -46,6 +47,10 @@ public EventBus getEventBus() {
return vertx.eventBus();
}

public Vertx getVertRx() {
return vertx;
}

@Override
public Completable rxStart() {

Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/redhat/vertx/pipeline/AbstractStep.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,8 @@ protected Maybe<Object> executeSlow(JsonObject env) {
return Maybe.error(e);
}
}

void addDisposable(JsonObject env, Disposable disposable) {
super.addDisposable(env.getJsonObject("doc").getString(Engine.DOC_UUID), disposable);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ public abstract class DocBasedDisposableManager implements Step {
private Map<String, Collection<Disposable>> disposables = new HashMap<>();


public void addDisposable(String uuid, Disposable disposable) {
protected void addDisposable(String uuid, Disposable disposable) {
this.addDisposable(uuid,Arrays.asList(disposable));
}

public void addDisposable(String uuid, Collection disposables) {
protected void addDisposable(String uuid, Collection disposables) {
Collection d = this.disposables.getOrDefault(uuid,new ArrayList<>());
this.disposables.put(uuid,d);
d.addAll(disposables);
Expand Down
24 changes: 15 additions & 9 deletions src/main/java/io/burt/jmespath/vertx/VertxRuntime.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,22 @@ public String toString(Object value) {
*/
@Override
public boolean isTruthy(Object value) {
if (value instanceof Boolean) {
return (Boolean)value;
} else if (value instanceof JsonArray) {
return ((JsonArray)value).size() > 0;
} else if (value instanceof JsonObject) {
return ((JsonObject)value).size() > 0;
} else if (value instanceof String) {
return ((String)value).length() > 0;
switch (typeOf(value)) {
case BOOLEAN:
return (Boolean)value;
case ARRAY:
return ((JsonArray)value).size() > 0;
case OBJECT:
return ((JsonObject)value).size() > 0;
case STRING:
return ((String)value).length() > 0;
case NULL:
return false;
case NUMBER:
return true;
default:
throw new IllegalStateException();
}
return value != null;
}

@Override
Expand Down
217 changes: 215 additions & 2 deletions src/test/java/io/burt/jmespath/vertx/VertxTest.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,225 @@
package io.burt.jmespath.vertx;

import io.vertx.core.json.JsonObject;

import io.burt.jmespath.JmesPathRuntimeTest;
import io.burt.jmespath.JmesPathType;
import io.burt.jmespath.RuntimeConfiguration;
import io.burt.jmespath.Adapter;
import org.assertj.core.api.AbstractIntegerAssert;
import org.junit.Test;

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.*;

import static io.burt.jmespath.JmesPathType.*;
import static org.assertj.core.api.Assertions.assertThat;

public class VertxTest extends JmesPathRuntimeTest<Object> {
@Override
protected Adapter<Object> createRuntime(RuntimeConfiguration configuration) { return new VertxRuntime(configuration); }

@Test
public void testLists() throws NoSuchAlgorithmException {
byte[] bytes = new byte[20];
SecureRandom.getInstanceStrong().nextBytes(bytes);
String bytesString = Base64.getEncoder().encodeToString(bytes);

var map = new HashMap<String, Object>();
map.put("text","hi");

var backingArr = Arrays.asList(
1L, // 0
1f, // 1
1, // 2
1.2, // 3
bytesString, // 4
"", // 5
true, // 6
Arrays.asList(new Object[]{"hi"}), // 7
map, // 8
null, // 9
false // 10
);

var runtime = createRuntime(RuntimeConfiguration.defaultConfiguration());
var converted = runtime.createArray(backingArr);
var newList = runtime.toList(converted);

assertThat(newList).isNotEqualTo(backingArr);
assertThat(newList.get(0)).isEqualTo(1L);
assertThat(newList.get(1)).isEqualTo(1f);
assertThat(newList.get(2)).isEqualTo(1);
assertThat(newList.get(3)).isEqualTo(1.2);
assertThat(newList.get(4)).isEqualTo(backingArr.get(4));
assertThat(newList.get(5)).isEqualTo("");
assertThat(newList.get(6)).isEqualTo(true);
assertThat(runtime.toList(newList.get(7))).isEqualTo(backingArr.get(7));
assertThat(parseObject(runtime,(newList.get(8)))).isEqualTo(backingArr.get(8));
assertThat(newList.get(9)).isNull();
assertThat(newList.get(10)).isEqualTo(Boolean.FALSE);

var backingIt = backingArr.iterator();
var newIt = newList.iterator();
for (var i=0;i<newList.size();i++) {
var expected = backingIt.next();
var actual = fromAdapted(runtime,newIt.next());
assertThat(fromAdapted(runtime, actual)).isEqualTo(expected);
}
}

@Test
public void testTruthy() {
var list = Arrays.asList(false);
var map = new HashMap<String, Object>();
map.put("text","hi");

var rt = createRuntime(RuntimeConfiguration.defaultConfiguration());
Arrays.asList(true,1,0l,1.1d,"yellow","false","null",map,list).stream().map(x -> toAdapted(rt,x))
.iterator().forEachRemaining(x-> assertThat(rt.isTruthy(x)).isTrue());
Arrays.asList(false,"",null,Collections.emptyList(),Collections.emptyMap()).stream().map(x -> toAdapted(rt,x))
.iterator().forEachRemaining(x-> assertThat(rt.isTruthy(x)).isFalse());

try {
rt.isTruthy(this);
assertThat(false).isTrue();
} catch (IllegalStateException e) {
// expected
}

}

@Test
public void testTypeOf() {
var rt = createRuntime(RuntimeConfiguration.defaultConfiguration());
checkTypeOf(rt, 1,NUMBER);
checkTypeOf(rt, 1l,NUMBER);
checkTypeOf(rt, 1.1d,NUMBER);
checkTypeOf(rt, 1.1f,NUMBER);
checkTypeOf(rt, false,BOOLEAN);
checkTypeOf(rt, true,BOOLEAN);
checkTypeOf(rt, "lorem",STRING);
checkTypeOf(rt, 1,NUMBER);
checkTypeOf(rt, Arrays.asList(1,2,3),ARRAY);
checkTypeOf(rt, Collections.emptyMap(), OBJECT);

try {
rt.typeOf(this);
assertThat(false).isTrue();
} catch (IllegalStateException e) {
// expected
}
}

@Test
public void testCompare() {
var rt = createRuntime(RuntimeConfiguration.defaultConfiguration());
compare(rt, "foo", "foo").isEqualTo(0);
compare(rt, "a", "b").isEqualTo("a".compareTo("b"));
compare(rt, "b", "a").isEqualTo("b".compareTo("a"));

compare(rt, 1, 1).isEqualTo(0);
compare(rt, 1, 2).isEqualTo(Integer.valueOf(1).compareTo(2));
compare(rt, 2, 1).isEqualTo(Integer.valueOf(2).compareTo(1));

compare(rt, 1.1d, 1.1d).isEqualTo(0);
compare(rt, 1.1d, 2.1d).isEqualTo(Double.valueOf(1.1d).compareTo(2.1d));
compare(rt, 2.1d, 1.1d).isEqualTo(Double.valueOf(2.1d).compareTo(1.1d));

compare(rt, 1l, 2.1d).isEqualTo(Double.valueOf(1l).compareTo(2.1d));

compare(rt, null, null).isEqualTo(0);

compare(rt, true, true).isEqualTo(0);
compare(rt, false, true).isEqualTo(-1);
compare(rt, true, false).isEqualTo(-1);

var array1 = Arrays.asList("a","b","c");
var array2 = Arrays.asList("do","re","mi");
compare(rt, array1, array1).isEqualTo(0);
compare(rt, array1, array2).isEqualTo(-1);
compare(rt, Collections.emptyList(), Collections.emptyList()).isEqualTo(0);
compare(rt, array1, Collections.emptyList()).isEqualTo(-1);
compare(rt, Collections.emptyList(), array1).isEqualTo(-1);


var map1 = new HashMap<String,Object>();
map1.put("lorem","ipsum");
var map2 = new HashMap<String,Object>();
map2.put("dolor","st");
compare(rt, map1, map1).isEqualTo(0);
compare(rt, map1, map2).isEqualTo(-1);
compare(rt, Collections.emptyMap(), Collections.emptyMap()).isEqualTo(0);
compare(rt, map1, Collections.emptyMap()).isEqualTo(-1);
compare(rt, Collections.emptyMap(), map1).isEqualTo(-1);

compare(rt, 1, map1).isEqualTo(-1);
compare(rt, "foo", 1).isEqualTo(-1);
compare(rt, 1, true).isEqualTo(-1);
compare(rt, 0, false).isEqualTo(-1);
compare(rt,"foo", array1).isEqualTo(-1);
compare(rt, null, false).isEqualTo(-1);
}

private AbstractIntegerAssert compare(Adapter<Object> rt, Object a, Object b) {
return assertThat(rt.compare(toAdapted(rt,a),toAdapted(rt,b)));
}

private void checkTypeOf(Adapter<Object> runtime, Object baseObj, JmesPathType type) {
Object convertedObj = toAdapted(runtime,baseObj);
assertThat(runtime.typeOf(convertedObj)).isEqualTo(type);
}


private Object toAdapted(Adapter<Object> runtime, Object object) {
if (object == null) {
return runtime.createNull();
} else if (object instanceof Boolean) {
return runtime.createBoolean((Boolean)object);
} else if (object instanceof Number) {
if (object instanceof Double || object instanceof Float) {
return runtime.createNumber(((Number)object).doubleValue());
} else {
return runtime.createNumber(((Number) object).longValue());
}
} else if (object instanceof Map) {
return runtime.createObject((Map<Object,Object>)object);
} else if (object instanceof Collection) {
return runtime.createArray((Collection)object);
} else if (object instanceof String) {
return runtime.createString((String)object);
} else {
throw new IllegalStateException(String.format("Unknown node type encountered: %s", object.getClass().getName()));
}
}

private Object fromAdapted(Adapter<Object> runtime, Object object) {
try {
switch (runtime.typeOf(object)) {
case ARRAY:
return runtime.toList(object);
case BOOLEAN:
return runtime.isTruthy(object);
case NULL:
return null;
case NUMBER:
return runtime.toNumber(object);
case OBJECT:
return parseObject(runtime, object);
case STRING:
return runtime.toString(object);
default:
throw new IllegalArgumentException();
}
} catch (IllegalStateException e ) {
// already unboxed
return object;
}
}

private Map<String,Object> parseObject(Adapter<Object> runtime, Object obj) {
var map = new HashMap<String,Object>();
runtime.getPropertyNames(obj).iterator().forEachRemaining(p -> map.put((String)p,runtime.getProperty(obj,p)));
return Collections.unmodifiableMap(map);
}

}