1
2
3
4
5
6
7 package org.astrogrid.datacenter.service;
8 import java.io.InputStreamReader;
9 import java.io.PrintWriter;
10 import java.io.StringWriter;
11 import java.rmi.RemoteException;
12 import javax.xml.namespace.QName;
13 import javax.xml.rpc.soap.SOAPFaultException;
14 import javax.xml.soap.Detail;
15 import javax.xml.soap.SOAPException;
16 import javax.xml.soap.SOAPFactory;
17 import org.apache.commons.logging.Log;
18 import org.apache.commons.logging.LogFactory;
19 import org.astrogrid.community.Account;
20 import org.astrogrid.datacenter.metadata.VoDescriptionServer;
21 import org.astrogrid.datacenter.queriers.status.QuerierStatus;
22 import org.astrogrid.io.Piper;
23 import org.astrogrid.util.DomHelper;
24
25 /***
26 * Provides methods suitable for a SOAP implementation of the Datacenter. This
27 * is an abstract class as we want to *force* people to subclass. That means
28 * that if the interface changes, a new subclass can be added without
29 * interfering with the old one.
30 *
31 * @author M Hill
32 * @author Noel Winstanly
33 *
34 */
35
36 public abstract class SoapDataServer {
37
38 protected static Log log = LogFactory.getLog(SoapDataServer.class);
39
40 protected DataServer server = new DataServer();
41
42 public SoapDataServer() {
43 }
44
45 /***
46 * Returns the metadata file as a string
47 */
48 public String getMetadata() throws SOAPFaultException {
49 try {
50 return DomHelper.DocumentToString(VoDescriptionServer.getVoDescription());
51 }
52 catch (Throwable e) {
53 throw makeSoapFault("Server", "Could not access metadata", e);
54 }
55 }
56
57 /***
58 * This routine is public so that we can test our client-side error
59 * reporting */
60 public void testFault(String message) throws SOAPFaultException {
61 throw makeSoapFault(message);
62 }
63
64 /***
65 * Sets up a SOAP Fault Exception suitable for passing the original cause of
66 * the error across the web interface.
67 * Note that it is not sufficient to throw this; the fault handler requires
68 * some work to include the details in the fault response.
69 * @see summary at http://www.w3schools.com/SOAP/soap_fault.asp
70 * @see .Net-related article at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnservice/html/service09172002.asp
71 * @see JAX-RPC article (low level) at http://www.fawcette.com/javapro/2004_01/online/webservices_kjones_01_21_04/page2.aspx
72 *
73 * <p>
74 * The actor is assumed to be this service.
75 * <p>
76 * This can be overridden by subclasses to throw faults more appropriate to
77 * their publication mechanism. For example AxisFault is more useful for
78 * Axis services. Unfortunately AxisFault subclasses RuntimeException and
79 * SOAPFaultException subclasses RemoteException (->IOException).
80 * <p>
81 * @code - Client, Server depending on whether the error is caused by
82 * something wrong being sent from the client, or a failure inside the server
83 */
84 protected SOAPFaultException makeSoapFault(String code, String message, Throwable cause) {
85
86 log.error("An error has occured, so throwing "+cause+" to client, message="+message, cause);
87
88 QName faultCode = new QName(code);
89
90 try {
91 Detail detail = SOAPFactory.newInstance().createDetail();
92
93 if (cause != null) {
94 detail.addTextNode(cause.getClass().toString());
95 detail.addTextNode(cause.toString());
96
97
98 StringWriter writer = new StringWriter();
99 cause.printStackTrace(new PrintWriter(writer));
100 detail.addTextNode(writer.toString());
101 }
102
103 return new SOAPFaultException(faultCode, message, cause.toString(), detail);
104 }
105 catch (SOAPException se) {
106 log.error(se+" trying to build SOAPFaultException("+faultCode+", "+message+", "+cause.toString()+")");
107 return new SOAPFaultException(faultCode, message, cause.toString(), null);
108 }
109
110 }
111
112 /***
113 * Convenience method for makeSoapFault(String, Throwable=null)
114 */
115 protected SOAPFaultException makeSoapFault(String message) {
116
117 return makeSoapFault("Server", message, null);
118 }
119
120 /***
121 * Aborts the query specified by the given id. Returns
122 * nothing - if there are any problems doing this it's a server-end problem.
123 */
124 public void abortQuery(Account user, String queryId) throws SOAPFaultException {
125 try {
126 server.abortQuery(user, queryId);
127 }
128 catch (IllegalArgumentException iae) {
129 throw makeSoapFault("Client", "Aborting "+queryId, iae);/
130
131
132
133
134
135
136
137
138
139
140 public QuerierStatus getQueryStatus(Account user, String queryId) throws RemoteException {
141 try {
142 return server.getQueryStatus(user, queryId);
143 }
144 catch (IllegalArgumentException iae) {
145 throw makeSoapFault("Client", "Aborting "+queryId, iae);/
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176