/*=============================================================================*
* Copyright 2004 The Apache Software Foundation
*
* 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.
*=============================================================================*/
import junit.framework.TestCase;
import org.apache.ws.addressing.EndpointReference;
import org.apache.ws.addressing.XmlBeansEndpointReference;
import org.apache.ws.muws.interop.client.FaultException;
import org.apache.ws.muws.interop.client.ResourceStub;
import org.apache.ws.muws.interop.client.ServiceStub;
import org.apache.ws.muws.v1_0.MuwsConstants;
import org.apache.ws.muws.v1_0.capability.OperationalStatusCapability;
import org.apache.ws.util.XmlBeanUtils;
import org.apache.ws.util.test.PortListen;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl;
import org.oasisOpen.docs.wsdm.x2004.x12.muws.wsdmMuwsPart1.ComponentAddressType;
import org.oasisOpen.docs.wsdm.x2004.x12.muws.wsdmMuwsPart1.ComponentType;
import org.oasisOpen.docs.wsdm.x2004.x12.muws.wsdmMuwsPart1.impl.ManagementEventTypeImpl;
import org.oasisOpen.docs.wsn.x2004.x06.wsnWSBaseNotification12Draft01.NotificationMessageHolderType;
import org.oasisOpen.docs.wsn.x2004.x06.wsnWSBaseNotification12Draft01.NotifyDocument;
import org.oasisOpen.docs.wsrf.x2004.x06.wsrfWSResourceProperties12Draft01.ResourcePropertyValueChangeNotificationType;
import org.wsdmdemo.service.InteropConstants;
import org.wsdmdemo.service.InteropRequestUtils;
import org.wsdmdemo.service.weatherStation.RecalibrateDocument;
import org.xmlsoap.schemas.soap.envelope.Body;
import org.xmlsoap.schemas.soap.envelope.EnvelopeDocument;
import org.xmlsoap.schemas.ws.x2004.x08.addressing.EndpointReferenceDocument;
import org.xmlsoap.schemas.ws.x2004.x08.addressing.EndpointReferenceType;
import javax.xml.namespace.QName;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
/**
* @author Sal Campana
*/
public class WeatherStationNotifTest
extends TestCase
{
private static final String WEATHER_STATION_1_EPR_URL =
System.getProperty(InteropConstants.SYSPROP_WS1_EPR_URL,
"http://localhost:8080/muse/epr/weather-station-1-epr.xml");
private static EndpointReferenceDocument WEATHER_STATION_1_EPR_DOC;
private ResourceStub m_resource;
private PortListen m_listener;
/**
* The actual unit test...well not really a unit test but still....
*
* @throws FaultException
* @throws IOException
* @throws XmlException
*/
public void testNotif()
throws FaultException,
IOException,
XmlException
{
//build a resource stub for the weather station you plan to talk to
XmlBeansEndpointReference xepr =
new XmlBeansEndpointReference(WEATHER_STATION_1_EPR_DOC.getEndpointReference());
m_resource = new ResourceStub(xepr);
//make sure to have path in consumer url...not sure if he still needs it be we had added at one point
String consumerUrl = "http://12.35.246.160:8001/notifs";
//subscribe for the events
EndpointReference subscriptionEPR = subscribeForOperationalStatusChangeEvents(consumerUrl, m_resource);
//setup port listener
m_listener = new PortListen(80, 600000);
//call recalibrate (after noticing erratic behavior) on webservice to trigger the status change evennt
sendRecalibrateRequest(xepr);
//listen for operational change notif ...this will actually capture any message that comes in...
String messageText = m_listener.waitForIncomingMessage();
//upon notification.......dump to standard out for debugging
System.out.println(messageText);
try
{
//parse out the managementevent
ManagementEventTypeImpl manEvt = parseManagementEvent(messageText);
//here is the epr and the address of the source of the event....this is the weatherstation which caused the event.
EndpointReferenceType sourceEpr = parseSourceEpr(manEvt);
String sourceAddress = sourceEpr.getAddress().getStringValue();
//get the current operational status.....
String currentOperationalStatus = parseCurrentOperationalStatus(manEvt);
//try again to get the available message ...this was to debug their end....
m_listener = new PortListen(80, 600000);
String messageText2 = m_listener.waitForIncomingMessage();
}
catch (Exception e)
{
e.printStackTrace();
}
}
protected void setUp()
throws Exception
{
//init the epr
WEATHER_STATION_1_EPR_DOC = InteropRequestUtils.getEndpointReference(new URL(WEATHER_STATION_1_EPR_URL));
}
/**
* Gets the current OperationalStatus from the ManagementEvent
*
* @param manEvt
* @return OperationalStatus (i.e. Available)
*/
private String parseCurrentOperationalStatus(ManagementEventTypeImpl manEvt)
{
XmlObject[] childElements = XmlBeanUtils.getChildElements(manEvt);
ResourcePropertyValueChangeNotificationType propChange =
(ResourcePropertyValueChangeNotificationType) childElements[3];
ResourcePropertyValueChangeNotificationType.NewValue newValue = propChange.getNewValue();
XmlObject operationalStatus =
XmlBeanUtils.getChildElements(newValue)[0];
XmlCursor xmlCursor = operationalStatus.newCursor();
return xmlCursor.getTextValue();
}
/**
* Parses the ManagementEvent out of the SOAPEnvelope
*
* @param messageText
* @return ManagementEvent
* @throws XmlException
*/
private ManagementEventTypeImpl parseManagementEvent(String messageText)
throws XmlException
{
EnvelopeDocument ed = (EnvelopeDocument) XmlObject.Factory.parse(messageText);
org.xmlsoap.schemas.soap.envelope.Envelope env = ed.getEnvelope();
Body body = env.getBody();
XmlObject[] arryStuff = XmlBeanUtils.getChildElements(body);
NotifyDocument.Notify ele = (NotifyDocument.Notify) arryStuff[0];
NotificationMessageHolderType noteMess = ele.getNotificationMessageArray(0);
XmlAnyTypeImpl mess = (XmlAnyTypeImpl) noteMess.getMessage();
ManagementEventTypeImpl manEvt =
(ManagementEventTypeImpl) XmlBeanUtils.getChildElements(mess)[0];
return manEvt;
}
/**
* Parses the source (web service which threw event) epr from the ManagementEvent
*
* @param manEvt
* @return Source EPR
*/
private EndpointReferenceType parseSourceEpr(ManagementEventTypeImpl manEvt)
{
ComponentType sourceComponent = manEvt.getSourceComponent();
ComponentAddressType sourceCompAddr = sourceComponent.getComponentAddressArray(0);
EndpointReferenceType sourceEpr =
(EndpointReferenceType) XmlBeanUtils.getChildElements(sourceCompAddr)[0];
return sourceEpr;
}
/**
* Sends a recalibrate call to the webservice.....
*
* @param xepr
*/
private void sendRecalibrateRequest(XmlBeansEndpointReference xepr)
{
ResourceStub sstub = new ResourceStub(xepr);
RecalibrateDocument recalibrateDocument = RecalibrateDocument.Factory.newInstance();
recalibrateDocument.addNewRecalibrate();
sstub.sendRequest(recalibrateDocument,
"http://recalibrate");
}
/**
* Subscribes for OperationalStatusCapability Notifications
*
* @param consumerUrl
* @param resourceStub
* @throws FaultException
*/
private EndpointReference subscribeForOperationalStatusChangeEvents(String consumerUrl,
ResourceStub resourceStub)
throws FaultException
{
return resourceStub.subscribe(consumerUrl,
new QName(MuwsConstants.NSURI_MUWS_PART2_TOPICS,
OperationalStatusCapability.TOPIC_NAME));
}
}