/**
* 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.cxf.ws.eventing.integration;
import java.io.IOException;
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.ws.addressing.AttributedURIType;
import org.apache.cxf.ws.addressing.EndpointReferenceType;
import org.apache.cxf.ws.addressing.ReferenceParametersType;
import org.apache.cxf.ws.eventing.DeliveryType;
import org.apache.cxf.ws.eventing.ExpirationType;
import org.apache.cxf.ws.eventing.FilterType;
import org.apache.cxf.ws.eventing.FormatType;
import org.apache.cxf.ws.eventing.ObjectFactory;
import org.apache.cxf.ws.eventing.Subscribe;
import org.apache.cxf.ws.eventing.backend.notification.NotificatorService;
import org.apache.cxf.ws.eventing.backend.notification.emitters.Emitter;
import org.apache.cxf.ws.eventing.backend.notification.emitters.EmitterImpl;
import org.apache.cxf.ws.eventing.base.SimpleEventingIntegrationTest;
import org.apache.cxf.ws.eventing.base.TestUtil;
import org.apache.cxf.ws.eventing.integration.eventsink.TestingEventSinkImpl;
import org.apache.cxf.ws.eventing.integration.eventsink.TestingWrappedEventSinkImpl;
import org.apache.cxf.ws.eventing.integration.notificationapi.EarthquakeEvent;
import org.apache.cxf.ws.eventing.integration.notificationapi.FireEvent;
import org.apache.cxf.ws.eventing.shared.EventingConstants;
import org.apache.cxf.ws.eventing.shared.utils.DurationAndDateUtil;
import org.junit.Assert;
import org.junit.Test;
public class NotificationTest extends SimpleEventingIntegrationTest {
static final String NOTIFICATION_TEST_PORT = allocatePort(NotificationTest.class);
@Test
public void basicReceptionOfEvents() throws IOException {
NotificatorService service = createNotificatorService();
Subscribe subscribe = new Subscribe();
ExpirationType exp = new ExpirationType();
exp.setValue(
DurationAndDateUtil.convertToXMLString(DurationAndDateUtil.parseDurationOrTimestamp("PT0S")));
subscribe.setExpires(exp);
EndpointReferenceType eventSinkERT = new EndpointReferenceType();
AttributedURIType eventSinkAddr = new AttributedURIType();
String url = TestUtil.generateRandomURLWithHttpTransport(NOTIFICATION_TEST_PORT);
eventSinkAddr.setValue(url);
eventSinkERT.setAddress(eventSinkAddr);
subscribe.setDelivery(new DeliveryType());
subscribe.getDelivery().getContent()
.add(new ObjectFactory().createNotifyTo(eventSinkERT));
eventSourceClient.subscribeOp(subscribe);
eventSourceClient.subscribeOp(subscribe);
eventSourceClient.subscribeOp(subscribe);
Server eventSinkServer = createEventSink(url);
TestingEventSinkImpl.RECEIVED_FIRES.set(0);
service.start();
Emitter emitter = new EmitterImpl(service);
emitter.dispatch(new FireEvent("Canada", 8));
for (int i = 0; i < 10; i++) {
if (TestingEventSinkImpl.RECEIVED_FIRES.get() == 3) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
eventSinkServer.stop();
if (TestingEventSinkImpl.RECEIVED_FIRES.get() != 3) {
Assert.fail("TestingEventSinkImpl should have received 3 events but received "
+ TestingEventSinkImpl.RECEIVED_FIRES.get());
}
}
@Test
public void basicReceptionOfWrappedEvents() throws IOException {
NotificatorService service = createNotificatorService();
Subscribe subscribe = new Subscribe();
ExpirationType exp = new ExpirationType();
exp.setValue(
DurationAndDateUtil.convertToXMLString(DurationAndDateUtil.parseDurationOrTimestamp("PT0S")));
subscribe.setExpires(exp);
EndpointReferenceType eventSinkERT = new EndpointReferenceType();
AttributedURIType eventSinkAddr = new AttributedURIType();
String url = TestUtil.generateRandomURLWithHttpTransport(NOTIFICATION_TEST_PORT);
eventSinkAddr.setValue(url);
eventSinkERT.setAddress(eventSinkAddr);
subscribe.setDelivery(new DeliveryType());
subscribe.getDelivery().getContent().add(new ObjectFactory().createNotifyTo(eventSinkERT));
FormatType formatType = new FormatType();
formatType.setName(EventingConstants.DELIVERY_FORMAT_WRAPPED);
subscribe.setFormat(formatType);
eventSourceClient.subscribeOp(subscribe);
eventSourceClient.subscribeOp(subscribe);
eventSourceClient.subscribeOp(subscribe);
Server eventSinkServer = createWrappedEventSink(url);
TestingWrappedEventSinkImpl.RECEIVED_FIRES.set(0);
service.start();
Emitter emitter = new EmitterImpl(service);
emitter.dispatch(new FireEvent("Canada", 8));
for (int i = 0; i < 10; i++) {
if (TestingWrappedEventSinkImpl.RECEIVED_FIRES.get() == 3) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
eventSinkServer.stop();
if (TestingWrappedEventSinkImpl.RECEIVED_FIRES.get() != 3) {
Assert.fail("TestingWrappedEventSinkImpl should have received 3 events but received "
+ TestingWrappedEventSinkImpl.RECEIVED_FIRES.get());
}
}
@Test
public void withWSAAction() throws Exception {
NotificatorService service = createNotificatorService();
Subscribe subscribe = new Subscribe();
ExpirationType exp = new ExpirationType();
exp.setValue(
DurationAndDateUtil.convertToXMLString(DurationAndDateUtil.parseDurationOrTimestamp("PT0S")));
subscribe.setExpires(exp);
EndpointReferenceType eventSinkERT = new EndpointReferenceType();
AttributedURIType eventSinkAddr = new AttributedURIType();
String url = TestUtil.generateRandomURLWithHttpTransport(NOTIFICATION_TEST_PORT);
eventSinkAddr.setValue(url);
eventSinkERT.setAddress(eventSinkAddr);
subscribe.setDelivery(new DeliveryType());
subscribe.getDelivery().getContent().add(new ObjectFactory().createNotifyTo(eventSinkERT));
eventSourceClient.subscribeOp(subscribe);
Server eventSinkServer = createEventSinkWithWSAActionAssertion(url, "http://www.fire.com");
TestingEventSinkImpl.RECEIVED_FIRES.set(0);
service.start();
Emitter emitter = new EmitterImpl(service);
emitter.dispatch(new FireEvent("Canada", 8));
for (int i = 0; i < 10; i++) {
if (TestingEventSinkImpl.RECEIVED_FIRES.get() == 1) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
eventSinkServer.stop();
if (TestingEventSinkImpl.RECEIVED_FIRES.get() != 1) {
Assert.fail("TestingEventSinkImpl should have received 1 events but received "
+ TestingEventSinkImpl.RECEIVED_FIRES.get());
}
}
@Test
public void withReferenceParameters() throws Exception {
NotificatorService service = createNotificatorService();
Subscribe subscribe = new Subscribe();
ExpirationType exp = new ExpirationType();
exp.setValue(
DurationAndDateUtil.convertToXMLString(DurationAndDateUtil.parseDurationOrTimestamp("PT0S")));
subscribe.setExpires(exp);
EndpointReferenceType eventSinkERT = new EndpointReferenceType();
JAXBElement<String> idqn
= new JAXBElement<String>(new QName("http://www.example.org", "MyReferenceParameter"),
String.class,
"380");
JAXBElement<String> idqn2
= new JAXBElement<String>(new QName("http://www.example.org", "MyReferenceParameter2"),
String.class,
"381");
eventSinkERT.setReferenceParameters(new ReferenceParametersType());
eventSinkERT.getReferenceParameters().getAny().add(idqn);
eventSinkERT.getReferenceParameters().getAny().add(idqn2);
AttributedURIType eventSinkAddr = new AttributedURIType();
String url = TestUtil.generateRandomURLWithHttpTransport(NOTIFICATION_TEST_PORT);
eventSinkAddr.setValue(url);
eventSinkERT.setAddress(eventSinkAddr);
subscribe.setDelivery(new DeliveryType());
subscribe.getDelivery().getContent().add(new ObjectFactory().createNotifyTo(eventSinkERT));
eventSourceClient.subscribeOp(subscribe);
Server eventSinkServer = createEventSinkWithReferenceParametersAssertion(url,
eventSinkERT.getReferenceParameters());
TestingEventSinkImpl.RECEIVED_FIRES.set(0);
service.start();
Emitter emitter = new EmitterImpl(service);
emitter.dispatch(new FireEvent("Canada", 8));
for (int i = 0; i < 10; i++) {
if (TestingEventSinkImpl.RECEIVED_FIRES.get() == 1) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
eventSinkServer.stop();
int received = TestingEventSinkImpl.RECEIVED_FIRES.get();
if (received != 1) {
Assert.fail("TestingEventSinkImpl should have received 1 events but received "
+ received);
}
}
/**
* We request only to receive notifications about fires in Canada
* and there will be a fire in Canada. We should receive
* this notification.
*/
@Test
public void withFilter() throws IOException {
NotificatorService service = createNotificatorService();
Subscribe subscribe = new Subscribe();
ExpirationType exp = new ExpirationType();
exp.setValue(
DurationAndDateUtil.convertToXMLString(DurationAndDateUtil.parseDurationOrTimestamp("PT0S")));
subscribe.setExpires(exp);
EndpointReferenceType eventSinkERT = new EndpointReferenceType();
AttributedURIType eventSinkAddr = new AttributedURIType();
String url = TestUtil.generateRandomURLWithHttpTransport(NOTIFICATION_TEST_PORT);
eventSinkAddr.setValue(url);
eventSinkERT.setAddress(eventSinkAddr);
subscribe.setDelivery(new DeliveryType());
subscribe.getDelivery().getContent().add(new ObjectFactory().createNotifyTo(eventSinkERT));
subscribe.setFilter(new FilterType());
subscribe.getFilter().getContent().add("//*[local-name()='fire' and "
+ "namespace-uri()='http://www.events.com']/location[text()='Canada']");
eventSourceClient.subscribeOp(subscribe);
Server eventSinkServer = createEventSink(url);
TestingEventSinkImpl.RECEIVED_FIRES.set(0);
service.start();
Emitter emitter = new EmitterImpl(service);
emitter.dispatch(new FireEvent("Canada", 8));
for (int i = 0; i < 10; i++) {
if (TestingEventSinkImpl.RECEIVED_FIRES.get() == 1) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
eventSinkServer.stop();
if (TestingEventSinkImpl.RECEIVED_FIRES.get() != 1) {
Assert.fail("TestingEventSinkImpl should have received 1 events but received "
+ TestingEventSinkImpl.RECEIVED_FIRES.get());
}
}
/**
* We request only to receive notifications about fires in Russia
* and there will be only a fire in Canada. We should not receive
* this notification.
*/
@Test
public void withFilterNegative() throws IOException {
NotificatorService service = createNotificatorService();
Subscribe subscribe = new Subscribe();
ExpirationType exp = new ExpirationType();
exp.setValue(
DurationAndDateUtil.convertToXMLString(DurationAndDateUtil.parseDurationOrTimestamp("PT0S")));
subscribe.setExpires(exp);
EndpointReferenceType eventSinkERT = new EndpointReferenceType();
AttributedURIType eventSinkAddr = new AttributedURIType();
String url = TestUtil.generateRandomURLWithHttpTransport(NOTIFICATION_TEST_PORT);
eventSinkAddr.setValue(url);
eventSinkERT.setAddress(eventSinkAddr);
subscribe.setDelivery(new DeliveryType());
subscribe.getDelivery().getContent().add(new ObjectFactory().createNotifyTo(eventSinkERT));
subscribe.setFilter(new FilterType());
subscribe.getFilter().getContent().add("/*[local-name()='fire']/location[text()='Russia']");
eventSourceClient.subscribeOp(subscribe);
Server eventSinkServer = createEventSink(url);
TestingEventSinkImpl.RECEIVED_FIRES.set(0);
service.start();
Emitter emitter = new EmitterImpl(service);
emitter.dispatch(new FireEvent("Canada", 8));
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
eventSinkServer.stop();
if (TestingEventSinkImpl.RECEIVED_FIRES.get() != 0) {
Assert.fail("TestingEventSinkImpl should have received 0 events but received "
+ TestingEventSinkImpl.RECEIVED_FIRES.get());
}
}
/**
* We request only to receive notifications about earthquakes in Russia with Richter scale equal to 3.5
* and there will be one fire in Canada and one earthquake in Russia. We should
* receive only one notification.
*/
@Test
public void withFilter2() throws IOException {
NotificatorService service = createNotificatorService();
Subscribe subscribe = new Subscribe();
ExpirationType exp = new ExpirationType();
exp.setValue(
DurationAndDateUtil.convertToXMLString(DurationAndDateUtil.parseDurationOrTimestamp("PT0S")));
subscribe.setExpires(exp);
EndpointReferenceType eventSinkERT = new EndpointReferenceType();
AttributedURIType eventSinkAddr = new AttributedURIType();
String url = TestUtil.generateRandomURLWithHttpTransport(NOTIFICATION_TEST_PORT);
eventSinkAddr.setValue(url);
eventSinkERT.setAddress(eventSinkAddr);
subscribe.setDelivery(new DeliveryType());
subscribe.getDelivery().getContent().add(new ObjectFactory().createNotifyTo(eventSinkERT));
subscribe.setFilter(new FilterType());
subscribe.getFilter().getContent()
.add("//*[local-name()='earthquake']/location[text()='Russia']/"
+ "../richterScale[contains(text(),'3.5')]");
eventSourceClient.subscribeOp(subscribe);
Server eventSinkServer = createEventSink(url);
TestingEventSinkImpl.RECEIVED_FIRES.set(0);
TestingEventSinkImpl.RECEIVED_EARTHQUAKES.set(0);
service.start();
Emitter emitter = new EmitterImpl(service);
emitter.dispatch(new FireEvent("Canada", 8));
emitter.dispatch(new EarthquakeEvent(3.5f, "Russia"));
for (int i = 0; i < 10; i++) {
if (TestingEventSinkImpl.RECEIVED_EARTHQUAKES.get() == 1) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
eventSinkServer.stop();
if (TestingEventSinkImpl.RECEIVED_EARTHQUAKES.get() != 1) {
Assert.fail("TestingEventSinkImpl should have received 1 earthquake event but received "
+ TestingEventSinkImpl.RECEIVED_EARTHQUAKES.get());
}
if (TestingEventSinkImpl.RECEIVED_FIRES.get() != 0) {
Assert.fail("TestingEventSinkImpl should have not received a fire event"
+ TestingEventSinkImpl.RECEIVED_FIRES.get());
}
}
/**
* request a subscription that expires soon
* an event will be emitted after the expiration
* we should not receive notification about the event
* @throws IOException
*/
@Test
public void expiration() throws IOException {
NotificatorService service = createNotificatorService();
Subscribe subscribe = new Subscribe();
ExpirationType exp = new ExpirationType();
exp.setValue(
DurationAndDateUtil.convertToXMLString(DurationAndDateUtil.parseDurationOrTimestamp("PT1S")));
subscribe.setExpires(exp);
EndpointReferenceType eventSinkERT = new EndpointReferenceType();
AttributedURIType eventSinkAddr = new AttributedURIType();
String url = TestUtil.generateRandomURLWithHttpTransport(NOTIFICATION_TEST_PORT);
eventSinkAddr.setValue(url);
eventSinkERT.setAddress(eventSinkAddr);
subscribe.setDelivery(new DeliveryType());
subscribe.getDelivery().getContent().add(new ObjectFactory().createNotifyTo(eventSinkERT));
eventSourceClient.subscribeOp(subscribe);
Server eventSinkServer = createEventSink(url);
TestingEventSinkImpl.RECEIVED_FIRES.set(0);
service.start();
Emitter emitter = new EmitterImpl(service);
try {
Thread.sleep(3000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
emitter.dispatch(new FireEvent("Canada", 8));
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
eventSinkServer.stop();
if (TestingEventSinkImpl.RECEIVED_FIRES.get() != 0) {
Assert.fail("TestingEventSinkImpl should not have received any events but received "
+ TestingEventSinkImpl.RECEIVED_FIRES.get());
}
}
}