/*
* Copyright 2014 Red Hat, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php
*
* You may elect to redistribute this code under either of these licenses.
*/
package io.vertx.test.core;
import io.vertx.core.*;
import io.vertx.core.impl.Deployment;
import io.vertx.core.impl.VertxInternal;
import io.vertx.core.json.JsonObject;
import io.vertx.core.spi.VerticleFactory;
import org.junit.Test;
import java.io.IOException;
/**
* @author <a href="http://tfox.org">Tim Fox</a>
*/
public class VerticleFactoryTest extends VertxTestBase {
public void setUp() throws Exception {
super.setUp();
// Unregister the factory that's loaded from the classpath
VerticleFactory factory = vertx.verticleFactories().iterator().next();
vertx.unregisterVerticleFactory(factory);
}
@Test
public void testRegister() {
assertTrue(vertx.verticleFactories().isEmpty());
VerticleFactory fact1 = new TestVerticleFactory("foo");
vertx.registerVerticleFactory(fact1);
assertEquals(1, vertx.verticleFactories().size());
assertTrue(vertx.verticleFactories().contains(fact1));
}
@Test
public void testUnregister() {
VerticleFactory fact1 = new TestVerticleFactory("foo");
vertx.registerVerticleFactory(fact1);
assertEquals(1, vertx.verticleFactories().size());
assertTrue(vertx.verticleFactories().contains(fact1));
vertx.unregisterVerticleFactory(fact1);
assertFalse(vertx.verticleFactories().contains(fact1));
assertTrue(vertx.verticleFactories().isEmpty());
}
@Test
public void testRegisterTwice() {
VerticleFactory fact1 = new TestVerticleFactory("foo");
vertx.registerVerticleFactory(fact1);
try {
vertx.registerVerticleFactory(fact1);
fail("Should throw exception");
} catch (IllegalArgumentException e) {
// OK
}
}
@Test
public void testUnregisterTwice() {
VerticleFactory fact1 = new TestVerticleFactory("foo");
vertx.registerVerticleFactory(fact1);
vertx.unregisterVerticleFactory(fact1);
try {
vertx.unregisterVerticleFactory(fact1);
fail("Should throw exception");
} catch (IllegalArgumentException e) {
// OK
}
}
@Test
public void testUnregisterNoFact() {
VerticleFactory fact1 = new TestVerticleFactory("foo");
try {
vertx.unregisterVerticleFactory(fact1);
fail("Should throw exception");
} catch (IllegalArgumentException e) {
// OK
}
}
@Test
public void testRegisterUnregisterTwo() {
VerticleFactory fact1 = new TestVerticleFactory("foo");
VerticleFactory fact2 = new TestVerticleFactory("bar");
vertx.registerVerticleFactory(fact1);
assertEquals(1, vertx.verticleFactories().size());
vertx.registerVerticleFactory(fact2);
assertEquals(2, vertx.verticleFactories().size());
assertTrue(vertx.verticleFactories().contains(fact1));
assertTrue(vertx.verticleFactories().contains(fact2));
vertx.unregisterVerticleFactory(fact1);
assertFalse(vertx.verticleFactories().contains(fact1));
assertEquals(1, vertx.verticleFactories().size());
assertTrue(vertx.verticleFactories().contains(fact2));
vertx.unregisterVerticleFactory(fact2);
assertTrue(vertx.verticleFactories().isEmpty());
assertFalse(vertx.verticleFactories().contains(fact1));
assertFalse(vertx.verticleFactories().contains(fact2));
}
@Test
public void testMatchWithPrefix() {
TestVerticle verticle1 = new TestVerticle();
TestVerticle verticle2 = new TestVerticle();
TestVerticle verticle3 = new TestVerticle();
TestVerticleFactory fact1 = new TestVerticleFactory("aa", verticle1);
TestVerticleFactory fact2 = new TestVerticleFactory("bb", verticle2);
TestVerticleFactory fact3 = new TestVerticleFactory("cc", verticle3);
vertx.registerVerticleFactory(fact1);
vertx.registerVerticleFactory(fact2);
vertx.registerVerticleFactory(fact3);
String name1 = "aa:myverticle1";
String name2 = "bb:myverticle2";
String name3 = "cc:myverticle3";
vertx.deployVerticle(name1, new DeploymentOptions(), ar -> {
assertTrue(ar.succeeded());
assertEquals(name1, fact1.identifier);
assertTrue(verticle1.startCalled);
assertFalse(verticle2.startCalled);
assertFalse(verticle3.startCalled);
assertNull(fact2.identifier);
assertNull(fact3.identifier);
vertx.deployVerticle(name2, new DeploymentOptions(), ar2 -> {
assertTrue(ar2.succeeded());
assertEquals(name2, fact2.identifier);
assertTrue(verticle2.startCalled);
assertFalse(verticle3.startCalled);
assertNull(fact3.identifier);
vertx.deployVerticle(name3, new DeploymentOptions(), ar3 -> {
assertTrue(ar3.succeeded());
assertEquals(name3, fact3.identifier);
assertTrue(verticle3.startCalled);
testComplete();
});
});
});
await();
}
@Test
public void testMatchWithSuffix() {
TestVerticle verticle1 = new TestVerticle();
TestVerticle verticle2 = new TestVerticle();
TestVerticle verticle3 = new TestVerticle();
TestVerticleFactory fact1 = new TestVerticleFactory("aa", verticle1);
TestVerticleFactory fact2 = new TestVerticleFactory("bb", verticle2);
TestVerticleFactory fact3 = new TestVerticleFactory("cc", verticle3);
vertx.registerVerticleFactory(fact1);
vertx.registerVerticleFactory(fact2);
vertx.registerVerticleFactory(fact3);
String name1 = "myverticle1.aa";
String name2 = "myverticle2.bb";
String name3 = "myverticle3.cc";
vertx.deployVerticle(name1, new DeploymentOptions(), ar -> {
assertTrue(ar.succeeded());
assertEquals(name1, fact1.identifier);
assertTrue(verticle1.startCalled);
assertFalse(verticle2.startCalled);
assertFalse(verticle3.startCalled);
assertNull(fact2.identifier);
assertNull(fact3.identifier);
vertx.deployVerticle(name2, new DeploymentOptions(), ar2 -> {
assertTrue(ar2.succeeded());
assertEquals(name2, fact2.identifier);
assertTrue(verticle2.startCalled);
assertFalse(verticle3.startCalled);
assertNull(fact3.identifier);
vertx.deployVerticle(name3, new DeploymentOptions(), ar3 -> {
assertTrue(ar3.succeeded());
assertEquals(name3, fact3.identifier);
assertTrue(verticle3.startCalled);
testComplete();
});
});
});
await();
}
@Test
public void testNoMatch() {
TestVerticle verticle1 = new TestVerticle();
TestVerticle verticle2 = new TestVerticle();
TestVerticleFactory fact1 = new TestVerticleFactory("aa", verticle1);
TestVerticleFactory fact2 = new TestVerticleFactory("bb", verticle2);
vertx.registerVerticleFactory(fact1);
vertx.registerVerticleFactory(fact2);
String name1 = "cc:myverticle1";
// If no match it will default to the simple Java verticle factory and then fail with ClassNotFoundException
vertx.deployVerticle(name1, new DeploymentOptions(), ar -> {
assertFalse(ar.succeeded());
assertFalse(verticle1.startCalled);
assertFalse(verticle2.startCalled);
assertTrue(ar.cause() instanceof ClassNotFoundException);
testComplete();
});
await();
}
@Test
public void testResolve() {
TestVerticle verticle = new TestVerticle();
TestVerticleFactory fact = new TestVerticleFactory("actual", verticle);
vertx.registerVerticleFactory(fact);
TestVerticleFactory factResolve = new TestVerticleFactory("resolve", "actual:myverticle");
vertx.registerVerticleFactory(factResolve);
JsonObject config = new JsonObject().put("foo", "bar");
DeploymentOptions original = new DeploymentOptions().setWorker(false).setConfig(config).setIsolationGroup("somegroup");
DeploymentOptions options = new DeploymentOptions(original);
vertx.deployVerticle("resolve:someid", options, res -> {
assertTrue(res.succeeded());
assertEquals("resolve:someid", factResolve.identifierToResolve);
assertEquals(options, factResolve.deploymentOptionsToResolve);
assertEquals("actual:myverticle", fact.identifier);
assertTrue(verticle.startCalled);
assertTrue(verticle.startCalled);
assertEquals(1, vertx.deploymentIDs().size());
Deployment dep = ((VertxInternal)vertx).getDeployment(res.result());
assertNotNull(dep);
assertFalse(original.equals(dep.deploymentOptions()));
assertFalse(dep.deploymentOptions().getConfig().containsKey("foo"));
assertEquals("quux", dep.deploymentOptions().getConfig().getString("wibble"));
assertTrue(dep.deploymentOptions().isWorker());
assertEquals("othergroup", dep.deploymentOptions().getIsolationGroup());
testComplete();
});
await();
}
@Test
public void testOrdering() {
TestVerticle verticle = new TestVerticle();
TestVerticleFactory fact2 = new TestVerticleFactory("aa", verticle, 2);
vertx.registerVerticleFactory(fact2);
TestVerticleFactory fact1 = new TestVerticleFactory("aa", verticle, 1);
vertx.registerVerticleFactory(fact1);
TestVerticleFactory fact3 = new TestVerticleFactory("aa", verticle, 3);
vertx.registerVerticleFactory(fact3);
vertx.deployVerticle("aa:someverticle", res -> {
assertTrue(res.succeeded());
assertEquals("aa:someverticle", fact1.identifier);
assertNull(fact2.identifier);
assertNull(fact3.identifier);
testComplete();
});
await();
}
@Test
public void testOrderingFailedInCreate() {
TestVerticle verticle = new TestVerticle();
TestVerticleFactory fact2 = new TestVerticleFactory("aa", verticle, 2);
vertx.registerVerticleFactory(fact2);
TestVerticleFactory fact1 = new TestVerticleFactory("aa", verticle, 1, true);
vertx.registerVerticleFactory(fact1);
TestVerticleFactory fact3 = new TestVerticleFactory("aa", verticle, 3);
vertx.registerVerticleFactory(fact3);
vertx.deployVerticle("aa:someverticle", res -> {
assertTrue(res.succeeded());
assertEquals("aa:someverticle", fact2.identifier);
assertNull(fact1.identifier);
assertNull(fact3.identifier);
testComplete();
});
await();
}
@Test
public void testOrderingFailedInCreate2() {
TestVerticle verticle = new TestVerticle();
TestVerticleFactory fact2 = new TestVerticleFactory("aa", verticle, 2, true);
vertx.registerVerticleFactory(fact2);
TestVerticleFactory fact1 = new TestVerticleFactory("aa", verticle, 1, true);
vertx.registerVerticleFactory(fact1);
TestVerticleFactory fact3 = new TestVerticleFactory("aa", verticle, 3);
vertx.registerVerticleFactory(fact3);
vertx.deployVerticle("aa:someverticle", res -> {
assertTrue(res.succeeded());
assertEquals("aa:someverticle", fact3.identifier);
assertNull(fact1.identifier);
assertNull(fact2.identifier);
testComplete();
});
await();
}
@Test
public void testOrderingFailedInCreateAll() {
TestVerticle verticle = new TestVerticle();
TestVerticleFactory fact2 = new TestVerticleFactory("aa", verticle, 2, true);
vertx.registerVerticleFactory(fact2);
TestVerticleFactory fact1 = new TestVerticleFactory("aa", verticle, 1, true);
vertx.registerVerticleFactory(fact1);
TestVerticleFactory fact3 = new TestVerticleFactory("aa", verticle, 3, true);
vertx.registerVerticleFactory(fact3);
vertx.deployVerticle("aa:someverticle", res -> {
assertFalse(res.succeeded());
assertTrue(res.cause() instanceof ClassNotFoundException);
assertNull(fact1.identifier);
assertNull(fact2.identifier);
assertNull(fact3.identifier);
testComplete();
});
await();
}
@Test
public void testOrderingFailedInResolve() {
TestVerticle verticle = new TestVerticle();
TestVerticleFactory factActual = new TestVerticleFactory("actual", verticle);
vertx.registerVerticleFactory(factActual);
TestVerticleFactory fact2 = new TestVerticleFactory("aa", "actual:someverticle", 2);
vertx.registerVerticleFactory(fact2);
TestVerticleFactory fact1 = new TestVerticleFactory("aa", "actual:someverticle", 1, true);
vertx.registerVerticleFactory(fact1);
TestVerticleFactory fact3 = new TestVerticleFactory("aa", "actual:someverticle", 3);
vertx.registerVerticleFactory(fact3);
vertx.deployVerticle("aa:blah", res -> {
assertTrue(res.succeeded());
assertNull(fact2.identifier);
assertNull(fact1.identifier);
assertNull(fact3.identifier);
assertEquals("aa:blah", fact2.identifierToResolve);
assertNull(fact1.identifierToResolve);
assertNull(fact3.identifierToResolve);
assertEquals("actual:someverticle", factActual.identifier);
testComplete();
});
await();
}
@Test
public void testOrderingFailedInResolve2() {
TestVerticle verticle = new TestVerticle();
TestVerticleFactory factActual = new TestVerticleFactory("actual", verticle);
vertx.registerVerticleFactory(factActual);
TestVerticleFactory fact2 = new TestVerticleFactory("aa", "actual:someverticle", 2, true);
vertx.registerVerticleFactory(fact2);
TestVerticleFactory fact1 = new TestVerticleFactory("aa", "actual:someverticle", 1, true);
vertx.registerVerticleFactory(fact1);
TestVerticleFactory fact3 = new TestVerticleFactory("aa", "actual:someverticle", 3);
vertx.registerVerticleFactory(fact3);
vertx.deployVerticle("aa:blah", res -> {
assertTrue(res.succeeded());
assertNull(fact2.identifier);
assertNull(fact1.identifier);
assertNull(fact3.identifier);
assertEquals("aa:blah", fact3.identifierToResolve);
assertNull(fact1.identifierToResolve);
assertNull(fact2.identifierToResolve);
assertEquals("actual:someverticle", factActual.identifier);
testComplete();
});
await();
}
@Test
public void testOrderingAllFailedInResolve() {
TestVerticle verticle = new TestVerticle();
TestVerticleFactory factActual = new TestVerticleFactory("actual", verticle);
vertx.registerVerticleFactory(factActual);
TestVerticleFactory fact2 = new TestVerticleFactory("aa", "actual:someverticle", 2, true);
vertx.registerVerticleFactory(fact2);
TestVerticleFactory fact1 = new TestVerticleFactory("aa", "actual:someverticle", 1, true);
vertx.registerVerticleFactory(fact1);
TestVerticleFactory fact3 = new TestVerticleFactory("aa", "actual:someverticle", 3, true);
vertx.registerVerticleFactory(fact3);
vertx.deployVerticle("aa:blah", res -> {
assertTrue(res.failed());
assertTrue(res.cause() instanceof IOException);
assertNull(fact2.identifier);
assertNull(fact1.identifier);
assertNull(fact3.identifier);
assertNull(fact3.identifierToResolve);
assertNull(fact1.identifierToResolve);
assertNull(fact2.identifierToResolve);
assertNull(factActual.identifier);
testComplete();
});
await();
}
@Test
public void testNotBlockingCreate() {
TestVerticle verticle1 = new TestVerticle();
TestVerticleFactory fact1 = new TestVerticleFactory("aa", verticle1);
vertx.registerVerticleFactory(fact1);
String name1 = "aa:myverticle1";
vertx.deployVerticle(name1, new DeploymentOptions(), ar -> {
assertTrue(ar.succeeded());
assertEquals(name1, fact1.identifier);
assertFalse(fact1.blockingCreate);
assertFalse(fact1.createWorkerThread);
testComplete();
});
await();
}
@Test
public void testBlockingCreate() {
TestVerticle verticle1 = new TestVerticle();
TestVerticleFactory fact1 = new TestVerticleFactory("aa", verticle1);
fact1.blockingCreate = true;
vertx.registerVerticleFactory(fact1);
String name1 = "aa:myverticle1";
vertx.deployVerticle(name1, new DeploymentOptions(), ar -> {
assertTrue(ar.succeeded());
assertEquals(name1, fact1.identifier);
assertTrue(fact1.blockingCreate);
assertTrue(fact1.createWorkerThread);
assertTrue(fact1.createContext.isEventLoopContext());
testComplete();
});
await();
}
@Test
public void testBlockingCreateFailureInCreate() {
TestVerticle verticle1 = new TestVerticle();
TestVerticleFactory fact1 = new TestVerticleFactory("aa", verticle1);
fact1.blockingCreate = true;
fact1.failInCreate = true;
vertx.registerVerticleFactory(fact1);
String name1 = "aa:myverticle1";
vertx.deployVerticle(name1, new DeploymentOptions(), ar -> {
assertFalse(ar.succeeded());
testComplete();
});
await();
}
@Test
public void testDeploymentOnClosedVertxWithCompletionHandler() {
TestVerticle verticle = new TestVerticle();
vertx.close(done -> {
vertx.deployVerticle(verticle, ar -> {
assertFalse(ar.succeeded());
testComplete();
});
});
await();
}
@Test
public void testDeploymentOnClosedVertxWithoutCompletionHandler() {
TestVerticle verticle = new TestVerticle();
vertx.close(done -> {
vertx.deployVerticle(verticle);
testComplete();
});
await();
}
class TestVerticleFactory implements VerticleFactory {
String prefix;
Verticle verticle;
String identifier;
String resolvedIdentifier;
String identifierToResolve;
DeploymentOptions deploymentOptionsToResolve;
int order;
boolean failInCreate;
boolean failInResolve;
Context createContext;
boolean createWorkerThread;
boolean blockingCreate;
TestVerticleFactory(String prefix) {
this.prefix = prefix;
}
TestVerticleFactory(String prefix, Verticle verticle) {
this.prefix = prefix;
this.verticle = verticle;
}
TestVerticleFactory(String prefix, String resolvedIdentifier) {
this.prefix = prefix;
this.resolvedIdentifier = resolvedIdentifier;
}
TestVerticleFactory(String prefix, Verticle verticle, int order) {
this.prefix = prefix;
this.verticle = verticle;
this.order = order;
}
TestVerticleFactory(String prefix, Verticle verticle, int order, boolean failInCreate) {
this.prefix = prefix;
this.verticle = verticle;
this.order = order;
this.failInCreate = failInCreate;
}
TestVerticleFactory(String prefix, String resolvedIdentifier, int order) {
this.prefix = prefix;
this.resolvedIdentifier = resolvedIdentifier;
this.order = order;
}
TestVerticleFactory(String prefix, String resolvedIdentifier, int order, boolean failInResolve) {
this.prefix = prefix;
this.resolvedIdentifier = resolvedIdentifier;
this.order = order;
this.failInResolve = failInResolve;
}
@Override
public int order() {
return order;
}
@Override
public boolean requiresResolve() {
return resolvedIdentifier != null;
}
@Override
public void resolve(String identifier, DeploymentOptions deploymentOptions, ClassLoader classLoader, Future<String> resolution) {
if (failInResolve) {
resolution.fail(new IOException("whatever"));
} else {
identifierToResolve = identifier;
deploymentOptionsToResolve = deploymentOptions;
// Now we change the deployment options
deploymentOptions.setConfig(new JsonObject().put("wibble", "quux"));
deploymentOptions.setWorker(true);
deploymentOptions.setIsolationGroup("othergroup");
resolution.complete(resolvedIdentifier);
}
}
@Override
public void init(Vertx vertx) {
}
@Override
public String prefix() {
return prefix;
}
@Override
public Verticle createVerticle(String verticleName, ClassLoader classLoader) throws Exception {
if (failInCreate) {
throw new ClassNotFoundException("whatever");
}
this.identifier = verticleName;
this.createContext = Vertx.currentContext();
this.createWorkerThread = Context.isOnWorkerThread();
return verticle;
}
@Override
public void close() {
}
@Override
public boolean blockingCreate() {
return blockingCreate;
}
}
class TestVerticle extends AbstractVerticle {
boolean startCalled;
@Override
public void start() throws Exception {
startCalled = true;
}
@Override
public void stop() throws Exception {
}
}
}