/* * Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jboss.errai.cdi.event.client.test; import org.jboss.errai.bus.client.ErraiBus; import org.jboss.errai.bus.client.api.base.MessageBuilder; import org.jboss.errai.bus.client.api.builder.MessageBuildParms; import org.jboss.errai.bus.client.api.builder.MessageBuildSendableWithReply; import org.jboss.errai.bus.client.api.messaging.Message; import org.jboss.errai.bus.client.api.messaging.MessageBus; import org.jboss.errai.bus.client.api.messaging.MessageCallback; import org.jboss.errai.bus.common.AbstractErraiTest; import org.jboss.errai.common.client.api.ErrorCallback; import org.jboss.errai.common.client.protocols.MessageParts; import com.google.gwt.user.client.Timer; /** * Test that annotated services (types or methods) are properly scanned and subscribed by * CDIExtensionPoints. * * @author mbarkley <mbarkley@redhat.com> */ public class CDIServiceAnnotationTests extends AbstractErraiTest { MessageBus bus = ErraiBus.get(); private boolean received; private Message receivedMessage; private Timer timer; public final static String REPLY_TO_BASE = "AnnotationTester"; public static String REPLY_TO; private static Integer counter = 0; private final int POLL = 100; private final int TIMEOUT = 10000; @Override public String getModuleName() { return "org.jboss.errai.cdi.event.ServiceAnnotationTestModule"; } @Override protected void gwtSetUp() throws Exception { super.gwtSetUp(); // Do this to enhance independence of tests REPLY_TO = REPLY_TO_BASE + ++counter; bus.subscribe(REPLY_TO, new MessageCallback() { @Override public void callback(Message message) { received = true; receivedMessage = message; } }); } @Override protected void gwtTearDown() throws Exception { timer.cancel(); super.gwtTearDown(); bus.unsubscribeAll(REPLY_TO); received = false; receivedMessage = null; } public void testClassWithServiceMethod() throws Exception { runServiceTest("serviceMethod", null, null); } public void testClassWithService() throws Exception { runServiceTest("ClassWithService", null, null); } public void testClassWithMultipleServices() throws Exception { runServiceTestAndThen("service1", null, null, new Runnable() { @Override public void run() { runServiceTest("service2", null, null); } }); } public void testClassWithCommandMethod() throws Exception { runServiceTest("ClassWithCommandMethod", "command", null); } public void testNamedClassWithService() throws Exception { runServiceTest("ANamedClassService", null, null); } public void testClassWithNamedServiceMethod() throws Exception { runServiceTest("ANamedServiceMethod", null, null); } public void testClassWithNamedCommandMethod() throws Exception { runServiceTest("ClassWithNamedCommandMethod", "ANamedCommandMethod", null); } public void testClassWithServiceAndCommandMethod() throws Exception { runServiceTest("ClassWithServiceAndCommandMethod", "serviceAndCommandMethod", null); } /** * Test that type service works with inner method service. */ public void testClassWithServiceAndMethodWithService1() throws Exception { runServiceTest("ClassWithServiceAndMethodWithService", null, null); } /** * Test that method service works with enclosing type service. */ public void testClassWithServiceAndMethodWithService2() throws Exception { runServiceTest("methodWithService", null, null); } /** * Check that a method with a service and command annotation works if it is enclosed in a service * type. */ public void testClassWithServiceAndMethodWithServiceAndCommand1() throws Exception { runServiceTest("TheMethodsService", "command", null); } /** * Check that a type service will ignores @Command method annotations if that method also is a * service. */ public void testClassWithServiceAndMethodWithServiceAndCommand2() throws Exception { runServiceTestAndThen("ClassWithServiceAndMethodWithServiceAndCommand", "command", null, new Runnable() { @Override public void run() { if ("callback".equals(receivedMessage.getValue(String.class))) { finishTest(); } else { fail("The callback should have received this message"); } } }); } /** * Test that local class service does not receive message from client. */ public void testClassWithLocalService1() throws Exception { runNonRespondingServiceTest("ClassWithLocalService"); } /** * Test that local class service does receive message relayed through server. */ public void testClassWithLocalService2() throws Exception { runServiceTest("LocalCDIAnnotationRouterService", null, "ClassWithLocalService"); } /** * Test that local method service does not receive message from client. */ public void testMethodWithLocalService1() throws Exception { runNonRespondingServiceTest("localMethodService"); } /** * Test that local method service does receive message relayed through server. */ public void testMethodWithLocalService2() throws Exception { runServiceTest("LocalCDIAnnotationRouterService", null, "localMethodService"); } private void runNonRespondingServiceTest(String subject) { delayTestFinish(TIMEOUT + 2 * POLL); final long start = System.currentTimeMillis(); MessageBuilder.createMessage(subject).signalling().with(MessageParts.ReplyTo, REPLY_TO) .errorsHandledBy(new ErrorCallback<Message>() { @Override public boolean error(Message message, Throwable throwable) { throw new RuntimeException("error occurred with message: " + throwable.getMessage(), throwable); } }).sendNowWith(bus); timer = new Timer() { @Override public void run() { if (System.currentTimeMillis() - start > TIMEOUT && !received) { cancel(); finishTest(); } else if (received) { cancel(); System.out.println(receivedMessage); System.out.println(counter); fail("Message should not have been received!"); } } }; timer.scheduleRepeating(POLL); } private void runServiceTest(final String subject, String command, String value) { runServiceTestAndThen(subject, command, value, new Runnable() { @Override public void run() { finishTest(); } }); } private void runServiceTestAndThen(final String subject, String command, String value, final Runnable finish) { delayTestFinish(TIMEOUT + 2 * POLL); final long start = System.currentTimeMillis(); MessageBuildParms<MessageBuildSendableWithReply> message; if (command != null) { message = MessageBuilder.createMessage(subject).command(command); } else message = MessageBuilder.createMessage(subject).signalling(); if (value != null) message = message.withValue(value); message.with(MessageParts.ReplyTo, REPLY_TO).errorsHandledBy(new ErrorCallback<Message>() { @Override public boolean error(Message message, Throwable throwable) { throw new RuntimeException("error occurred with message: " + throwable.getMessage(), throwable); } }).sendNowWith(bus); timer = new Timer() { @Override public void run() { if (System.currentTimeMillis() - start > TIMEOUT && !received) { cancel(); fail("No response received after " + (System.currentTimeMillis() - start) + " ms"); } else if (received) { cancel(); System.out.println(receivedMessage); System.out.println(counter); finish.run(); } } }; timer.scheduleRepeating(POLL); } }