You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by st...@apache.org on 2003/04/21 07:28:04 UTC
cvs commit: xml-axis/addons/discovery/xml checkstyle-noframes.xsl message.xsd
stevel 2003/04/20 22:28:03
Added: addons/discovery build.xml
addons/discovery/doc discovery.properties ws-discovery.dbk
addons/discovery/src log4j.properties
addons/discovery/src/org/apache/axis/discovery/client
Client.java ResponseReceivedListener.java
addons/discovery/src/org/apache/axis/discovery/core
BroadcastTransceiver.java Const.java
DiscoveryException.java DiscoveryMessage.java
LoggingTransceiver.java LoopbackTransceiver.java
Marshaller.java MessageQueue.java
MulticastTransceiver.java
SubnetPollTransceiver.java Transceiver.java
Utils.java XmlMarshaller.java
addons/discovery/src/org/apache/axis/discovery/server
AxisBinder.java DiscoveryListener.java
DiscoveryServer.java ServiceEntry.java
UriStore.java
addons/discovery/src/org/apache/axis/discovery/server/management
DiscoveryServlet.java ServerMBean.java
ServiceEntryMBean.java
addons/discovery/src/org/apache/axis/discovery/test
LoopbackTest.java MarshallTest.java
MessagingTestBase.java NetBroadcastTest.java
NetMulticastTest.java NetworkTest.java
ResolveTest.java SubnetPollTest.java
TransceiverTestBase.java
addons/discovery/web discovery.jsp
addons/discovery/web/WEB-INF .cvskeep
addons/discovery/xml checkstyle-noframes.xsl message.xsd
Log:
multicast (and broadcast (and brute force poll)) discovery for web services, dynamically bound to Axis; also works as standalone. Currently uses Castor; I should move to a pure dom or sax binding.
The protocol itself is an XML version of Service Location Protocol; at this stage we could actually plug in a new wire format and the discovery service would *really* be SLP, though we dont scope ourselves properly (its polite to get scope from DHCP servers), and I deliberately throttle back the TTL from 255 to something lower. We need more experimentation there.
Documentation is docbook format, XSLTs to HTML, FOPs to PDF. We need more docs, and a better way of integrating with Axis than hacking a new service into axis's web.xml.
Revision Changes Path
1.1 xml-axis/addons/discovery/build.xml
Index: build.xml
===================================================================
<?xml version="1.0" ?>
<project name="discovery" default="default">
<description>
Build file for discovery; endpoint location/discovery application
that uses Multicast IP to find endpoints in a LAN.
Libraries Used in the application (add them to lib/)
axis.jar CVS head
castor-0.9.4.3.jar http://castor.exolab.org/
commons-logging 1.0.3 http://jakarta.apache.org
log4j-1.2.7.jar http://jakarta.apache.org (optional)
+probably an XML parser if not working on Java1.4
Libraries used at build time
junit.jar 3.8.1 junit.org
servlet.jar 2.3 java.sun.com
Extras used in the build process
checkstyle sourceforge.net
Docbook DTDs docbook.org
</description>
<property file="build.properties"/>
<property environment="env"/>
<property name ="build.dir" location="build/" />
<property name ="classes.dir"
location="${build.dir}/classes" />
<property name ="src.dir"
location="src" />
<property name ="lib.dir"
location="lib" />
<property name ="dist.dir"
location="dist" />
<property name="doc.dir" location="doc"/>
<property name="javadoc.dir" location="${doc.dir}/javadoc"/>
<property name="jar.filename"
value="axis-discovery.jar"/>
<property name ="jar.file"
location="${dist.dir}/${jar.filename}" />
<property name="axis.home" location="..\..\java"/>
<property name="axis.dist.dir" location="${axis.home}/build/lib"/>
<property name="castor.src.dir"
location="${build.dir}/castor/src"/>
<property name="castor.touchfile" location="${castor.src.dir}/castor.built"/>
<property name="castor.package"
value="org.apache.axis.discovery.xml"/>
<property name="castor.dist.dir"
location="${lib.dir}"/>
<property name="xml.schema.file"
location="xml/message.xsd"/>
<!-- when running castor we want all in its classpath -->
<path id="castor.execute.path">
<fileset dir="${castor.dist.dir}" includes="**/*.jar"/>
</path>
<path id="compile.classpath">
<fileset dir="${lib.dir}" includes="**/*.jar"/>
<fileset dir="${axis.dist.dir}" includes="**/*.jar"/>
</path>
<path id="execute.classpath">
<fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>
<target name="init">
<mkdir dir="${build.dir}"/>
<mkdir dir="${classes.dir}"/>
<mkdir dir="${dist.dir}"/>
</target>
<target name="clean" description="clean up" >
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
<delete dir="${javadoc.dir}" />
</target>
<target name="compile" depends="init,castor">
<depend srcdir="${src.dir}"
destdir="${classes.dir}"
cache="${build.dir}/depends"
closure="yes"/>
<javac
debug="true"
debuglevel="lines,vars,source"
includeAntRuntime="false"
destdir="${classes.dir}"
target="1.2"
classpathref="compile.classpath"
>
<src path="${src.dir}"/>
<src path="${castor.src.dir}"/>
</javac>
<copy todir="${classes.dir}">
<fileset dir="${src.dir}"
includes="**/*.xml,**/*.dtd,**/*.xsd,**/*.properties" />
</copy>
</target>
<target name="dist" depends="compile"
description="create a distribution">
<jar destfile="${jar.file}">
<zipfileset dir="${classes.dir}" includes="org/**/*"/>
</jar>
</target>
<target name="test" depends="compile"
description="run unit tests">
<junit printsummary="withOutAndErr" fork="no" haltonfailure="yes">
<classpath>
<path refid="execute.classpath"/>
<pathelement location="${classes.dir}"/>
</classpath>
<batchtest >
<fileset dir="${src.dir}">
<include name="**/*Test.java" />
<exclude name="**/Net*Test.java" unless="online" />
</fileset>
</batchtest>
</junit>
</target>
<!-- build the Javadocs -->
<target name="javadocs" description="make the java docs" >
<mkdir dir="${javadoc.dir}"/>
<javadoc author="false"
destdir="${javadoc.dir}"
packagenames="org.*"
use="true"
version="true"
windowtitle="Axis-Discovery"
package="true"
>
<sourcepath>
<pathelement location="src"/>
</sourcepath>
<classpath refid="compile.classpath"/>
</javadoc>
</target>
<target name="server" depends="dist"
description="run the server">
<java classname="org.apache.axis.discovery.server.DiscoveryServer"
fork="true" failonerror="true">
<classpath>
<path refid="execute.classpath"/>
<pathelement location="${jar.file}"/>
</classpath>
<arg file="doc/discovery.properties"/>
</java>
</target>
<target name="client" depends="dist"
description="run the client">
<property name="uri" value="service:axis-discovery"/>
<java classname="org.apache.axis.discovery.client.Client"
fork="true" failonerror="true">
<classpath>
<path refid="execute.classpath"/>
<pathelement location="${jar.file}"/>
</classpath>
<arg value="${uri}"/>
</java>
</target>
<target name="default" depends="dist"/>
<target name="all" depends="dist,test,javadocs"/>
<property name="checkstyle.project" value="discovery"/>
<property name="checkstyle.src.dir" location="src"/>
<property name="checkstyle.dest.dir" location="${build.dir}/checkstyle/${checkstyle.project}"/>
<property name="checkstyle-noframes.xsl"
location="xml/checkstyle-noframes.xsl"/>
<!-- look for checkstyle; fail gracefully -->
<target name="probe_checkstyle">
<!-- classpathref="checkstyle.classpath" -->
<available property="checkstyle.found"
resource="checkstyletask.properties"
/>
<fail unless="checkstyle.found">
Unable to find the checkstyle jar on the classpath
</fail>
<taskdef resource="checkstyletask.properties" />
</target>
<target name="checkstyle" depends="init,probe_checkstyle"
description="Check the style of a project">
<echo message="Checking style of ${checkstyle.project}"/>
<mkdir dir="${checkstyle.dest.dir}"/>
<property name="report.stem" value="checkstyle-${checkstyle.project}" />
<property name="results.xml" value="${report.stem}.xml" />
<property name="resultsfile.xml"
location="${checkstyle.dest.dir}/${results.xml}" />
<property name="resultsfile.html"
location="${checkstyle.dest.dir}/${report.stem}.html" />
<checkstyle failOnViolation="${checkstyle.failonerror}"
maxLineLen="80"
allowNoAuthor="true"
allowProtected="true"
ignoreImports="true"
javadocScope="nothing"
memberPattern="^[a-z_][a-zA-Z0-9]*$"
cacheFile="${checkstyle.dest.dir}/checkstyle.cache">
<formatter type="plain"/>
<formatter type="xml" toFile="${resultsfile.xml}"/>
<fileset dir="${checkstyle.src.dir}" includes="**/*.java"/>
</checkstyle>
<style basedir="${checkstyle.dest.dir}" destdir="${checkstyle.dest.dir}"
includes="${results.xml}"
style="${checkstyle-noframes.xsl}"/>
<echo>
Style checked, results are in ${resultsfile.html}
</echo>
</target>
<!-- poll to see if castor files need rebuilding -->
<target name="check-castor" depends="init">
<uptodate property="castor.uptodate"
targetfile="${castor.touchfile}">
<srcfiles dir="xml" includes="**/*.xsd"/>
</uptodate>
</target>
<!--
create java classes that map to our XSD description of an XFF file
-->
<target name="castor" depends="check-castor" unless="castor.uptodate">
<property name="castor.generator"
value="org.exolab.castor.builder.SourceGenerator"/>
<java classname="${castor.generator}"
fork="true"
failonerror="true"
classpathref="castor.execute.path">
<arg value="-i"/>
<arg file="${xml.schema.file}"/>
<arg value="-package"/>
<arg value="${castor.package}"/>
<arg value="-dest"/>
<arg file="${castor.src.dir}"/>
<arg value="-types"/>
<arg value="j2"/>
<arg value="-f"/>
</java>
<touch file="${castor.touchfile}"/>
</target>
<!-- deploy to catalina -->
<target name="deploy-catalina" depends="dist"
description="deploy to axis on tomcat 4.x">
<fail unless="env.CATALINA_HOME"/>
<property name="webapp.name" value="axis" />
<property name="deploy.webapp.dir"
location="${env.CATALINA_HOME}/webapps/${webapp.name}" />
<property name="deploy.lib.dir"
location="${deploy.webapp.dir}/WEB-INF/lib" />
<copy todir="${deploy.webapp.dir}">
<fileset dir="web" includes="**/*" />
</copy>
<copy todir="${deploy.lib.dir}">
<fileset dir="${lib.dir}" includes="castor*.jar"/>
<fileset dir="${dist.dir}" includes="${jar.filename}"/>
</copy>
</target>
<!-- docbook stuff -->
<property name="fop.jar" location="${fop.home}/build/fop.jar"/>
<property name="docbook.fo.xsl"
location="${docbook.home}/fo/docbook.xsl"/>
<property name="docbook.html.xsl"
location="${docbook.home}/html/docbook.xsl"/>
<target name="probe-docbook-dependencies">
<condition property="fop.found">
<and>
<isset property="fop.home"/>
<available file="${fop.jar}"/>
</and>
</condition>
<echo level="verbose">fop.found=${fop.found} at ${fop.jar}</echo>
<condition property="docbook.found">
<and>
<isset property="docbook.home"/>
<available file="${docbook.fo.xsl}"/>
<available file="${docbook.html.xsl}"/>
<isset property="fop.found"/>
</and>
</condition>
<echo level="verbose">docbook.found=${docbook.found}</echo>
<fail unless="docbook.found">Docbook is missing</fail>
</target>
<target name="init-docbook"
depends="probe-docbook-dependencies">
<taskdef name="fop"
classname="org.apache.fop.tools.anttasks.Fop" >
<classpath>
<pathelement location="${fop.jar}"/>
<fileset dir="${fop.home}/lib">
<include name="**/*.jar"/>
</fileset>
</classpath>
</taskdef>
</target>
<property name="paper" value="ws-discovery"/>
<property name="paper.src" location="${doc.dir}/${paper}.dbk"/>
<property name="paper.fo" location="${build.dir}/doc/${paper}.fo"/>
<property name="paper.pdf" location="${build.dir}/doc/${paper}.pdf" />
<property name="paper.html" location="${build.dir}/doc/${paper}.html" />
<target name="doc-pdf" depends="init-docbook"
description="Produces the PDF version of the paper">
<xslt style="${docbook.fo.xsl}"
in="${paper.src}" out="${paper.fo}" />
<java
classname="org.apache.fop.apps.Fop"
fork="true"
failonerror="true"
>
<arg value="-q"/>
<arg value="${paper.fo}"/>
<arg value="-pdf"/>
<arg file="${paper.pdf}"/>
<classpath>
<pathelement location="${fop.home}/build/fop.jar"/>
<fileset dir="${fop.home}/lib">
<include name="**/*.jar"/>
</fileset>
</classpath>
</java>
<!-- <exec executable="cmd.exe" os="Windows XP">
<arg line="/c java -Djava.ext.dirs=${tools}\lib\fop-0.20.3
-jar ${tools}\lib\fop-0.20.3.jar -q temp/${paper}.fo -pdf ${paper}.pdf" />
</exec>
-->
</target>
<target name="doc-html" depends="init-docbook"
description="Produces the HTML version of the paper">
<xslt style="${docbook.html.xsl}" in="${paper.src}" out="${paper.html}" />
</target>
<target name="doc" depends="doc-html,doc-pdf"/>
</project>
1.1 xml-axis/addons/discovery/doc/discovery.properties
Index: discovery.properties
===================================================================
http\://example.org/=http\://localhost:8080/axis/services/
1.1 xml-axis/addons/discovery/doc/ws-discovery.dbk
Index: ws-discovery.dbk
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
<?xmlspysps docbook.sps?><book>
<bookinfo>
<title>WS-Discovery</title>
<authorgroup>
<author>
<firstname>Steve</firstname>
<surname>Loughran</surname>
</author>
</authorgroup>
<publisher>
<publishername>Apache Web Services</publishername>
</publisher>
<copyright>
<year>Copyright (c) 2003 Apache Software Foundation</year>
</copyright>
</bookinfo>
<chapter>
<title>WS-Discovery</title>
<abstract>
<para>
This documenet describes a protocol for finding Web Services on a LAN or campus wide
network, using multicasting of XML request messages. The underlying payload is similar
to that of Service Location Protocol, though the directory agent process is omitted. To scale
well, integration with UDDI is required.
</para>
<para>
While it is easy to fault the design, mainly on security and scalability, the
initial implementation binds to Axis, automatically exporting running Axis services,
enabling local clients to find services without a server.
</para>
</abstract>
<sect1>
<title></title>
<sect2 id="rationale">
<title>rationale</title>
<para>This specification aims to provide dynamic discovery of web services on a
Local Area Network. It will not scale up to "the Internet", or
indeed a large Intranet, but it lets programs find local
implementations of well known services, including UDDI registries.</para>
<para>The envisaged uses are embedded web services, workgroup
computing systems and to bootstrap server-side clusters in a
'near-zero' configuration environment. Every server exporting
services can run a discovery server, responding to queries for the services
that it offers.</para>
<para>The protocol is not SOAP-centric; you could also use it to enumerate REST
objects that the client knows about; The system just maps URIs to URLs and
leaves to applications and entities at the end of URLs to work out the
details among themselves.</para>
</sect2>
<sect2 id="related-work">
<title>related work</title>
<sect3>
<title>Service Location Protocol</title>
<para>The IETF's Service Location Protocol, RFC2608, is an
example of how to use multicast discovery in a complex LAN network.
Its hierarchy of directory agents are intended to scale, as does the
advertisement mechanism, which can keep multicast traffic down. The
SLP is gradually acquiring more features, which make implementing it
more complex. WS-Discovery could grow to mimic SLP server, but it really
expects to hand off complex service location to a UDDI server. Such
a server, can of course be located with WS-Discovery. The SLP defines a
multicast IP Address 239.255.255.253, that we also use,
listening to a different port. The aim is to leverage any
administrative routing controls that have been set in place in SLP,
that recommends using that address and a TTL of 255; restrictions on
packet distance will be made in the network, not in the client.</para>
<para>SLPv2 adds scoping, and the option to specify the lifespan of
an endpoint being valid, and thus the limit of its cacheability.
Again, caching is an effective way to scale, and scoping could be
convenient to prevent accidental binding to the wrong
implementation.</para>
<para>SLP addresses scalability with advertising of directory
servers, and a URL based query mechanism to specify searches on the
server. In the Web Service world, we may be able to delegate such a
task to UDDI servers and the like, although the directory agents
effectively create an emergent directory of all located devices,
which current UDDI implementations do not.</para>
<para>What may be an interesting project would be to provide a UDDI
interface to a network of self-advertising web services; letting
programs use UDDI interfaces to find services in a dynamic network.</para>
</sect3>
<sect3>
<title>Jini</title>
<para>Sun's Jini has a LAN scoped discovery mechanism, that is
primarily Java based. It could perhaps be extended to locate Web
Services, though its bias on Java clients would limit its value.
Scalability of Jini is another concern; one it never had to address
due to its lack of success outside of some very interesting
academic Ubiquitous Computing demonstration projects. </para>
</sect3>
<sect3>
<title>JXTA</title>
<para>Sun's JXTA technology may also be usable for service
locations among a peer network. JXTA likes to be configured with the
name of a peer system, for the initial bootstrap. JXTA2 has a
multiple tier model of peers, that may complicate the model, but
make it more workable. </para>
</sect3>
<sect3>
<title>e"speak</title>
<para>HP's e"speak framework had a discovery mechanism for
its e-services, a blur of Jini and UDDI. It had a query
language; services would register themselves in a
<emphasis>vocabulary</emphasis> against which queries could be run.
An inconvenience of e"speak was that this was the only way that
services could be located. While discovery based location of
services is an effective means of locating services, it should not
be the only way. Forcing one to go through a registry to find all
services is like the Windows font creation API: you can't ask
for a font called courier, you have to ask for a fixed-width serif
font with a name like courier, and take what you are given, even if
it is the wrong font.</para>
</sect3>
<sect3>
<title>UPnP</title>
<para>Universal Plug and Play is a Microsoft-originated
specification for device interaction. It goes beyond discovery to
mandate the profiles that devices must use, so that they can
interact. It is focused at devices, not services, and to make use of
the UPnP Intellectual Property, UPnP device vendors must implement
at least one standardised device protocol. Thus, even though it
adopts SOAP as the interaction mechanism, UPnP is not suitable as a
discovery mechanism for arbitrary web services, ignoring technical
issues. From a technical standpoint, UPnP is neither good nor bad.
It does have a means of advertising functions of a service, but it
is not WSDL. The service discovery protocol, SSDP, using a variant
of HTTP to make requests, rather than pure XML. The protocol has a
default TTL of four, to minimise searches, yet the system lacks the
scalability of SLPv2, which keeps traffic down in a complex
environment by supporting discovery servers which retain knowledge
of currently services, and respond to unicast messages. One feature
of UPnP missing from Web Services is notification, yet by its nature
notification does not go through firewalls. Using the UPnP
notification algorithm would constrain services to only support LAN
scoped clients.</para>
<para>Although built into Windows XP, UPnP is not broadly popular.
One of the weaknesses of the design may be the same as Jini: by
redefining how things talk to each other, you need to redesign the
entire interoperability stack to have a functional UPnP service. The
UPnP device protocols are roughly comparable in complexity to
Bluetooth Profiles, yet the fact that everything bar discovery
already works today, makes implementing UPnP less than compelling.</para>
</sect3>
<sect3>
<title>Apple Rendezvous</title>
<para>The Rendezvous framework from Apple is also intended to
support device discovery. Rendezvous discounts the notion of
implementing a service discovery infrastructure in favour of DNS. In
a managed environment, services would dynamically register with the
DNS server. In an unmanaged environment, Apple's proposed
multicast DNS would let services be self-locating.</para>
<para>Apple argue in favour of using DNS for a number of reasons,
reasons which are partially compelling. It eliminates the need for
new servers on the network, unlike SLP and SLPv2. It also integrates
well in a corporate environment, as managed DNS servers take on the
workload. This is a marked contrast to UPnP, which is too chatty to
use on a busy network. The whole DNS caching and update mechanism
also acts as a replicated directory service, which provides high
availability.</para>
<para>Where Rendezvous falls down is its requirement for a dynamic
DNS registry: what does one do at home with static DNS handled by
the broadband supplier? One has to install a new DNS server. Without
a DNS server, the system will not query beyond the local subnet;
their multicast DNS gives all packets a TTL of 1. This limits its
use in mildly complex networks, such as one with a wireless access
point attached to a home LAN, unless the user is going to go to the
effort of setting up a DNS server, at which point the reuse of
existing standards becomes a liability, not a feature.</para>
<para>Nor is it easy to implement Rendezvous without extending the OS
to support multicast DNS. Apple did this for MacOS X, but nobody is
seemingly doing it for other platforms. We could (maybe) hack this in
as a layer atop Java, implementing a multicast DNS service in Java
and using this in the absence of a real DNS system. Similarly, the
managed DNS registration and lookup could be implemented in Java with
a binding to Axis. A Java implementation of Rendezvous would clearly
be an interesting exercise, albeit a potentially complex one. Still,
it may be easier than extending the WinNT network stack with the same
functionality.
</para>
<para>A final critique of Rendezvous it that is also weak when it
comes to queries: DNS does not really support a complex query syntax.
The region-specific hierarchy of DNS provides a single taxonomy for
finding services, unlike the multiple-taxonomy approach of UDDI.</para>
<para>Where Rendezvous has succeeded is taking multicast service
discovery mainstream, by integrating it into the OS and encouraging
application developers to work with it. By focusing
on discovery, rather than the harder problem of interoperability, it
is a simple and manageable specification. Thus it demonstrates the
value of a simple discovery mechanism for applications, albeit only
in the constrained space of the MacOS family (and perhaps Linux in
the near future)</para>
</sect3>
</sect2>
<sect2 id="protocol">
<title>protocol</title>
<para>Server listens on a well known (potentially IANA-assigned)
multicast group, awaiting resolution requests. Client builds a request
object, comprising</para>
<programlisting>
requestID: xsd:int
type: xsd:string
URI: xsd:anyURL
URL: xsd:anyURI
scope: xsd:string (can be "")
expires: xsd:int (optional)
</programlisting>
<para>
The XML Schema is as follows:
</para>
<programlisting>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="discovery">
<xs:annotation>
<xs:documentation>message of specified type</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="uri" type="xs:anyURI">
<xs:annotation>
<xs:documentation>uri of service</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="scope" type="xs:string">
<xs:annotation>
<xs:documentation>scope of request, leave empty for 'any' scope</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="url" type="xs:anyURI" minOccurs="0">
<xs:annotation>
<xs:documentation>endpoint of service</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="expires" type="xs:int" minOccurs="0">
<xs:annotation>
<xs:documentation>expiry time as time_t integer, always in UTC</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="description" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>optional description of endpoint</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="type" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
</programlisting>
<para>
The "type" attribute is the key to the system.
The protocol supports a series of verbs.
</para>
<programlisting>
"Find": look up any implementations of the supplied URI.
"Found": a found URL mapped from the requested URI.
"Advertisement": to be used in any announcement extensions.
</programlisting>
<para>Requests can be sent out with a TTL of 1,2,3, whatever. If the
client wants to find any implementation, rather than enumerate all
implementations in a location, then the client should slowly increase
the TTL till it gets a response: using the same requestID.
Services should ignore repeated requests from the same host with the
same request ID.</para>
<para>Server receives the "Find" request. If the combination of (senderIP,
requestID) is in the list of recent requests, the server does not
respond to the request. If the request merits a response, then the
server looks to see if it has an entry for that URI in the same scope.
If it does it sleeps a short period of time (20-500ms), then posts the
response directly back to the client as a unicast datagram.
A response is a "Found" message containing the same requestID and URI
as the request, adding the URL, and optionally an expiry time and
description. The expiry time is a time_t value; UTC seconds since
1970-01-01-0000. The xsd:dateTime value would match were it not for the
ongoing cross-platform issues with binding the dateTime to specific
time zones.
</para>
<para>Negative responses, "no-match" responses, do not
generate network traffic. The network load does not therefore scale
with the number of servers on the network, but with the number of
clients using it, and then by the number of successful responses to
their requests.</para>
</sect2>
<sect2 id="extensibility">
<title>extensibility</title>
<para>There are different ways to extend this; The protocol could support new
request types, and have new responses. The content of requests and
responses may change too. How can we address this? The proposed
solution is XML schemas; if the schema of the request is not
recognised, then the server ignores the message. The schema of the
response must be bound to that of the request; you cannot change the
response schema without also changing the request schema.
A future iteration may also add an xsd:any section to the payload</para>
<para>
What about replacing the current payload with a full SOAP envelope?
It would let us add authentication via WS-Security, and do other things.
But in the absence of a standard for SOAP-over-multicast-datagrams, and
the size limitations of such datagrams, it doesn't seem immediately appealing.
One of the interesting challenges is what should recipients of a multicast
SOAP message do with mustUnderstand headers they don't understand.
The SOAP rules say 'fault' -but that means every recipient is going to
send a fault back -this is the wrong thing to do.
</para>
</sect2>
<sect2 id="implementation-issues">
<title>Implementation Issues</title>
<sect3 id="configuration">
<title>configuration</title>
<para>Where does the system get configured? It can be directly hooked
to the SOAP server. WS-Discovery aware endpoints should be able to provide
extra configuration information in their deployment metadata, which
for Axis implies the deployment descriptor. Web applications should
also be able to add or delete entries. This lets a Web Service
hide entries, but it also lets a local WS-Discovery server return references
to remote services, such as a distant UDDI service.</para>
</sect3>
<sect3 id="discovery-of-servers">
<title>discovery of WS-Discovery servers</title>
<para>Should WS-Discovery servers be discoverable in their own right, just as
SLP directory agents are? Yes, if you want to permit unicast
interrogation and management. No if you want to make it harder to find
system information and vulnerabilities. A WS-Discovery server may choose to
respond to requests to find the WS-Discovery service; this option could be user
configurable. The current service string to search for is "service:axis-discovery"
</para>
<para>
The response to such a request is a URL indicating the
UDP ports supported; in the absence of a widespread 'udp:' URL
schema, we choose to declare the use of this URL schema in our
responses. If a URL contains something such as
udp://192.168.4.4:1434 then it means that the machine at IP address
192.168.4.4 is responding to unicast datagrams on port 1434.
This is an extension of the SLP responses, which introduced tcp: urls,
URLS which should not be confused with the .NET remoting URLs, which
adopt the same tcp: prefix to mean .NET remoting connections exclusively.
This confusion should not have adverse effects -merely serves to demonstrate
why meaningful prefixes should be used, and the W3C addressing recommendations
(http://www.w3.org/Addressing/) used. </para>
</sect3>
<sect3 id="i18n">
<title>Internationalisation</title>
<para>The requests and responses must be in the UTF-8 encoding.
</para>
</sect3>
</sect2>
<sect2 id="limitations-and-risks">
<title>limitations and risks</title>
<para>Multicast IP does scale, but things get very chatty. The
protocol needs to minimise chattiness and collisions by having servers
not repeat responses, and by adding a random delay before responding.</para>
<para>Multicast IP does not work on ad-hoc WLANs; those wireless
networks without an access point. Some network stacks refuse to allow
applications to bind to a multicast address, though there are hints
this may just be a firmware defect. .</para>
<para>Could it be used to amplify a DoS attack? Yes, if someone spoofs
an IP address and asks for a popular service with a high TTL: all
implementations would respond. If servers could determine the # of
hops from the client, it could restrict responses to local systems
only. As we cannot do that, we can code our client to limit the TTL to
a maximum well below 255.</para>
<para>Could servers be subjected to a DoS attack? Not really. The
computational load of this is minor: an unmarshal of an XML document,
a document limited in size to 8192 bytes by the IP protocol itself, a
lookup of a hash table, and a generation of an XML response document.
A logging attack is possible if the server logs serious failures to
the file system; the log system should be configured to not save full
details to file, or (better) to use a rolling file system logger.</para>
<para>What about security? There is currently no security or authentication in
WS-Discovery; after you get an endpoint from it, you have to negotiate with the
endpoint to see if you trust it. The risk here is twofold. First, a
malicious client could issue may requests, generating server load.
Secondly, a malicious server could issue false responses, listing
endpoints that were invalid. This could deny clients service,
especially if the invalid endpoints were themselves malicious and
deliberately slow, acting as a tar-pit endpoint.</para>
<para>Security could be addressed with signing of messages and
responses, but as well as the size limits of datagrams, signing
introduces a need for authentication, which implies some
authentication and authorisation framework.
The obvious solutions would be XML-Signature and perhaps even
WS-Security, the latter needing a SOAP-esque payload first. </para>
</sect2>
</sect1>
</chapter>
</book>
1.1 xml-axis/addons/discovery/src/log4j.properties
Index: log4j.properties
===================================================================
log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
# Print the date in ISO 8601 format
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/client/Client.java
Index: Client.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.client;
import org.apache.axis.discovery.core.Const;
import org.apache.axis.discovery.core.DiscoveryException;
import org.apache.axis.discovery.core.DiscoveryMessage;
import org.apache.axis.discovery.core.MulticastTransceiver;
import org.apache.axis.discovery.core.Transceiver;
import org.apache.axis.discovery.core.XmlMarshaller;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* implementation of a client to Discovery. Creates a transport,
* sends requests out
* and handles responses. To get per-message notifications as they come in,
* subclass or implement a ResponseReceivedListener and point the Client at it.
* @see ResponseReceivedListener
*
*/
public class Client {
/**
* discovery transceiver for comms
*/
private Transceiver transceiver;
/**
* a single listener for responses; could be expanded to
* a add/remove listener pattern if someone really wanted.
*/
private ResponseReceivedListener listener;
/**
* logging
*/
private static Log log = LogFactory.getLog(Client.class);
/**
* create a client using multicast
*
*@throws IOException when things wont create
*/
public Client() throws IOException {
this(new MulticastTransceiver(Const.MBONE_ADDRESS,
0,
Const.MBONE_PORT,
new XmlMarshaller()));
}
/**
* create a client bound to whatever kind of transport is wanted.
* @param transport
*/
public Client(Transceiver transport) {
this.transceiver = transport;
}
/**
* find all the endpoints in a given ttl area, the timeout is the total
* weight time
*
*@param endpointUri what to look for
*@param ttl scope of request
*@param timeout time to wait for responses in milliseconds
*@param limit max number of responses
*@return a List of ResolveResponse entries, may be of size 0
*@exception IOException any old trouble
*/
public List findEndpoints(String endpointUri, int ttl, int timeout,
int limit)
throws IOException, DiscoveryException {
DiscoveryMessage request = new DiscoveryMessage(DiscoveryMessage.MESSAGE_REQUEST);
request.setUri(endpointUri);
request.setScope("");
List responses = new LinkedList();
transceiver.multicastMessage(request, ttl);
long now = System.currentTimeMillis();
long end = now + timeout;
long timeLeft;
int count = 0;
while ((timeLeft = end - now) > 0) {
DiscoveryMessage response = transceiver.receiveMessage(timeLeft);
if (response != null) {
responses.add(response);
log.debug("received " + response);
count++;
if (!messageReceived(response)) {
break;
}
//bail out when done
if (limit > 0 && count >= limit) {
break;
}
}
now = System.currentTimeMillis();
}
return responses;
}
/**
* callback method for subclasses to override if they
* dont want to wait for the timeout or limits to be reached
* before acting on incoming data, or want a way of breaking early.
* Default implementation forwards to ant ResponseReceivedListener
* set previously
* @param response received message
* @return true if we are to continue waiting for more responses
*/
public boolean messageReceived(DiscoveryMessage response) {
if (listener != null) {
return listener.messageReceived(response);
} else {
return true;
}
}
/**
* go from a list of responses to a list of endpoints
*
*@param responses List of DiscoveryMessage elements
*@return array of endpoints
*@todo resolve duplicates
*/
public String[] extractEndpointArray(List responses) {
String[] endpoints = new String[responses.size()];
int counter = 0;
Iterator i = responses.iterator();
while (i.hasNext()) {
DiscoveryMessage response = (DiscoveryMessage) i.next();
endpoints[counter++] = response.getUrl();
}
return endpoints;
}
/**
* set a listener to be used for notifications of events
* @param listener
*/
public void setListener(ResponseReceivedListener listener) {
this.listener = listener;
}
/**
* client entry point
*
*@param args URI
*@throws Exception
*/
public static void main(String args[]) throws Exception {
String uri = Const.DISCOVERY_SERVICE_URI;
if (args.length > 0) {
uri = args[0];
}
System.out.println("Searching for [" + uri + "]");
Client client = new Client();
List responses = client.findEndpoints(uri,
1,
Const.CLIENT_TIMEOUT,
0);
String[] endpoints = client.extractEndpointArray(responses);
System.out.println("Found " + endpoints.length + " endpoint(s)");
for (int i = 0; i < endpoints.length; i++) {
System.out.println(endpoints[i]);
}
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/client/ResponseReceivedListener.java
Index: ResponseReceivedListener.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.client;
import org.apache.axis.discovery.core.DiscoveryMessage;
/**
* listener interface for per-message callbacks
* when searching for multiple endpoints
*/
public interface ResponseReceivedListener {
/**
* callback when a message is received
* @param message the received message
* @return true if the loop is to continue
*/
boolean messageReceived(DiscoveryMessage message);
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/core/BroadcastTransceiver.java
Index: BroadcastTransceiver.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.core;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
/**
* a broadcast transceiver broadcasts to the LAN, but not
* over other lans. Intended for use on WLANs that cannot handle mcast.
*
*/
public class BroadcastTransceiver extends Transceiver {
/**
* our socket
*/
private DatagramSocket socket;
/**
* where to send ports to
*/
private int sendPortNumber;
/**
* where we receive things
*/
private int receivePortNumber;
/**
* our url
*/
private String url;
/**
* cache of our broadcast address
*/
private InetAddress broadcastAddress;
/**
* logging entry
*/
private static Log log = LogFactory.getLog(BroadcastTransceiver.class);
/**
* construct an incomplete transceiver
* @param marshaller marshalling algorithm
*/
public BroadcastTransceiver(Marshaller marshaller) {
super(marshaller);
}
/**
* construct a broadcast socket
* @param receivePortNumber port to listen on, 0 for no listen
* @param sendPortNumber port to send on
* @param marshaller marshalling algorithm
* @throws SocketException if things went wrong
*/
public BroadcastTransceiver(int receivePortNumber, int sendPortNumber,
Marshaller marshaller)
throws IOException {
super(marshaller);
bind(receivePortNumber,
sendPortNumber,
InetAddress.getByName("255.255.255.255"));
}
/**
* override point for binding
* @param receivePortNumber
* @param sendPortNumber
* @param address
* @throws IOException
*/
protected void bind(int receivePortNumber, int sendPortNumber,
InetAddress address)
throws IOException {
this.sendPortNumber = sendPortNumber;
this.receivePortNumber = receivePortNumber;
setSocket(createSocket(receivePortNumber));
if (receivePortNumber != 0) {
url = "udp://" + Utils.getLocalAddress(socket)
+ ":" + this.receivePortNumber;
} else {
url = "uri://offline";
}
setBroadcastAddress(address);
}
/**
* override point: create a new socket.
* @param receivePortNumber may be 0
* @return new socket
* @throws IOException
*/
protected DatagramSocket createSocket(int receivePortNumber)
throws IOException {
if (receivePortNumber != 0) {
return new DatagramSocket(receivePortNumber);
} else {
return new DatagramSocket();
}
}
public InetAddress getBroadcastAddress() {
return broadcastAddress;
}
protected void setBroadcastAddress(InetAddress broadcastAddress) {
this.broadcastAddress = broadcastAddress;
}
public int getReceivePortNumber() {
return receivePortNumber;
}
protected void setReceivePortNumber(int receivePortNumber) {
this.receivePortNumber = receivePortNumber;
}
public int getSendPortNumber() {
return sendPortNumber;
}
protected void setSendPortNumber(int sendPortNumber) {
this.sendPortNumber = sendPortNumber;
}
public DatagramSocket getSocket() {
return socket;
}
public void setSocket(DatagramSocket socket) {
this.socket = socket;
}
protected void setURL(String url) {
this.url = url;
}
/**
* wait for a packet.
* @param timeout time to wait in milliseconds; 0 means no wait
* @return packet received or null for timeout
* @throws IOException if there was trouble
*/
public DatagramPacket receive(long timeout) throws IOException {
getSocket().setSoTimeout((int) timeout);
byte buffer[] = new byte[Const.DATAGRAM_SIZE];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
try {
getSocket().receive(packet);
} catch (SocketTimeoutException e) {
return null;
}
return packet;
}
/**
* get a URL for receiving messages
* @return a url for messages. return something in the uri: schema
* for no real url.
*/
public String getReceiverURL() {
return url;
}
/**
* send a packet.
* @param packet what to send
* @throws IOException in case of emergency
*/
public void send(DatagramPacket packet) throws IOException {
getSocket().send(packet);
}
/**
* send a packet to our configured sender.
* @param packet what to send
* @param ttl time to live, which can be ignored
* @throws IOException in case of emergency
*/
public void multicast(DatagramPacket packet, int ttl) throws IOException {
packet.setPort(sendPortNumber);
packet.setAddress(broadcastAddress);
send(packet);
}
/**
* called at destroy time; use for any cleanup
*/
public void destroy() {
getSocket().close();
}
/**
* get the name of this transceiver
* @return a name string
*/
public String getName() {
return "Broadcast";
}
/**
* can this transceiver actually receive data?
* @return true if we have a receive port defined
*/
public boolean canReceive() {
return getReceivePortNumber() != 0;
}
/**
* probe for data being ready. as we cant tell,
* we alwys return true.
* @return true iff data is ready
*/
public boolean dataReady() {
return true;
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/core/Const.java
Index: Const.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.core;
/**
* This is where build time constants go
* @author Steve Loughran
*/
public class Const {
/**
* We are using the IANA SLP address, listening on a
* different port
* @todo maybe get a real address from IANA
*/
//IANA
public static final String MBONE_ADDRESS = "239.255.255.253";
/**
* port to listen to (20649). we dont use 5049 as
* endpoints may be using http on that port
*/
public static final int MBONE_PORT = 0x50A9;
/**
* do we list ourself
*/
public static final boolean AUTO_REGISTER_SELF = true;
/**
* what is our own uri; SLP style.
*/
public static final String DISCOVERY_SERVICE_URI = "service:axis-discovery";
/**
* spin delay on the server; longer means slower shutdown time
*/
public static final int SERVER_TIMEOUT = 1000;
/**
* default TTL for queries sent out. IANA say 255 for
* SLP, leaving it to the routers to sort it out. But I
* dont trust the routers to be so well configured.
*/
public static final int DEFAULT_TTL = 4;
/**
* frequency of resync to axis state
*/
public static final long AXIS_BINDER_RESYNC_INTERVAL = 1000;
/**
* time for client apps to wait for a response; recommended
*/
public static final int CLIENT_TIMEOUT = 2000;
/**
* what is the charset of the xml messages
*/
public static final String MESSAGE_CHARSET = "UTF-8";
/**
* how big can a datagram be
*/
public static final int DATAGRAM_SIZE = 8192;
/**
* how big can a datagram be for warnings
*/
public static final int DATAGRAM_WARN_SIZE = 1500;
/**
* default scope for registering stuff
*/
public static final String DEFAULT_SCOPE = "*";
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/core/DiscoveryException.java
Index: DiscoveryException.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.core;
/**
* used to swallow up some other exceptions, like the castor ones, that
* effectively expose too much implementation specifics.
*/
public class DiscoveryException extends Exception {
private Exception rootCause;
public DiscoveryException(String message) {
super(message);
}
public DiscoveryException() {
}
public DiscoveryException(Exception rootCause) {
this.rootCause = rootCause;
}
public DiscoveryException(String message, Exception rootCause) {
super(message);
this.rootCause = rootCause;
}
public Exception getRootCause() {
return rootCause;
}
public void setRootCause(Exception rootCause) {
this.rootCause = rootCause;
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/core/DiscoveryMessage.java
Index: DiscoveryMessage.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.core;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.Serializable;
import java.net.DatagramPacket;
import java.net.InetAddress;
/**
* messages that get sent over the wire all fit into this format different
* messages use different elements all: messageID, messageType, uri request:
* scope response: url, description
*
*/
public class DiscoveryMessage implements Serializable {
/**
* message identifier
*/
private int messageID;
/**
* message type
*/
private String messageType;
/**
* what were you looking for
*/
private String uri;
/**
* scope string; valid on requests only
*/
private String scope;
/**
* response URL; "" or null for no match responses only
*/
private String url;
/**
* end user readable UTF-8 text. responses only
*/
private String description = "";
/**
* addresss of sender
*/
private transient InetAddress sender;
/**
* port of sender
*/
private transient int senderPort;
/**
* counter of messages
*/
private static int idCounter = 1;
/**
* our log
*/
private static Log log = LogFactory.getLog(DiscoveryMessage.class);
/**
* Construct; give the message a new ID (can be changed) you have to know
* what type of message you want when you create it.
*
*@param messageType
*/
public DiscoveryMessage(String messageType) {
this.setMessageType(messageType);
createID();
}
/**
* empty ctor inits nothing
*/
public DiscoveryMessage() {
}
/**
* give a message an id
*/
public void createID() {
setMessageID(getID());
}
/**
* stringify
*
*@return
*/
public String toString() {
String response = getMessageType() + " #" + getMessageID() + " from "
+ (sender != null ? sender.getHostAddress() : "unknown")
+ ":" + getSenderPort() + " scope [" + scope + "]"
+ " for [" + getUri() + "]";
if (isType(MESSAGE_RESPONSE)) {
response += " = [" + getUrl() + "]"
+ "; " + getDescription();
}
return response;
}
/**
* test if a message matches a type
*
*@param type
*@return
*/
public boolean isType(String type) {
return getMessageType() != null && getMessageType().equals(type);
}
/**
* a request message
*/
public static final String MESSAGE_REQUEST = "Find";
/**
* a response message
*/
public static final String MESSAGE_RESPONSE = "Found";
/**
* a response message
*/
public static final String MESSAGE_ADVERTISMENT = "Advertisment";
/**
* synchronized access to a static ID counter.
*
*@return
*/
protected static synchronized int getID() {
return idCounter++;
}
/**
* create a new response message. copy over sender info
*
*@return Description of the Return Value
*/
public DiscoveryMessage createResponse() {
DiscoveryMessage response = new DiscoveryMessage(MESSAGE_RESPONSE);
response.setMessageID(getMessageID());
response.setUri(getUri());
response.setSender(getSender());
response.setSenderPort(getSenderPort());
return response;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getMessageID() {
return messageID;
}
public void setMessageID(int messageID) {
this.messageID = messageID;
}
public String getMessageType() {
return messageType;
}
public void setMessageType(String messageType) {
this.messageType = messageType;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public InetAddress getSender() {
return sender;
}
public void setSender(InetAddress sender) {
this.sender = sender;
}
public int getSenderPort() {
return senderPort;
}
public void setSenderPort(int senderPort) {
this.senderPort = senderPort;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
/**
* test for an object being valid. Rules about optional parts for different
* message types are implemented here.
* @return true iff we are happy
*/
public boolean isValid() {
boolean valid;
valid = messageID != 0;
// non empty uri
valid &= uri != null && uri.length() != 0;
valid &= scope != null;
if (isType(MESSAGE_RESPONSE)) {
valid &= url != null && url.length() != 0;
} else if (isType(MESSAGE_REQUEST)) {
//any checks here?
} else {
//an unknown type means it aint valid
valid = false;
}
return valid;
}
/**
* get the return address from a packet and save it to a message
*
* @param packet received packet
*/
public void extractReturnAddress(DatagramPacket packet) {
setSender(packet.getAddress());
setSenderPort(packet.getPort());
}
/**
* address the packet to the sender for return packets
* @param packet
*/
public void addressToSender(DatagramPacket packet) {
packet.setAddress(sender);
packet.setPort(senderPort);
}
/**
* equality test validates core fields but not transient tat like sender
* @param o
* @return true if the message is deemed equal
*/
public boolean equals(Object o) {
if (!(o instanceof DiscoveryMessage)) {
return false;
}
DiscoveryMessage message = (DiscoveryMessage) o;
if (messageID != message.messageID) {
return false;
}
if (description == null
? message.description != null
: !description.equals(message.description)) {
return false;
}
if (messageType == null
? message.messageType != null
: !messageType.equals(message.messageType)) {
return false;
}
if (scope == null
? message.scope != null
: !scope.equals(message.scope)) {
return false;
}
if (uri == null
? message.uri != null
: !uri.equals(message.uri)) {
return false;
}
if (url == null
? message.url != null
: !url.equals(message.url)) {
return false;
}
return true;
}
/**
* use the mesage ID as a hash chode
* @return
*/
public int hashCode() {
return messageID;
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/core/LoggingTransceiver.java
Index: LoggingTransceiver.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.core;
import java.io.IOException;
import java.net.DatagramPacket;
/**
* this is a delegating transceiver that logs various thingies
*/
public class LoggingTransceiver extends Transceiver {
private Transceiver transceiver;
private int failures;
private int sends;
private int multicasts;
private int receipts;
public LoggingTransceiver(Transceiver transceiver) {
super(transceiver.getMarshaller());
this.transceiver = transceiver;
}
public boolean canReceive() {
return transceiver.canReceive();
}
public boolean dataReady() {
return transceiver.dataReady();
}
public void destroy() {
transceiver.destroy();
}
public void fillResponsePacket(DatagramPacket request,
DatagramPacket response) {
transceiver.fillResponsePacket(request, response);
}
public String getName() {
return transceiver.getName();
}
public String getReceiverURL() {
return transceiver.getReceiverURL();
}
public void multicast(DatagramPacket packet, int ttl) throws IOException {
multicasts++;
try {
transceiver.multicast(packet, ttl);
} catch (IOException e) {
handle(e);
} catch (RuntimeException e) {
handle(e);
}
}
public void multicastMessage(DiscoveryMessage message, int ttl)
throws IOException, DiscoveryException {
transceiver.multicastMessage(message, ttl);
}
public DatagramPacket receive(long timeout) throws IOException {
DatagramPacket packet = null;
try {
packet = transceiver.receive(timeout);
if (packet != null) {
receipts++;
}
} catch (IOException e) {
handle(e);
} catch (RuntimeException e) {
handle(e);
}
return packet;
}
public void send(DatagramPacket packet) throws IOException {
try {
transceiver.send(packet);
sends++;
} catch (IOException e) {
handle(e);
} catch (RuntimeException e) {
handle(e);
}
}
private synchronized void handle(RuntimeException e) {
failures++;
throw e;
}
private synchronized void handle(IOException e) throws IOException {
failures++;
throw e;
}
public DiscoveryMessage receiveMessage(long timeout)
throws IOException, DiscoveryException {
return transceiver.receiveMessage(timeout);
}
public void sendMessage(DiscoveryMessage message)
throws IOException, DiscoveryException {
transceiver.sendMessage(message);
}
public int getFailures() {
return failures;
}
public int getMulticasts() {
return multicasts;
}
public int getReceipts() {
return receipts;
}
public int getSends() {
return sends;
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/core/LoopbackTransceiver.java
Index: LoopbackTransceiver.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.core;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.net.DatagramPacket;
/**
* loopback for testing and the like
*/
public class LoopbackTransceiver extends Transceiver {
public LoopbackTransceiver(Marshaller marshaller) {
super(marshaller);
}
private MessageQueue queue = new MessageQueue();
/**
* logging entry
*/
private static Log log = LogFactory.getLog(LoopbackTransceiver.class);
/**
* wait for a packet.
* @param timeout time to wait in milliseconds; 0 means no wait
* @return packet received or null for timeout
* @throws IOException if there was trouble
*/
public DatagramPacket receive(long timeout) throws IOException {
return queue.getNextPacketBlocking(timeout);
}
/**
* send a packet.
* @param packet what to send
* @throws IOException in case of emergency
*/
public void send(DatagramPacket packet) throws IOException {
queue.add(packet);
}
/**
* send a packet to our configured sender.
* @param packet what to send
* @param ttl time to live, which can be ignored
* @throws IOException in case of emergency
*/
public void multicast(DatagramPacket packet, int ttl) throws IOException {
send(packet);
}
/**
* probe for data being ready. optional implementation
* @return true iff data is ready
*/
public boolean dataReady() {
return !queue.isEmpty();
}
/**
* get a URL for receiving messages
* @return a url for messages. return something in the uri: schema
* for no real url.
*/
public String getReceiverURL() {
return "uri:loopback";
}
/**
* get the name of this transceiver
* @return a name string
*/
public String getName() {
return "Loopback";
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/core/Marshaller.java
Index: Marshaller.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.core;
import java.io.IOException;
import java.net.DatagramPacket;
/**
* marshallers marshall and unmarshall messages to datagrams.
* having this code factored out lets one plug in new wire formats.
*/
public abstract class Marshaller {
/**
* turn a received datagram into a packet
* @param packet
* @return a new message
* @throws IOException IO trouble is permitted
* @throws DiscoveryException if anything went wrong
*/
public abstract DiscoveryMessage unmarshall(DatagramPacket packet)
throws IOException, DiscoveryException;
/**
* create a datagram packet from the message. Optional fields
* are omitted if missing (description, url).
* @return a ready-to-go datagram
* @throws IOException IO trouble is permitted
* @throws DiscoveryException if anything went wrong
*/
public abstract DatagramPacket marshall(DiscoveryMessage message)
throws IOException, DiscoveryException;
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/core/MessageQueue.java
Index: MessageQueue.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.core;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.net.DatagramPacket;
import java.util.ArrayList;
import java.util.List;
/**
* this queues up the messages as received; senders can use this
* queue for asyc transports
*/
public class MessageQueue {
/**
* our real queue
*/
private List queue = new ArrayList();
/**
* logging entry
*/
private static Log log = LogFactory.getLog(MessageQueue.class);
/**
* non blocking emptiness test
* @return true iff the queue is empty
*/
public boolean isEmpty() {
return queue.isEmpty();
}
/**
* add a packet to the queue; notify any waiting objects,
* Synchronized.
* @param packet packet to add
*/
public synchronized void add(DatagramPacket packet) {
queue.add(packet);
synchronized (queue) {
queue.notify();
}
}
/**
* nonblocking query for the next packet
* @return next packet or null
*/
public synchronized DatagramPacket getNextPacket() {
if (isEmpty()) {
return null;
}
DatagramPacket packet = (DatagramPacket) queue.get(0);
queue.remove(0);
return packet;
}
/**
* block calling thread till there is more data.
* @param timeout max time to wait in milliseconds
* @throws InterruptedException
*/
public void blockForMoreData(long timeout) throws InterruptedException {
synchronized (queue) {
log.debug("blocking for " + timeout);
queue.wait(timeout);
}
}
/**
* wait for a packet
* @param timeout max time to wait in milliseconds
* @return packet or null if a timeout occurred
*/
public DatagramPacket getNextPacketBlocking(long timeout) {
DatagramPacket packet = null;
packet = getNextPacket();
try {
if (packet == null) {
blockForMoreData(timeout);
packet = getNextPacket();
if (packet == null) {
log.debug("timeout");
}
}
} catch (InterruptedException e) {
//timeout
log.debug("interrupted");
packet = null;
}
return packet;
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/core/MulticastTransceiver.java
Index: MulticastTransceiver.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.core;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
/**
* This class uses multicasting to send and receive requests
*/
public class MulticastTransceiver extends BroadcastTransceiver {
/**
* logging entry
*/
private static Log log = LogFactory.getLog(MulticastTransceiver.class);
/**
* get access to the multicast socket
* @return
*/
public MulticastSocket getMulticastSocket() {
return (MulticastSocket) getSocket();
}
/**
* create a new multicast transceiver.
* @param address multicast address
* @param receivePortNumber receive port, or 0 for dont bind
* @param sendPortNumber send port
* @throws IOException if anything went wrong, including missing lan
*/
public MulticastTransceiver(String address,
int receivePortNumber,
int sendPortNumber,
Marshaller marshaller)
throws IOException {
super(marshaller);
InetAddress multicastAddress = InetAddress.getByName(address);
bind(receivePortNumber,
sendPortNumber,
multicastAddress.getByName("255.255.255.255"));
try {
getMulticastSocket().joinGroup(multicastAddress);
} catch (IOException e) {
//log with a hint then rethrow
log.error("Unable to join group " + address
+ "; this may mean the network is absent", e);
throw e;
}
log.info("joined mcast " + address + ":" + sendPortNumber
+ "; listening on " + receivePortNumber);
}
/**
* get the name of this transceiver
* @return a name string
*/
public String getName() {
return "Multicast";
}
/**
* send a packet to our configured sender.
* @param packet what to send
* @param ttl time to live, which can be ignored
* @throws IOException in case of emergency
*/
public void multicast(DatagramPacket packet, int ttl) throws IOException {
getMulticastSocket().setTimeToLive(ttl);
super.multicast(packet, ttl);
}
/**
* create a new multicast socket.
* @param receivePortNumber
* @return
* @throws IOException
*/
protected DatagramSocket createSocket(int receivePortNumber)
throws IOException {
if (receivePortNumber != 0) {
return new MulticastSocket(receivePortNumber);
} else {
return new MulticastSocket();
}
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/core/SubnetPollTransceiver.java
Index: SubnetPollTransceiver.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.core;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
/**
* this is a brute force poll-the-subnet discovery algorithm.
* Bad form as the discovery traffic is huge. So why have it? simple
* Multicast and Broadcast does not work with WinXP in ad-hoc mode. This
* transceiver finds services in an ad-hoc space.
* Do not use this over a big network as people will get upset :)
*/
public class SubnetPollTransceiver extends BroadcastTransceiver {
private long startAddress;
private int range;
private int intervalSize;
private int intervalPause;
/**
* logging entry
*/
private static Log log = LogFactory.getLog(SubnetPollTransceiver.class);
/**
* create the transceiver with subnet parameters
* @param marshaller
* @param portNumber
* @param startAddress
* @param range
* @param intervalSize
* @param intervalPause
* @throws IOException
*/
public SubnetPollTransceiver(Marshaller marshaller, int portNumber,
long startAddress, int range,
int intervalSize, int intervalPause
) throws IOException {
super(portNumber, portNumber, marshaller);
this.intervalPause = intervalPause;
this.intervalSize = intervalSize;
this.range = range;
this.startAddress = startAddress;
}
public void multicast(DatagramPacket packet, int ttl) throws IOException {
packet.setPort(getSendPortNumber());
byte[] addr = new byte[4];
int interval = 0;
//loop over all the addresses in this address space
for (long address = startAddress; address < startAddress + range; address++) {
Utils.makeAddressWord(address, addr);
InetAddress ipv4Addr = InetAddress.getByAddress(addr);
packet.setAddress(ipv4Addr);
if (log.isDebugEnabled()) {
log.debug("sending to " + ipv4Addr);
}
send(packet);
//check for a timed pause
if (intervalSize > 0 && ++interval > intervalSize) {
//reset the counter
interval = 0;
//and sleep
try {
Thread.sleep(intervalPause);
} catch (InterruptedException swallowed) {
;
}
}
}
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/core/Transceiver.java
Index: Transceiver.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.core;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.net.DatagramPacket;
/**
* abstract base class for transceivers - classes that send and receive
* content
*/
public abstract class Transceiver {
/**
* logging entry
*/
private static Log log = LogFactory.getLog(Transceiver.class);
/**
* our marshalling algorithm
*/
private Marshaller marshaller;
/**
* construct a transceiver
* @param marshaller algorithm to marshall with
*/
public Transceiver(Marshaller marshaller) {
this.marshaller = marshaller;
}
/**
* send a packet.
* @param packet what to send
* @throws IOException in case of emergency
*/
public abstract void send(DatagramPacket packet) throws IOException;
/**
* send a packet to our configured sender.
* @param packet what to send
* @param ttl time to live, which can be ignored
* @throws IOException in case of emergency
*/
public abstract void multicast(DatagramPacket packet, int ttl)
throws IOException;
/**
* wait for a packet.
* @param timeout time to wait in milliseconds; 0 means no wait
* @return packet received or null for timeout
* @throws IOException if there was trouble
*/
public abstract DatagramPacket receive(long timeout) throws IOException;
/**
* probe for data being ready.
* @return true iff data is ready
*/
public abstract boolean dataReady();
/**
* send a message
* @param message message to send
* @throws IOException
*/
public void sendMessage(DiscoveryMessage message)
throws IOException, DiscoveryException {
DatagramPacket packet = marshaller.marshall(message);
message.addressToSender(packet);
send(packet);
}
/**
* multicast a message
* @param message message to send
* @throws IOException
*/
public void multicastMessage(DiscoveryMessage message, int ttl)
throws IOException, DiscoveryException {
DatagramPacket packet = marshaller.marshall(message);
multicast(packet, ttl);
}
/**
* receive a message
* @param timeout how long to wait
* @return null for timeout
* @throws IOException when there is trouble
*/
public DiscoveryMessage receiveMessage(long timeout)
throws IOException, DiscoveryException {
DatagramPacket packet = receive(timeout);
if (packet == null) {
return null;
} else {
if (log.isDebugEnabled()) {
String messageText = Utils.stringFromDatagram(packet,
Const.MESSAGE_CHARSET);
log.debug("Received [" + messageText + "]");
}
return marshaller.unmarshall(packet);
}
}
/**
* get a URL for receiving messages
* @return a url for messages. return something in the uri: schema
* for no real url.
*/
public abstract String getReceiverURL();
/**
* set a response packet to the sender info that came in with the request;
* the response can then be sent to the sender to arrive at the originating
* port
*
*@param request received
*@param response response packet to edit
*/
public void fillResponsePacket(DatagramPacket request,
DatagramPacket response) {
response.setAddress(request.getAddress());
response.setPort(request.getPort());
}
/**
* called at destroy time; use for any cleanup
*/
public void destroy() {
}
/**
* get the name of this transceiver
* @return a name string
*/
public abstract String getName();
/**
* can this transceiver actually receive data?
* @return
*/
public boolean canReceive() {
return true;
}
public Marshaller getMarshaller() {
return marshaller;
}
public void setMarshaller(Marshaller marshaller) {
this.marshaller = marshaller;
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/core/Utils.java
Index: Utils.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.core;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* general utility stuff
*/
public final class Utils {
private Utils() {
}
/**
* what this the local address of this system as a dotted string. this may
* just be 127.0.0.1 if nothing else
*
*@return host ip addr
*/
public static String getLocalAddress(DatagramSocket socket) {
String hostaddr;
InetAddress address = socket.getLocalAddress();
hostaddr = address.getHostAddress();
//looks like the system always thinks we are listening on
//all ports, even though that is not necessarily true.
if ("0.0.0.0".equals(hostaddr)) {
try {
address = InetAddress.getLocalHost();
hostaddr = address.getHostAddress();
} catch (UnknownHostException noIpAddrException) {
//bail out here
hostaddr = "127.0.0.1";
}
}
return hostaddr;
}
public static long getLocalAddressValue() {
long addr;
try {
InetAddress address = InetAddress.getLocalHost();
byte[] byteval = address.getAddress();
addr = (((long) byteval[0]) << 24) | (byteval[1] << 16)
| (byteval[2] << 8) | (byteval[3]);
} catch (UnknownHostException e) {
addr = (long) 0x7f000001;
}
return addr;
}
public static String toDotAddressString(long address) {
byte[] bytes = makeAddressWord(address);
StringBuffer buffer = new StringBuffer(5 * 3);
buffer.append(bytes[0]);
buffer.append('.');
buffer.append(bytes[1]);
buffer.append('.');
buffer.append(bytes[2]);
buffer.append('.');
buffer.append(bytes[3]);
return new String(buffer);
}
/**
* get a string from a datagram
* @param packet
* @param charset to use
* @return datagram string
* @throws IOException if things go awry
*/
public static String stringFromDatagram(DatagramPacket packet, String charset)
throws IOException {
ByteArrayInputStream bin = new ByteArrayInputStream(packet.getData());
InputStreamReader reader = null;
StringBuffer result = new StringBuffer();
int limit = packet.getLength();
int count = 0;
try {
reader = new InputStreamReader(bin, charset);
int c;
//spin till finished, we got a 0 byte (overshoot) or we
//could not read any more.
while ((c = reader.read()) != -1 && c != 0 && count < limit) {
char read = (char) c;
result.append(read);
count++;
//handle UTF8 & UTF16 encoding by skipping more bytes.
if (c >= 256) {
count++;
}
}
} finally {
try {
reader.close();
} catch (IOException swallowed) {
;
}
}
return new String(result);
}
/**
* get a word from an address
* @param address
* @param addr
*/
public static void makeAddressWord(long address, byte[] addr) {
addr[0] = (byte) ((address & 0xff000000) >> 24);
addr[1] = (byte) ((address & 0x00ff0000) >> 16);
addr[2] = (byte) ((address & 0x0000ff00) >> 8);
addr[3] = (byte) (address & 0x000000ff);
}
public static byte[] makeAddressWord(long address) {
byte[] addr = new byte[4];
makeAddressWord(address, addr);
return addr;
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/core/XmlMarshaller.java
Index: XmlMarshaller.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.core;
import org.apache.axis.discovery.xml.Discovery;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.ValidationException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.DatagramPacket;
/**
* this class does the marshalling to
* and from the xml representation. It is the only place that castor stuff
* should make an appearance
*/
public class XmlMarshaller extends Marshaller {
/**
* our log
*/
private static Log log = LogFactory.getLog(XmlMarshaller.class);
/**
* turn a received datagram into a packet
* @param packet
* @return a new message
* @throws IOException IO trouble is permitted
* @throws DiscoveryException if anything went wrong
*/
public DiscoveryMessage unmarshall(DatagramPacket packet)
throws IOException, DiscoveryException {
DiscoveryMessage message = new DiscoveryMessage();
String xml = Utils.stringFromDatagram(packet, Const.MESSAGE_CHARSET);
unmarshall(new StringReader(xml), message);
message.extractReturnAddress(packet);
return message;
}
/**
* extract message info from a reader.
* @param reader
*/
private void unmarshall(Reader reader, DiscoveryMessage dest)
throws DiscoveryException {
Discovery message;
try {
message = Discovery.unmarshal(reader);
} catch (MarshalException e) {
log.debug("Caught Marshalling Exception while unmarshalling", e);
throw new DiscoveryException(e);
} catch (ValidationException e) {
log.debug("Caught Validation Exception while marshalling", e);
throw new DiscoveryException(e);
}
dest.setMessageType(message.getType());
dest.setMessageID(message.getId());
dest.setUri(message.getUri());
dest.setUrl(message.getUrl());
dest.setScope(message.getScope());
dest.setDescription(message.getDescription());
if (!dest.isValid()) {
throw new DiscoveryException("Message is not valid");
}
}
/**
* create a datagram packet from the message. Optional fields
* are omitted if missing (description, url).
* @return a ready-to-go datagram
* @throws IOException IO trouble is permitted
* @throws DiscoveryException if anything went wrong
*/
public DatagramPacket marshall(DiscoveryMessage message)
throws IOException, DiscoveryException {
ByteArrayOutputStream byteData = new ByteArrayOutputStream();
OutputStreamWriter writer = null;
try {
writer = new OutputStreamWriter(byteData,
Const.MESSAGE_CHARSET);
marshall(message, writer);
writer.flush();
writer.close();
} catch (UnsupportedEncodingException e) {
throw new DiscoveryException(e);
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException swallowed) {
;
}
}
}
byte rawdata[] = byteData.toByteArray();
//check and warn for larger packets
if (rawdata.length > Const.DATAGRAM_WARN_SIZE) {
log.warn("message size " + rawdata.length
+ "is over warning size " + Const.DATAGRAM_WARN_SIZE);
}
DatagramPacket packet = new DatagramPacket(rawdata, byteData.size());
return packet;
}
/**
* marshall this to a writer
* @param out
*/
protected void marshall(DiscoveryMessage src, Writer out)
throws DiscoveryException {
Discovery xmlMessage = new Discovery();
xmlMessage.setId(src.getMessageID());
xmlMessage.setType(src.getMessageType());
xmlMessage.setScope(src.getScope());
xmlMessage.setUri(src.getUri());
if (src.getUrl() != null) {
xmlMessage.setUrl(src.getUrl());
}
if (src.getDescription() != null) {
xmlMessage.setDescription(src.getDescription());
}
try {
xmlMessage.marshal(out);
} catch (MarshalException e) {
log.debug("Caught Marshalling Exception while marshalling", e);
throw new DiscoveryException(e);
} catch (ValidationException e) {
log.debug("Caught Validation Exception while marshalling", e);
throw new DiscoveryException(e);
}
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/server/AxisBinder.java
Index: AxisBinder.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.server;
import org.apache.axis.AxisEngine;
import org.apache.axis.ConfigurationException;
import org.apache.axis.description.ServiceDesc;
import org.apache.axis.discovery.core.Const;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.Iterator;
/**
* class to bind against Axis
*
*/
public class AxisBinder {
/**
* base url of this web service
*/
private String baseURL;
/**
* the axis engin we are bound to
*/
private AxisEngine engine;
/**
* the uri store
*/
private UriStore store;
/**
* when did we last sync up
*/
private long lastSync = 0;
/**
* sync interval
*/
private long interval = Const.AXIS_BINDER_RESYNC_INTERVAL;
/**
* the log
*/
private static Log log = LogFactory.getLog(AxisBinder.class);
/**
* what is the scope for services unless they (somehow) say otherwise
*/
private static String defaultScope = "*";
/**
* Constructor for the AxisBinder object
*/
public AxisBinder() {
}
/**
* create a binding
*
*@param baseURL
*@param engine
*@param store
*@param interval
*@return Description of the Return Value
*/
public boolean bind(String baseURL, AxisEngine engine, UriStore store, long interval) {
this.baseURL = baseURL;
if (!baseURL.endsWith("/")) {
baseURL += "/";
}
this.engine = engine;
this.store = store;
this.interval = interval;
resync();
return true;
}
/**
* update the store with the engine settings;
*
* @return true iff a refresh went through
*/
public synchronized boolean resync() {
long now = System.currentTimeMillis();
if (lastSync + interval > now) {
return false;
}
Iterator i = null;
try {
i = engine.getConfig().getDeployedServices();
} catch (ConfigurationException e) {
log.fatal("getting deployed axis services", e);
return false;
}
store.markAllEntries();
while (i.hasNext()) {
ServiceEntry entry = new ServiceEntry();
ServiceDesc service = (ServiceDesc) i.next();
String name = service.getName();
//service.getEndpointURL();
String uri = service.getDefaultNamespace();
if (uri == null) {
uri = "service:" + name;
}
entry.setUrl(baseURL + "/services/" + name);
entry.setUri(uri);
entry.setMarker(false);
entry.setStaticEntry(false);
entry.setDescription("Apache Axis Endpoint");
entry.setScope(defaultScope);
store.addServiceEntry(entry);
}
store.deleteAllMarkedNonStaticEntries();
return true;
}
/**
* what is the current scope?
* @return
*/
public static String getDefaultScope() {
return defaultScope;
}
/**
* update the scope of services
* @param defaultScope new scope
*/
public static void setDefaultScope(String defaultScope) {
AxisBinder.defaultScope = defaultScope;
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/server/DiscoveryListener.java
Index: DiscoveryListener.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.server;
import org.apache.axis.discovery.core.Const;
import org.apache.axis.discovery.core.DiscoveryException;
import org.apache.axis.discovery.core.DiscoveryMessage;
import org.apache.axis.discovery.core.Transceiver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
/**
* this class implements the listener; has a few places to override if you feel
* like it. Listening can be done in a seperate thread, if that is your wont
*
*@author steve loughran
*@created August 30, 2002
*/
public class DiscoveryListener implements Runnable {
/**
* cached transceiver
*/
private Transceiver transceiver;
/**
* map of uris to urls
*/
private UriStore map;
/**
* our log
*/
private static Log log = LogFactory.getLog(DiscoveryListener.class);
/**
* a do-not-cache key used to spin the listener
*/
private volatile boolean timeToDie = false;
/**
* axis binder
*/
private AxisBinder axisBinder;
/**
* creat w/ map and transport
*
*@param map
*@param transceiver
*/
public DiscoveryListener(UriStore map, Transceiver transceiver) {
this.map = map;
this.transceiver = transceiver;
}
/**
* accessor
*
*@return current transport
*/
public Transceiver getTransceiver() {
return transceiver;
}
/**
*@return
*/
public UriStore getMap() {
return map;
}
/**
* Wake up, time to die. Set this to stop the listener next iteration. An
* alternate approach would be to send a packet to the listener, restrict
* it to local machine for security.
*/
public void setTimeToDie() {
timeToDie = true;
}
/**
* Gets the axisBinder attribute of the DiscoveryListener object
*
*@return The axisBinder value
*/
public AxisBinder getAxisBinder() {
return axisBinder;
}
/**
* Sets the axisBinder attribute of the DiscoveryListener object
*
*@param axisBinder The new axisBinder value
*/
public void setAxisBinder(AxisBinder axisBinder) {
this.axisBinder = axisBinder;
}
/**
* start the thread running
*
*@param daemon Description of the Parameter
*/
public void start(boolean daemon) {
Thread thread = new Thread(this, "DiscoveryListener");
thread.setDaemon(daemon);
thread.start();
}
/**
* thread callback. This stuff is running in a different thread from the
* rest
*/
public void run() {
log.info("starting listener loop");
while (!timeToDie) {
try {
DiscoveryMessage request = transceiver.receiveMessage(Const.SERVER_TIMEOUT);
//resync our bindings;
//and not before.
if (axisBinder != null) {
axisBinder.resync();
}
//check for a null request
if (request == null) {
continue;
}
//check it is for a type we want
if (!request.isType(DiscoveryMessage.MESSAGE_REQUEST)) {
log.info("ignoring message of type " + request);
continue;
}
//now handle the message
DiscoveryMessage responses[] = processRequest(request);
for (int i = 0; i < responses.length; i++) {
transceiver.sendMessage(responses[i]);
}
} catch (IOException e) {
log.error("processing a request", e);
} catch (DiscoveryException e) {
log.error("processing a request", e);
}
}
destroy();
}
private void destroy() {
transceiver.destroy();
}
/**
* subclassable handler of request to response processing
*
*@param request
*@return
*/
public DiscoveryMessage[] processRequest(DiscoveryMessage request) {
logRequest(request);
DiscoveryMessage[] responses = map.processRequest(request);
logResponses(responses);
return responses;
}
/**
* log a request
*
*@param request Description of the Parameter
*/
public void logRequest(DiscoveryMessage request) {
log.info("received " + request);
}
/**
* log a response
*
*@param responses
*/
public void logResponses(DiscoveryMessage[] responses) {
for (int i = 0; i < responses.length; i++) {
log.info("response =" + responses[i]);
}
if (responses.length == 0) {
log.info("no match");
}
}
/**
* stop us
*/
public void stop() {
setTimeToDie();
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/server/DiscoveryServer.java
Index: DiscoveryServer.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.server;
import org.apache.axis.discovery.core.Const;
import org.apache.axis.discovery.core.LoggingTransceiver;
import org.apache.axis.discovery.core.MulticastTransceiver;
import org.apache.axis.discovery.core.Transceiver;
import org.apache.axis.discovery.core.XmlMarshaller;
import org.apache.axis.discovery.server.management.ServerMBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
/**
* This is a discovery server: a listener, a transport and a uristore to map uris to
* urls
* @author steve loughran
*/
public class DiscoveryServer implements ServerMBean {
/**
* a listener
*/
private DiscoveryListener listener;
/**
* logging
*/
private LoggingTransceiver transceiver;
/**
* Description of the Field
*/
private UriStore map;
/**
* construct a server instance
* @param transceiver existing transceiver
* @param registerSelf flag set to true if we want to self register
* @exception IOException trouble with networking
*/
public DiscoveryServer(Transceiver transceiver, boolean registerSelf) throws IOException {
map = new UriStore();
setTransceiver(transceiver);
if (registerSelf) {
map.registerSelf(transceiver.getReceiverURL());
}
listener = new DiscoveryListener(map, transceiver);
}
/**
* construct a server instance using the default port and address values
* and the xml marshaller
* @exception IOException trouble with networking
*/
public DiscoveryServer() throws IOException {
this(new MulticastTransceiver(Const.MBONE_ADDRESS,
Const.MBONE_PORT,
Const.MBONE_PORT,
new XmlMarshaller()),
Const.AUTO_REGISTER_SELF);
}
/**
* make sure we stop
*
*@exception Throwable Description of the Exception
*/
protected void finalize() throws Throwable {
stop();
}
/**
* start listening in a separate thread
*/
public void startInNewThread() {
listener.start(false);
}
/**
* stop listening
*/
public void startInThisThread() {
listener.run();
}
/**
* stop listening, if we are
*/
public void stop() {
if (listener != null) {
listener.stop();
} else {
transceiver.destroy();
}
}
/**
* set the transceiver, wrapping it in a logger
* @param transceiver
*/
public void setTransceiver(Transceiver transceiver) {
this.transceiver = new LoggingTransceiver(transceiver);
}
/**
* logging transceivers are assigned without wrapping
* @param transceiver
*/
public void setTransceiver(LoggingTransceiver transceiver) {
this.transceiver = transceiver;
}
/**
* get access to the uri store
* @return
*/
public UriStore getMap() {
return map;
}
/**
* set access to the URI store
* @param map
*/
public void setMap(UriStore map) {
this.map = map;
}
/**
* get the current listener
*
*@return a listener
*/
public DiscoveryListener getListener() {
return listener;
}
/**
* get the current transport
*
*@return the transport
*/
public LoggingTransceiver getTransceiver() {
return transceiver;
}
/**
* get our uri map
*
*@return the store
*/
public UriStore getStore() {
return map;
}
/**
* string form of the multicast address
*
*@return a dotted ip address
*/
public String getURL() {
return getTransceiver().getReceiverURL();
}
/**
* how many sent
*
*@return number >=0
*/
public Integer getMessagesSent() {
return new Integer(getTransceiver().getSends());
}
/**
* how many received (inc failures)
*
*@return number>=0
*/
public Integer getMessagesReceived() {
return new Integer(getTransceiver().getReceipts());
}
/**
* how many failures received
*
*@return number>=0
*/
public Integer getFailures() {
return new Integer(getTransceiver().getFailures());
}
/**
* set a new listener
* @param listener listener
*/
public void setListener(DiscoveryListener listener) {
this.listener = listener;
}
/**
* entry point for demos
*
*@param args
*@throws IOException
*/
public static void main(String args[]) throws IOException {
Log log = LogFactory.getLog(DiscoveryServer.class);
log.info("Starting Discovery server");
DiscoveryServer server = new DiscoveryServer();
if (args.length > 0) {
Properties props = new Properties();
log.info("Loading properties file " + args[0]);
props.load(new FileInputStream(args[0]));
server.getStore().registerProperties(props);
}
server.startInThisThread();
log.info("Stopping Discovery server");
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/server/ServiceEntry.java
Index: ServiceEntry.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.server;
import org.apache.axis.discovery.core.Const;
import org.apache.axis.discovery.core.DiscoveryMessage;
import org.apache.axis.discovery.server.management.ServiceEntryMBean;
import java.io.Serializable;
/**
* this is what is put in the UriStore, description and stats for a service
* some of the fields here are for the store.
* @author steve loughran
*/
public class ServiceEntry
implements Serializable, ServiceEntryMBean {
/**
* URI of service
*/
private String uri;
/**
* URL of service
*/
private String url;
/**
* scope of queries
*/
private String scope;
/**
* description
*/
private String description;
/**
* number of times an entry has been hit
*/
private int hitCount = 0;
/**
* is a service static, that is the axis autoregistrar
* should leave it alone.
*/
private boolean staticEntry = true;
/**
* any extra store/binder data. used as marker when purging the store
*
*/
private boolean marker = false;
/**
* an empty entry
*/
public ServiceEntry() {
}
/**
* a full entry
*
*@param uri uri to use as the key
*@param url url to return
*@param scope scope entry
*@param description description
*/
public ServiceEntry(String uri, String url,
String scope, String description) {
this.setUri(uri);
this.setUrl(url);
this.setScope(scope);
this.setDescription(description);
}
/**
* Constructor for the ServiceEntry object
*
*@param uri uri to use as the key
*@param url url to return
*/
public ServiceEntry(String uri, String url) {
this.setUri(uri);
this.setUrl(url);
setScope(Const.DEFAULT_SCOPE);
setDescription("");
}
/**
* hashcode comes from the URL
*
*@return
*/
public int hashCode() {
return getUrl().hashCode();
}
/**
* equality is based on URI and url
*
*@param o
*@return true of URL and URL equality
*/
public boolean equals(Object o) {
ServiceEntry that = ((ServiceEntry) o);
return this.getUri().equals(that.getUri())
&& this.getUrl().equals(that.getUrl());
}
/**
* test for a complete match across all fields
*
*@param that object to test against
*@return
*/
public boolean matches(ServiceEntry that) {
return this.equals(that)
&& this.getDescription().equals(that.getDescription())
&& this.getScope().equals(that.getScope());
}
/**
* uri equality
*
*@param uri
*@return
*/
public boolean equalsURI(String uri) {
return this.getUri().equals(uri);
}
/**
* url equality
*
*@param url
*@return
*/
public boolean equalsURL(String url) {
return this.getUri().equals(url);
}
/**
* fill in a response with specifics from this entry
*
*@param response
*/
public void fillIn(DiscoveryMessage response) {
response.setUrl(getUrl());
response.setUri(getUri());
response.setScope(getScope());
response.setDescription(getDescription());
}
/**
* Gets the uri attribute of the ServiceEntry object
*
*@return The uri value
*/
public String getUri() {
return uri;
}
/**
* Sets the uri attribute of the ServiceEntry object
*
*@param uri The new uri value
*/
public void setUri(String uri) {
this.uri = uri;
}
/**
* Gets the url attribute of the ServiceEntry object
*
*@return The url value
*/
public String getUrl() {
return url;
}
/**
* Sets the url attribute of the ServiceEntry object
*
*@param url The new url value
*/
public void setUrl(String url) {
this.url = url;
}
/**
* Gets the scope attribute of the ServiceEntry object
*
*@return The scope value
*/
public String getScope() {
return scope;
}
/**
* Sets the scope attribute of the ServiceEntry object
*
*@param scope The new scope value
*/
public void setScope(String scope) {
this.scope = scope;
}
/**
* Gets the description attribute of the ServiceEntry object
*
*@return The description value
*/
public String getDescription() {
return description;
}
/**
* Sets the description attribute of the ServiceEntry object
*
*@param description The new description value
*/
public void setDescription(String description) {
this.description = description;
}
/**
* Gets the hitCount attribute of the ServiceEntry object
*
*@return The hitCount value
*/
public Integer getHitCount() {
return new Integer(hitCount);
}
/**
* Sets the hitCount attribute of the ServiceEntry object
*
*@param hitCount The new hitCount value
*/
public void setHitCount(Integer hitCount) {
this.setHitCount(hitCount.intValue());
}
/**
* Gets the hitCountInt attribute of the ServiceEntry object
*
*@return The hitCountInt value
*/
public int getHitCountInt() {
return hitCount;
}
/**
* Sets the hitCount attribute of the ServiceEntry object
*
*@param hitCount The new hitCount value
*/
public void setHitCount(int hitCount) {
this.hitCount = hitCount;
}
/**
* inc the hit count by one
*/
public synchronized void hit() {
setHitCount(hitCount + 1);
}
/**
* is this a static entry
* @return
*/
public boolean isStaticEntry() {
return staticEntry;
}
/**
* set the static entry flag
* @param staticEntry
*/
public void setStaticEntry(boolean staticEntry) {
this.staticEntry = staticEntry;
}
/**
* get the marker status
* @return
*/
public boolean getMarker() {
return marker;
}
/**
* set the marker status
* @param marker
*/
public void setMarker(boolean marker) {
this.marker = marker;
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/server/UriStore.java
Index: UriStore.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.server;
import org.apache.axis.discovery.core.Const;
import org.apache.axis.discovery.core.DiscoveryMessage;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
/**
* Store of uris. May be a map, may be something else
* to support multiple endpoints implementing the same uri
* @author steve loughran
*/
public class UriStore {
/**
* our list of ServiceEntries
*/
private LinkedList mappings;
/**
* log file
*/
private static Log log = LogFactory.getLog(UriStore.class);
/**
* failure array is cached for performance
*/
private static final String[] NOMATCH = new String[0];
/**
* create a store
*/
public UriStore() {
mappings = new LinkedList();
}
/**
* Add a uri,url pair; service is static
* @param uri
* @param url
*/
public void add(String uri, String url) {
addServiceEntry(new ServiceEntry(uri, url));
}
/**
* find all urls that map to a uri
* @param uri
* @return list of zero or more entries.
*/
public List lookupEntries(String uri) {
log.debug("looking for " + uri);
List hits = new LinkedList();
Iterator entries = mappings.iterator();
while (entries.hasNext()) {
ServiceEntry e = (ServiceEntry) entries.next();
if (e.equalsURI(uri)) {
hits.add(e);
}
}
return hits;
}
/**
* lookup an entry; match is on uri and url
* @param entry
* @return
*/
public int indexOf(ServiceEntry entry) {
return mappings.indexOf(entry);
}
/**
* find all urls that map to a uri
* @param uri
* @return array of zero or more urls.
*/
public String[] lookup(String uri) {
List hits = lookupEntries(uri);
int l = hits.size();
log.debug("found " + l + " match(es)");
if (l == 0) {
return NOMATCH;
} else {
String[] endpoints = new String[l];
Iterator hitit = hits.iterator();
int count = 0;
while (hitit.hasNext()) {
ServiceEntry entry = (ServiceEntry) hitit.next();
endpoints[count++] = entry.getUrl();
}
return endpoints;
}
}
/**
* register ourselves from a transport.
* @param url url to register
*/
public void registerSelf(String url) {
add(Const.DISCOVERY_SERVICE_URI, url);
}
/**
* Resolve the request.
* Do not worry about repeat requests here, or anything
*
* @param request
* @return array of responses
*/
public DiscoveryMessage[] processRequest(DiscoveryMessage request) {
List results = lookupEntries(request.getUri());
DiscoveryMessage[] responses = new DiscoveryMessage[results.size()];
Iterator resultIterator = results.iterator();
int index = 0;
while (resultIterator.hasNext()) {
ServiceEntry entry = (ServiceEntry) resultIterator.next();
DiscoveryMessage response = request.createResponse();
entry.fillIn(response);
entry.hit();
responses[index] = response;
}
return responses;
}
/**
* add a set of endpoints from a property array
* @param props
*/
public void registerProperties(Properties props) {
Enumeration e = props.keys();
while (e.hasMoreElements()) {
String uri = (String) e.nextElement();
add(uri, props.getProperty(uri));
}
}
/**
* add an entry to the store
* @param entry
*/
public synchronized void addServiceEntry(ServiceEntry entry) {
int index = indexOf(entry);
if (index == -1) {
log.debug("adding "
+ entry.getUri()
+ " -> "
+ entry.getUrl());
mappings.add(entry);
} else {
ServiceEntry oldentry = (ServiceEntry) mappings.get(index);
if (entry.equals(oldentry)) {
log.debug("updating "
+ entry.getUri()
+ " -> "
+ entry.getUrl());
entry.setHitCount(entry.getHitCount().intValue()
+ oldentry.getHitCount().intValue());
mappings.set(index, entry);
}
}
}
/**
* get an iterator over the entries, all of type ServiceEntry
* not a clone; not synchronized, use carefully
* @return iterator of type ServiceEntry
*/
public Iterator getEntries() {
return mappings.iterator();
}
/**
* purge all non-static entries from the list that have their
* marker flag set
* this is for removing undeployed axis entries
*/
public synchronized void deleteAllMarkedNonStaticEntries() {
Iterator entries = mappings.iterator();
while (entries.hasNext()) {
ServiceEntry e = (ServiceEntry) entries.next();
if (!e.isStaticEntry() && e.getMarker()) {
entries.remove();
}
}
}
/**
* purge all non-static entries from the list
* this is for removing undeployed axis entries
*/
public synchronized void markAllEntries() {
Iterator entries = mappings.iterator();
while (entries.hasNext()) {
ServiceEntry e = (ServiceEntry) entries.next();
e.setMarker(true);
}
}
/**
* get a shallow clone of the mappings
* @return a clone of the mappings
*/
public LinkedList cloneMappings() {
return (LinkedList) mappings.clone();
}
/**
* set the mappings list
* @param mappings
*/
public synchronized void setMappings(LinkedList mappings) {
this.mappings = mappings;
}
/**
* how many entries are in the list
* @return
*/
public int size() {
return mappings.size();
}
/**
* return the sole entry bound to an uri/endpoint pair
* @param uri uri of service
* @param endpoint endpoint
* @return entry or null
*/
public ServiceEntry lookupEntry(String uri, String endpoint) {
ServiceEntry entry = null;
List entries = lookupEntries(uri);
Iterator i = entries.iterator();
while (i.hasNext()) {
ServiceEntry serviceEntry = (ServiceEntry) i.next();
if (endpoint.equals(serviceEntry.getUrl())) {
entry = serviceEntry;
break;
}
}
return entry;
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/server/management/DiscoveryServlet.java
Index: DiscoveryServlet.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.server.management;
import org.apache.axis.AxisEngine;
import org.apache.axis.AxisFault;
import org.apache.axis.discovery.server.AxisBinder;
import org.apache.axis.discovery.server.DiscoveryServer;
import org.apache.axis.discovery.server.ServiceEntry;
import org.apache.axis.transport.http.AxisServletBase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
/**
* This servlet does two things.
* One, it starts and stops the server, with a binding to axis
* Two, it provides a listing of endpoints, if the appropriate
* config flag is set
*@author Steve Loughran
*@web.servlet name="discovery"
*@web.servlet-mapping url-pattern="/discovery"
*/
public class DiscoveryServlet extends AxisServletBase {
/**
* who our discovery server
*/
private DiscoveryServer _server;
/**
* bridging code
*/
private AxisBinder axisBridge;
/**
* logging entry
*/
private static Log log = LogFactory.getLog(DiscoveryServlet.class);
/**
* birth
*/
public void init() {
log.info("DiscoveryServlet::init");
super.init();
}
/**
* handle destruction
*/
public void destroy() {
log.info("DiscoveryServlet::destroy");
if (_server != null) {
_server.stop();
}
super.destroy();
}
/**
* incoming get request triggers initialization.
*
*@param request
*@param response
*@exception ServletException Description of the Exception
*@exception IOException Description of the Exception
*@throws javax.servlet.ServletException
*@throws java.io.IOException
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("<html><head><title>Discovery Status</title></head>");
out.println("<body bgcolor=#ffffff>");
if (getServer(request) == null) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
out.println("Cannot start Discovery, check error logs");
out.println("</body></html>");
return;
}
listEntries(out);
out.println("</body></html>");
}
/**
* list the entries into a table
* @param out
*/
private void listEntries(PrintWriter out) {
int count = 0;
Iterator it = _server.getStore().getEntries();
out.println("<table border=1>");
out.print("<tr><td>URI</td><td>URL</td>hits</td>");
for (; it.hasNext(); count++) {
ServiceEntry entry = (ServiceEntry) it.next();
out.print("<tr><td>");
out.print(entry.getUri());
out.print("</td><td>");
out.print(entry.getUrl());
out.print("</td><td>");
out.print(entry.getHitCountInt());
out.print("</td></tr>");
}
out.println("</table>");
out.println(" There are " + count + " entries");
out.println("<hr>");
out.println("<table border=0>");
out.print("<tr><td>Messages in:</td><td>");
out.print(_server.getTransceiver().getReceipts());
out.print("</td></tr>");
out.print("<tr><td>Failures in:</td><td>");
out.print(_server.getTransceiver().getFailures());
out.print("</td></tr>");
out.print("<tr><td>Messages out:</td><td>");
out.print(_server.getTransceiver().getSends());
out.print("</td></tr>");
out.println("</table>");
out.print("</td><td>");
}
/**
* Get the discovery server, creating it if need be
*
*@param request
*@return null if we couldnt start
*/
private DiscoveryServer getServer(HttpServletRequest request) {
if (_server == null) {
try {
_server = new DiscoveryServer();
} catch (IOException e) {
log.fatal("creating a new DiscoveryServer", e);
return null;
}
AxisEngine engine;
engine = getEngineWithFaultHandling();
if (engine == null) {
return null;
}
axisBridge = new AxisBinder();
String baseURL = getWebappBase(request);
axisBridge.bind(baseURL, engine, _server.getStore(), 1000);
_server.startInNewThread();
}
return _server;
}
private AxisEngine getEngineWithFaultHandling() {
AxisEngine engine;
try {
engine = getEngine();
} catch (AxisFault axisFault) {
log.fatal("retrieving the Axis engine", axisFault);
engine = null;
}
return engine;
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/server/management/ServerMBean.java
Index: ServerMBean.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.server.management;
public interface ServerMBean {
/**
* how many sent
* @return number >=0
*/
Integer getMessagesSent();
/**
* how many received (inc failures)
* @return number>=0
*/
Integer getMessagesReceived();
/**
* how many failures received
* @return number>=0
*/
Integer getFailures();
/**
* what is our url
* @return the url we listen on
*/
String getURL();
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/server/management/ServiceEntryMBean.java
Index: ServiceEntryMBean.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.server.management;
/**
* this is an mbean interface for a service entry
*/
public interface ServiceEntryMBean {
String getUri();
void setUri(String uri);
String getUrl();
void setUrl(String url);
String getScope();
void setScope(String scope);
String getDescription();
void setDescription(String description);
Integer getHitCount();
void setHitCount(Integer hitCount);
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/test/LoopbackTest.java
Index: LoopbackTest.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.test;
import org.apache.axis.discovery.core.DiscoveryMessage;
import org.apache.axis.discovery.core.LoopbackTransceiver;
import org.apache.axis.discovery.core.Transceiver;
/**
* loopback to verify that all works
*/
public class LoopbackTest extends TransceiverTestBase {
public LoopbackTest(String s) {
super(s);
}
/**
* create a subclass of transceiver
* @return a new txr instance
*/
protected Transceiver createTransceiver() {
return new LoopbackTransceiver(createMarshaller());
}
public void testEmpty() {
assertTrue(!transceiver.dataReady());
}
public void testPush() throws Exception {
DiscoveryMessage message = createRequest("uri:foo", "debug");
assertTrue(!transceiver.dataReady());
transceiver.sendMessage(message);
assertTrue(transceiver.dataReady());
}
public void testRoundTrip() throws Exception {
DiscoveryMessage message = createRequest("uri:foo", "debug");
assertTrue(!transceiver.dataReady());
transceiver.sendMessage(message);
assertTrue(transceiver.dataReady());
DiscoveryMessage message2;
message2 = transceiver.receiveMessage(0);
assertEquals(message, message2);
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/test/MarshallTest.java
Index: MarshallTest.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.test;
import org.apache.axis.discovery.core.DiscoveryException;
import org.apache.axis.discovery.core.DiscoveryMessage;
import org.apache.axis.discovery.core.Marshaller;
import org.apache.axis.discovery.core.XmlMarshaller;
import java.io.IOException;
import java.net.DatagramPacket;
/**
* test our to-from datagram marshalling
*/
public class MarshallTest extends MessagingTestBase {
private Marshaller marshaller = new XmlMarshaller();
public MarshallTest(String s) {
super(s);
}
/**
* marshall and unmarshall a message
* @param message
*/
public void roundTrip(DiscoveryMessage message)
throws IOException, DiscoveryException {
DatagramPacket packet = marshaller.marshall(message);
DiscoveryMessage unmarshalled = marshaller.unmarshall(packet);
/*
Writer writer;
writer = new OutputStreamWriter(System.out);
unmarshalled.marshall(writer);
writer.flush();
System.out.println();
*/
assertEquals(message, unmarshalled);
}
public void testRequest() throws Exception {
String uri = "http://foo";
String scope = "test";
DiscoveryMessage message = createRequest(uri, scope);
roundTrip(message);
}
public void testResponse() throws Exception {
String uri = "http://foobar";
String scope = "test";
String url = "http://localhost";
DiscoveryMessage message = createResponse(uri, scope, url, null);
roundTrip(message);
}
public void testUnicoding() throws Exception {
DiscoveryMessage message = createResponse("http://foobar",
"test",
"http://localhost",
"Cost per use is \u20ac30");
roundTrip(message);
}
/**
* verify that we can handle bad XML
* @throws Exception
*/
public void testBadDatagrams() throws Exception {
expectFailure("");
expectFailure("<?xml version='1.0'?><discovery/>");
expectFailure("<?xml version='1.0'?><discovery id='0' type='foobar'><uri>a</uri><scope/></discovery>");
expectFailure("<?xml version='1.0'?><discovery id='0' type='request'><uri>a</uri><scope/></discovery>");
expectFailure("<?xml version='1.0'?><discovery id='0' type='request'><uri>a</uri><scope>foo</scope></discovery>");
expectFailure(new DatagramPacket(new byte[0], 0), "empty buffer");
expectFailure(new DatagramPacket(new byte[256], 256), "256 buffer");
}
/**
* expect an unmarshall failure on a string or bail
* @param xml
* @throws IOException
*/
public void expectFailure(String xml) throws IOException, DiscoveryException {
DatagramPacket packet = createDatagramFromText(xml);
expectFailure(packet, "Expected failure from " + xml);
}
/**
* handle an expected failure of a packet
* @param packet
* @param text
*/
public void expectFailure(DatagramPacket packet, String text) {
try {
marshaller.unmarshall(packet);
fail(text);
} catch (IOException swallowed) {
;
} catch (DiscoveryException swallowed) {
;
}
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/test/MessagingTestBase.java
Index: MessagingTestBase.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.test;
import junit.framework.TestCase;
import org.apache.axis.discovery.core.Const;
import org.apache.axis.discovery.core.DiscoveryMessage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.DatagramPacket;
/**
* just a base class
*/
public class MessagingTestBase extends TestCase {
public MessagingTestBase(String s) {
super(s);
}
/**
* this is just here as IDEA tries to run all classes that extend TestCase
* and gets upset when there are no tests in a class.
*/
public void testNoop() {
}
/**
* create a request
* @param uri
* @param scope
* @return
*/
protected static DiscoveryMessage createRequest(String uri, String scope) {
DiscoveryMessage message = new DiscoveryMessage(DiscoveryMessage.MESSAGE_REQUEST);
message.setUri(uri);
message.setScope(scope);
return message;
}
/**
* create a response
* @param uri
* @param scope
* @param url
* @param description
* @return
*/
protected DiscoveryMessage createResponse(String uri,
String scope,
String url,
String description) {
DiscoveryMessage message = new DiscoveryMessage(DiscoveryMessage.MESSAGE_REQUEST);
message.setUri(uri);
message.setScope(scope);
message.setUrl(url);
message.setDescription(description);
return message;
}
/**
* build a datagram from the text
* @param xml any arbitrary text
* @return packet for sending/processing
* @throws IOException
*/
protected DatagramPacket createDatagramFromText(String xml)
throws IOException {
ByteArrayOutputStream byteData = new ByteArrayOutputStream();
OutputStreamWriter writer;
writer = new OutputStreamWriter(byteData,
Const.MESSAGE_CHARSET);
writer.write(xml);
writer.flush();
writer.close();
byte rawdata[] = byteData.toByteArray();
DatagramPacket packet = new DatagramPacket(rawdata, byteData.size());
return packet;
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/test/NetBroadcastTest.java
Index: NetBroadcastTest.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.test;
import org.apache.axis.discovery.core.BroadcastTransceiver;
import org.apache.axis.discovery.core.Const;
import org.apache.axis.discovery.core.Transceiver;
import java.io.IOException;
/**
*
*/
public class NetBroadcastTest extends TransceiverTestBase {
public NetBroadcastTest(String s) {
super(s);
}
/**
* create a subclass of transceiver
* @return a new txr instance
*/
protected Transceiver createTransceiver() throws IOException {
return new BroadcastTransceiver(Const.MBONE_PORT,
Const.MBONE_PORT,
createMarshaller());
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/test/NetMulticastTest.java
Index: NetMulticastTest.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.test;
import org.apache.axis.discovery.core.Const;
import org.apache.axis.discovery.core.MulticastTransceiver;
import org.apache.axis.discovery.core.Transceiver;
import java.io.IOException;
/**
*
*/
public class NetMulticastTest extends TransceiverTestBase {
public NetMulticastTest(String s) {
super(s);
}
/**
* create a subclass of transceiver
* @return a new txr instance
*/
protected Transceiver createTransceiver() throws IOException {
return new MulticastTransceiver(Const.MBONE_ADDRESS,
Const.MBONE_PORT,
Const.MBONE_PORT,
createMarshaller());
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/test/NetworkTest.java
Index: NetworkTest.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.test;
import junit.framework.TestCase;
import org.apache.axis.discovery.client.Client;
import org.apache.axis.discovery.core.Const;
import org.apache.axis.discovery.server.DiscoveryServer;
import java.util.List;
/**
* This is a fun little test case. It sets up a server in one
* thread then calls it in a client; the client asserts that
* it gets back at least one response to the request.
* This test only works if a network is present, because mcast
* sockets are somehow fussier than normal sockets...you cannot
* join an mcast group off-line, at least not on WinXP.
* @author Steve Loughran
* @created Jul 11, 2002 3:40:51 PM
*/
public class NetworkTest extends TestCase {
private DiscoveryServer _server;
public NetworkTest(String s) {
super(s);
}
protected void setUp() throws Exception {
_server = new DiscoveryServer();
_server.startInNewThread();
}
protected void tearDown() throws Exception {
_server.stop();
}
/**
* who says you cant do functional tests with junit?
* @throws Exception
*/
public void testLoopback() throws Exception {
String uri = Const.DISCOVERY_SERVICE_URI;
System.out.println("Searching for [" + uri + "]");
Client client = new Client();
List responses = client.findEndpoints(uri,
1,
Const.CLIENT_TIMEOUT,
0);
String[] endpoints = client.extractEndpointArray(responses);
int length = endpoints.length;
assertTrue("No response from server", length > 0);
String localURL = _server.getTransceiver().getReceiverURL();
boolean matchFound = false;
for (int i = 0; i < length; i++) {
System.out.println(endpoints[i]);
if (localURL.equals(endpoints[i])) {
matchFound = true;
}
}
assertTrue("no match for our local server found", matchFound);
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/test/ResolveTest.java
Index: ResolveTest.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.test;
import junit.framework.TestCase;
import org.apache.axis.discovery.core.Const;
import org.apache.axis.discovery.core.DiscoveryMessage;
import org.apache.axis.discovery.server.ServiceEntry;
import org.apache.axis.discovery.server.UriStore;
/**
* test the uristore
*
*/
public class ResolveTest extends TestCase {
/**
* uristore used for testing
*/
private UriStore uristore;
/**
* schema1
*/
protected static final String SCHEMA = "nap:underworld";
/**
* schema2
*/
protected static final String SCHEMA2 = "nap:underworld+born+slippy";
/**
* schema3
*/
protected static final String SCHEMA3 = "http://apache.org/somenamespace";
/**
* endpoint#1
*/
protected static final String URL = "http://127.0.0.1/endpoint";
/**
* endpoint#2
*/
protected static final String URL2 = "http://127.0.0.1/endpoint2";
/**
* endpoint#3
*/
protected static final String URL3 = "http://127.0.0.1/endpoint3";
/**
* Constructor for the ResolveTest object
*
*@param s Description of the Parameter
*/
public ResolveTest(String s) {
super(s);
}
/**
* The JUnit setup method
*
*@exception Exception Description of the Exception
*/
protected void setUp() throws Exception {
uristore = new UriStore();
uristore.registerSelf("udp://127.0.0.1:1234");
uristore.add(SCHEMA, URL);
uristore.add(SCHEMA2, URL2);
uristore.add(SCHEMA2, URL3);
ServiceEntry entry = new ServiceEntry();
entry.setUrl(URL3);
entry.setUri(SCHEMA3);
entry.setMarker(false);
entry.setStaticEntry(false);
uristore.addServiceEntry(entry);
}
/**
* test we are adding our own service
*/
public void testServiceLookup() {
assertEquals(1, getEndpointCount(Const.DISCOVERY_SERVICE_URI));
}
/**
* test lookup of an added entry works
*/
public void testLookupWorks() {
String[] endpoints = uristore.lookup(SCHEMA);
assertEquals(1, endpoints.length);
assertEquals(URL, endpoints[0]);
}
/**
* if there is more than one entry, are both found?
*/
public void testMultipleLookupWorks() {
String[] endpoints = uristore.lookup(SCHEMA2);
assertEquals(2, endpoints.length);
assertTrue(!endpoints[0].equals(endpoints[1]));
}
/**
* does a message get processed
*/
public void testProcessing() {
DiscoveryMessage request = new DiscoveryMessage(DiscoveryMessage.MESSAGE_REQUEST);
request.setUri(SCHEMA);
DiscoveryMessage[] responses = uristore.processRequest(request);
assertEquals(1, responses.length);
assertEquals(URL, responses[0].getUrl());
assertEquals(SCHEMA, responses[0].getUri());
assertEquals(request.getMessageID(), responses[0].getMessageID());
}
/**
* test that we can clean up stuff
*/
public void testCleanup() {
assertEquals(1, getEndpointCount(SCHEMA3));
int size = uristore.size();
uristore.markAllEntries();
uristore.deleteAllMarkedNonStaticEntries();
assertEquals(0, getEndpointCount(SCHEMA3));
assertEquals(size - 1, uristore.size());
}
/**
* get a count of the # of endpoints implementing a URI
* @param uri
* @return count, may be 0
*/
private int getEndpointCount(String uri) {
String[] endpoints = uristore.lookup(uri);
return endpoints.length;
}
/**
* verify that updating an existing endpoint replaces the existing copy
* but the hit count is the combined value
*/
public void testUpdatesPreserveHitCount() {
//first get the existing entry of uri/url value
ServiceEntry oldEntry = uristore.lookupEntry(SCHEMA2, URL3);
assertNotNull(oldEntry);
//set it with a hit count
oldEntry.setHitCount(50);
ServiceEntry entry = new ServiceEntry(SCHEMA2, URL3);
entry.setHitCount(1);
uristore.addServiceEntry(entry);
ServiceEntry newEntry = uristore.lookupEntry(SCHEMA2, URL3);
assertSame(entry, newEntry);
assertEquals(newEntry.getHitCountInt(), 51);
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/test/SubnetPollTest.java
Index: SubnetPollTest.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.test;
import org.apache.axis.discovery.core.Const;
import org.apache.axis.discovery.core.DiscoveryException;
import org.apache.axis.discovery.core.SubnetPollTransceiver;
import org.apache.axis.discovery.core.Transceiver;
import org.apache.axis.discovery.core.Utils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
/**
* test our subnet polling by hitting 16 nodes, including us
*/
public class SubnetPollTest extends TransceiverTestBase {
/**
* logging entry
*/
private static Log log = LogFactory.getLog(SubnetPollTest.class);
public SubnetPollTest(String s) {
super(s);
}
protected Transceiver createTransceiver()
throws IOException, DiscoveryException {
long startAddr = Utils.getLocalAddressValue();
log.info("Current address is " + Utils.toDotAddressString(startAddr));
startAddr &= 0xfffffff0;
log.info("subnet is " + Utils.toDotAddressString(startAddr));
return new SubnetPollTransceiver(
createMarshaller(),
Const.MBONE_PORT,
startAddr,
16,
4, 10);
}
}
1.1 xml-axis/addons/discovery/src/org/apache/axis/discovery/test/TransceiverTestBase.java
Index: TransceiverTestBase.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.discovery.test;
import org.apache.axis.discovery.core.DiscoveryException;
import org.apache.axis.discovery.core.DiscoveryMessage;
import org.apache.axis.discovery.core.Marshaller;
import org.apache.axis.discovery.core.Transceiver;
import org.apache.axis.discovery.core.XmlMarshaller;
import java.io.IOException;
/**
* This is just the base class for transceiver tests
*/
public abstract class TransceiverTestBase extends MessagingTestBase {
protected Transceiver transceiver;
public TransceiverTestBase(String s) {
super(s);
}
/**
* create a subclass of transceiver
* @return a new txr instance
*/
protected abstract Transceiver createTransceiver()
throws IOException, DiscoveryException;
/**
* create the transceiver from the subclass
* @throws Exception
*/
protected void setUp() throws Exception {
transceiver = createTransceiver();
}
/**
* destroy the transceiver
* @throws Exception
*/
protected void tearDown() throws Exception {
transceiver.destroy();
}
public void testMulticastPush() throws Exception {
DiscoveryMessage message = createRequest("uri:foo", "debug");
transceiver.multicastMessage(message, 0);
DiscoveryMessage message2;
message2 = transceiver.receiveMessage(0);
assertNotNull(message2);
}
public void testMulticastRoundTrip() throws Exception {
DiscoveryMessage message = createRequest("uri:foo", "debug");
transceiver.multicastMessage(message, 0);
DiscoveryMessage message2;
message2 = transceiver.receiveMessage(0);
assertEquals(message, message2);
}
public void testUnicodeRoundTrip() throws Exception {
DiscoveryMessage message = createRequest("uri:\u05d00", "\u0416");
transceiver.multicastMessage(message, 0);
DiscoveryMessage message2;
message2 = transceiver.receiveMessage(0);
assertEquals(message, message2);
}
public void testBlockingWorks() throws Exception {
DiscoveryMessage message;
message = transceiver.receiveMessage(100);
assertNull(message);
}
public void testGetURL() {
String url = transceiver.getReceiverURL();
assertNotNull(url);
}
public Marshaller createMarshaller() {
return new XmlMarshaller();
}
}
1.1 xml-axis/addons/discovery/web/discovery.jsp
Index: discovery.jsp
===================================================================
<%@ page language="java"
session="false" contentType="text/html;charset=iso-8859-1"
import="org.apache.axis.discovery.client.Client,
java.util.List,
org.apache.axis.discovery.core.Const,
java.io.IOException,
java.io.PrintWriter,
java.io.StringWriter"%>
<html><head>
<title>Axis Mir location</title>
</head><html>
<body bgcolor="#ffffff">
<h2>Axis Discovery</h2>
<%!
public static final String uriParam="uri";
public static final String ttlParam = "ttl";
public void listEndpoints( String[] endpoints, JspWriter out) throws IOException{
int length = endpoints.length;
out.write("Found "+length+" endpoint(s)");
out.write("<p><table>");
for (int i = 0; i < length; i++) {
String endpoint = endpoints[i];
out.write("<tr><td>");
out.write(endpoint);
out.write("</td></tr>\n");
}
out.write("</table >");
}
public void logException(JspWriter out, Throwable e) throws IOException {
out.write("<h2>Exception ");
out.write(e.toString());
out.write("</h2>\n");
if(e.getMessage()!=null) {
out.write(e.getMessage());
}
out.write("\n<pre>\n");
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
out.write(sw.toString());
out.write("</pre>");
}
public int getIntParam(HttpServletRequest request, String name, int defVal) {
int result;
try {
result = Integer.parseInt(request.getParameter(name));
} catch (NumberFormatException e) {
result = defVal;
}
return result;
}
%>
<%
/*
* demo page to use discovery to find and display services.
* yes, jsps with code are ugly, but JSTL is even worse to debug
*/
String uri=request.getParameter(uriParam);
if(uri==null) {
%>
<form method="get">
<table border="0">
<tr>
<td>url</td>
<td>
<input type="text" name="uri" size="80">
</td>
</tr>
<tr>
<tr>
<td>time to live (0-255)</td>
<td>
<input type="text" name="ttl" size="10">
</td>
</tr>
<tr>
<td>timeout (seconds)</td>
<td>
<input type="text" name="timeout" size="10">
</td>
</tr>
<tr>
<td>max number to find</td>
<td>
<input type="text" name="limit" size="10">
</td>
</tr>
<tr><td>
<input type="submit" name="locate" value="Submit">
</td>
</tr>
</table>
</form>
<%
} else {
int ttl= getIntParam(request,"ttl",3);
int timeout= getIntParam(request, "ttl", 1)*1000;
int limit= getIntParam(request, "limit", 0);
%>
<p>Searching...<p>
<%
try {
Client client;
List responses;
String[] endpoints;
client = new Client();
responses= client.findEndpoints(uri,
ttl,
timeout,
limit);
endpoints = client.extractEndpointArray(responses);
listEndpoints(endpoints,out);
} catch (Throwable e) {
logException(out,e);
}
}
%>
</body>
</html>
1.1 xml-axis/addons/discovery/web/WEB-INF/.cvskeep
<<Binary file>>
1.1 xml-axis/addons/discovery/xml/checkstyle-noframes.xsl
Index: checkstyle-noframes.xsl
===================================================================
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:decimal-format decimal-separator="." grouping-separator="," />
<xsl:template match="checkstyle">
<html>
<head>
<style type="text/css">
.bannercell {
border: 0px;
padding: 0px;
}
body {
margin-left: 10;
margin-right: 10;
font:normal 80% arial,helvetica,sanserif;
background-color:#FFFFFF;
color:#000000;
}
.a td {
background: #efefef;
}
.b td {
background: #fff;
}
th, td {
text-align: left;
vertical-align: top;
}
th {
font-weight:bold;
background: #ccc;
color: black;
}
table, th, td {
font-size:100%;
border: none
}
table.log tr td, tr th {
}
h2 {
font-weight:bold;
font-size:140%;
margin-bottom: 5;
}
h3 {
font-size:100%;
font-weight:bold;
background: #525D76;
color: white;
text-decoration: none;
padding: 5px;
margin-right: 2px;
margin-left: 2px;
margin-bottom: 0;
}
</style>
</head>
<body>
<a name="#top"></a>
<!-- jakarta logo -->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td class="bannercell" rowspan="2">
<!--a href="http://jakarta.apache.org/">
<img src="http://jakarta.apache.org/images/jakarta-logo.gif" alt="http://jakarta.apache.org" align="left" border="0"/>
</a-->
</td>
<td class="text-align:right"><h2>CheckStyle Audit</h2></td>
</tr>
<tr>
<td class="text-align:right">Designed for use with <a href='http://checkstyle.sourceforge.net/'>CheckStyle</a> and <a href='http://jakarta.apache.org'>Ant</a>.</td>
</tr>
</table>
<hr size="1"/>
<!-- Summary part -->
<xsl:apply-templates select="." mode="summary"/>
<hr size="1" width="100%" align="left"/>
<!-- Package List part -->
<xsl:apply-templates select="." mode="filelist"/>
<hr size="1" width="100%" align="left"/>
<!-- For each package create its part -->
<xsl:for-each select="file">
<xsl:sort select="@name"/>
<xsl:apply-templates select="."/>
<p/>
<p/>
</xsl:for-each>
<hr size="1" width="100%" align="left"/>
</body>
</html>
</xsl:template>
<xsl:template match="checkstyle" mode="filelist">
<h3>Files</h3>
<table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
<tr>
<th>Name</th>
<th>Errors</th>
</tr>
<xsl:for-each select="file">
<xsl:sort select="@name"/>
<xsl:variable name="errorCount" select="count(error)"/>
<tr>
<xsl:call-template name="alternated-row"/>
<td><a href="#{@name}"><xsl:value-of select="@name"/></a></td>
<td><xsl:value-of select="$errorCount"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
<xsl:template match="file">
<a name="#{@name}"></a>
<h3>File <xsl:value-of select="@name"/></h3>
<table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
<tr>
<th>Error Description</th>
<th>Line</th>
</tr>
<xsl:for-each select="error">
<tr>
<xsl:call-template name="alternated-row"/>
<td><xsl:value-of select="@message"/></td>
<td><xsl:value-of select="@line"/></td>
</tr>
</xsl:for-each>
</table>
<a href="#top">Back to top</a>
</xsl:template>
<xsl:template match="checkstyle" mode="summary">
<h3>Summary</h3>
<xsl:variable name="fileCount" select="count(file)"/>
<xsl:variable name="errorCount" select="count(file/error)"/>
<table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
<tr>
<th>Files</th>
<th>Errors</th>
</tr>
<tr>
<xsl:call-template name="alternated-row"/>
<td><xsl:value-of select="$fileCount"/></td>
<td><xsl:value-of select="$errorCount"/></td>
</tr>
</table>
</xsl:template>
<xsl:template name="alternated-row">
<xsl:attribute name="class">
<xsl:if test="position() mod 2 = 1">a</xsl:if>
<xsl:if test="position() mod 2 = 0">b</xsl:if>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
1.1 xml-axis/addons/discovery/xml/message.xsd
Index: message.xsd
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="discovery">
<xs:annotation>
<xs:documentation>message of specified type</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="uri" type="xs:anyURI">
<xs:annotation>
<xs:documentation>uri of service</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="scope" type="xs:string">
<xs:annotation>
<xs:documentation>scope of request, leave empty for 'any' scope</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="url" type="xs:anyURI" minOccurs="0">
<xs:annotation>
<xs:documentation>endpoint of service</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="expires" type="xs:int" minOccurs="0">
<xs:annotation>
<xs:documentation>expiry time as time_t integer, always in UTC</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="description" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>optional description of endpoint</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="type" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>