blob: 1f771ea4cebc2377a245e5aaf90f9e9212030bc0 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.tuscany.sca.itest.oneway;
import java.io.File;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import junit.framework.Assert;
import org.apache.tuscany.sca.core.invocation.NonBlockingInterceptor;
import org.apache.tuscany.sca.itest.oneway.impl.OneWayClientImpl;
import org.apache.tuscany.sca.itest.oneway.impl.OneWayServiceImpl;
import org.apache.tuscany.sca.node.Contribution;
import org.apache.tuscany.sca.node.Node;
import org.apache.tuscany.sca.node.NodeFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* This test case will test invoking @OneWay operations.
*
* @version $Date$ $Revision$
*/
public class OneWayTestCase {
/**
* Maximum period of time that we are prepared to wait for all the @OneWay
* method calls to complete in milliseconds.
*/
private static final int MAX_SLEEP_TIME = 10000;
private Node node;
/**
* Initialise the SCADomain.
*
* @throws Exception Failed to initialise the SCADomain
*/
@Before
public void setUp() throws Exception {
NodeFactory factory = NodeFactory.newInstance();
node = factory.createNode(new File("src/main/resources/OneWayContribution/META-INF/sca-deployables/oneWay.composite").toURI().toURL().toString(),
new Contribution("TestContribution", new File("src/main/resources/OneWayContribution/META-INF/sca-deployables/").toURI().toURL().toString()));
node.start();
}
/**
* This method will ensure that the SCADomain is shutdown.
*
* @throws Exception Failed to shutdown the SCADomain
*/
@After
public void tearDown() throws Exception {
node.stop();
}
/**
* This test will test repeatedly calling a @OneWay operation and ensure that the correct
* number of @OneWay operations are run.
*
* @throws Exception Test failed
*/
@Test
public void testOneWay() throws Exception {
OneWayClient client =
node.getService(OneWayClient.class, "OneWayClientComponent");
int count = 100;
for (int i = 0; i < 10; i++) {
// System.out.println("Test: doSomething " + count);
// System.out.flush();
client.doSomething(count);
// TUSCANY-2192 - We need to sleep to allow the @OneWay method calls to complete.
// Note: This can take different periods depending on the speed and load
// on the computer where the test is being run.
// This loop will wait for the required number of @OneWay method calls to
// have taken place or MAX_SLEEP_TIME to have passed.
long startSleep = System.currentTimeMillis();
while (OneWayClientImpl.callCount != OneWayServiceImpl.CALL_COUNT.get()
&& System.currentTimeMillis() - startSleep < MAX_SLEEP_TIME) {
Thread.sleep(100);
// System.out.println("" + OneWayClientImpl.callCount + "," + OneWayServiceImpl.callCount);
}
System.out.println("Finished callCount = " + OneWayServiceImpl.CALL_COUNT);
Assert.assertEquals(OneWayClientImpl.callCount, OneWayServiceImpl.CALL_COUNT.get());
}
}
/**
* This method will invoke a @OneWay method that throws an exception
* when invoked over a SCA Binding which uses the NonBlockingInterceptor and
* ensure that the Exception is logged.
* See TUSCANY-2225
*/
@Test
public void testOneWayUsingNonBlockingInterceptorThrowsAnException() {
OneWayClient client =
node.getService(OneWayClient.class, "OneWayClientComponentSCABinding");
// We need to modify the JDK Logger for the NonBlockingInterceptor so we
// can check that it logs a message for the @OneWay invocation that throws
// an Exception
Logger nbiLogger = Logger.getLogger(NonBlockingInterceptor.class.getName());
DummyJDKHandler handler = new DummyJDKHandler();
nbiLogger.addHandler(handler);
// Add a message on the console to explain the stack dump that is going to be
// displayed and state that this is not a problem but expected behaviour
System.out.println();
System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
System.out.println("IMPORTANT: The error message that appears on the console");
System.out.println("below is an expected error if it is a NullPointerException");
System.out.println(" with the message of:");
System.out.println(" \"" + OneWayServiceImpl.EXCEPTION_MESSAGE + "\"");
System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
System.out.println();
System.out.flush();
// Invoke the @OneWay method that throws an exception
client.doSomethingWhichThrowsException();
// The logging is done asynchronously so we will need to wait a bit before
// the log message appears.
long start = System.currentTimeMillis();
boolean logged = false;
while (System.currentTimeMillis() - start < MAX_SLEEP_TIME && !logged) {
// Has the log message been logged?
if (handler.exceptionLogged.get()) {
logged = true;
} else {
try {
Thread.sleep(25);
} catch (InterruptedException ex) {
Assert.fail("Unexpected exception " + ex);
}
}
}
// Add a message explaining that errors beyond this point should be reported
System.out.println();
System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
System.out.println("End of expected exceptions. Any errors beyond this point are errors!");
System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
System.out.println();
System.out.flush();
// Remove the handler
nbiLogger.removeHandler(handler);
// Make sure that the exception was logged
Assert.assertTrue(handler.exceptionLogged.get());
}
/**
* A handler that is added to the JDK Logging system to examine the log messages
* generated to ensure that a @OneWay method that throws an Exception will
* generate a log message.
*/
private class DummyJDKHandler extends Handler {
/**
* Used to track whether the exception has been logged.
*/
private AtomicBoolean exceptionLogged = new AtomicBoolean(false);
/**
* Constructor.
*/
private DummyJDKHandler() {
super.setLevel(Level.ALL);
}
/**
* {@inheritDoc}
*/
@Override
public void close() throws SecurityException {
// Nothing to do
}
/**
* {@inheritDoc}
*/
@Override
public void flush() {
// Nothing to do
}
/**
* Examines the LogRecord and checks whether it matches the one we are looking for.
* If it matches, it will set exceptionLogged to True.
*
* @param record The Log Record that is being published
*/
@Override
public void publish(LogRecord record) {
// The log message we are looking for is Severe
if (record.getLevel() == Level.SEVERE) {
if (record.getThrown() != null
&& record.getThrown().toString().indexOf(
OneWayServiceImpl.EXCEPTION_MESSAGE) != -1) {
// We have found our Exception.
exceptionLogged.set(true);
}
}
}
}
}