001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package org.apache.axis2.transport.http;
021:
022: import org.apache.axiom.attachments.utils.IOUtils;
023: import org.apache.axis2.AxisFault;
024: import org.apache.axis2.Constants;
025: import org.apache.axis2.addressing.EndpointReference;
026: import org.apache.axis2.context.ConfigurationContext;
027: import org.apache.axis2.context.MessageContext;
028: import org.apache.axis2.context.SessionContext;
029: import org.apache.axis2.deployment.DeploymentConstants;
030: import org.apache.axis2.description.AxisDescription;
031: import org.apache.axis2.description.AxisService;
032: import org.apache.axis2.description.Parameter;
033: import org.apache.axis2.description.PolicyInclude;
034: import org.apache.axis2.description.TransportInDescription;
035: import org.apache.axis2.transport.TransportListener;
036: import org.apache.axis2.util.ExternalPolicySerializer;
037: import org.apache.commons.logging.Log;
038: import org.apache.commons.logging.LogFactory;
039: import org.apache.neethi.Policy;
040: import org.apache.neethi.PolicyRegistry;
041: import org.apache.ws.commons.schema.XmlSchema;
042:
043: import javax.servlet.ServletException;
044: import javax.servlet.http.HttpServletRequest;
045: import javax.servlet.http.HttpServletResponse;
046: import javax.xml.stream.FactoryConfigurationError;
047: import javax.xml.stream.XMLOutputFactory;
048: import javax.xml.stream.XMLStreamException;
049: import javax.xml.stream.XMLStreamWriter;
050: import java.io.IOException;
051: import java.io.InputStream;
052: import java.io.OutputStream;
053: import java.io.OutputStreamWriter;
054: import java.util.ArrayList;
055: import java.util.HashMap;
056: import java.util.Iterator;
057: import java.util.List;
058: import java.util.Map;
059:
060: public class ListingAgent extends AbstractAgent {
061:
062: private static final Log log = LogFactory
063: .getLog(ListingAgent.class);
064:
065: private static final String LIST_MULTIPLE_SERVICE_JSP_NAME = "listServices.jsp";
066: private static final String LIST_SINGLE_SERVICE_JSP_NAME = "listSingleService.jsp";
067: private static final String LIST_FAULTY_SERVICES_JSP_NAME = "listFaultyService.jsp";
068:
069: public static final String RUNNING_PORT = "RUNNING_PORT";
070:
071: public ListingAgent(ConfigurationContext aConfigContext) {
072: super (aConfigContext);
073: }
074:
075: private void addTransportListner(String schema, int port) {
076: try {
077: TransportInDescription trsIn = configContext
078: .getAxisConfiguration().getTransportIn(schema);
079: if (trsIn == null) {
080: trsIn = new TransportInDescription(schema);
081: HTTPSListener httspReceiver = new HTTPSListener(port,
082: schema);
083: httspReceiver.init(configContext, trsIn);
084: trsIn.setReceiver(httspReceiver);
085: configContext.getListenerManager().addListener(trsIn,
086: true);
087: }
088: } catch (AxisFault axisFault) {
089: //
090: }
091: }
092:
093: public void handle(HttpServletRequest httpServletRequest,
094: HttpServletResponse httpServletResponse)
095: throws IOException, ServletException {
096:
097: initTransportListener(httpServletRequest);
098:
099: String query = httpServletRequest.getQueryString();
100: if (query != null) {
101: if (query.indexOf("wsdl2") > 0 || query.indexOf("wsdl") > 0
102: || query.indexOf("xsd") > 0
103: || query.indexOf("policy") > 0) {
104: processListService(httpServletRequest,
105: httpServletResponse);
106: } else {
107: super .handle(httpServletRequest, httpServletResponse);
108: }
109: } else {
110: super .handle(httpServletRequest, httpServletResponse);
111: }
112: }
113:
114: protected void initTransportListener(
115: HttpServletRequest httpServletRequest) {
116: // httpServletRequest.getLocalPort() , giving me a build error so I had to use the followin
117: String filePart = httpServletRequest.getRequestURL().toString();
118: int ipindex = filePart.indexOf("//");
119: String ip;
120: if (ipindex >= 0) {
121: ip = filePart.substring(ipindex + 2, filePart.length());
122: int seperatorIndex = ip.indexOf(":");
123: int slashIndex = ip.indexOf("/");
124: String portstr;
125: if (seperatorIndex >= 0) {
126: portstr = ip.substring(seperatorIndex + 1, slashIndex);
127: } else {
128: portstr = "80";
129: }
130: try {
131: addTransportListner(httpServletRequest.getScheme(),
132: Integer.parseInt(portstr));
133: } catch (NumberFormatException e) {
134: log.debug(e.toString(), e);
135: }
136: }
137: }
138:
139: protected void processListFaultyServices(HttpServletRequest req,
140: HttpServletResponse res) throws IOException,
141: ServletException {
142: String serviceName = req.getParameter("serviceName");
143: if (serviceName != null) {
144: AxisService service = configContext.getAxisConfiguration()
145: .getService(serviceName);
146: req.getSession().setAttribute(Constants.SINGLE_SERVICE,
147: service);
148: }
149: renderView(LIST_FAULTY_SERVICES_JSP_NAME, req, res);
150: }
151:
152: protected void processIndex(HttpServletRequest httpServletRequest,
153: HttpServletResponse httpServletResponse)
154: throws IOException, ServletException {
155: processListServices(httpServletRequest, httpServletResponse);
156: }
157:
158: private String extractHostAndPort(String filePart, boolean isHttp) {
159: int ipindex = filePart.indexOf("//");
160: String ip = null;
161: if (ipindex >= 0) {
162: ip = filePart.substring(ipindex + 2, filePart.length());
163: int seperatorIndex = ip.indexOf(":");
164: int slashIndex = ip.indexOf("/");
165: String port;
166: if (seperatorIndex >= 0) {
167: port = ip.substring(seperatorIndex + 1, slashIndex);
168: ip = ip.substring(0, seperatorIndex);
169: } else {
170: ip = ip.substring(0, slashIndex);
171: port = "80";
172: }
173: if (isHttp) {
174: configContext.setProperty(RUNNING_PORT, port);
175: }
176: }
177: return ip;
178: }
179:
180: public void processExplicitSchemaAndWSDL(HttpServletRequest req,
181: HttpServletResponse res) throws IOException,
182: ServletException {
183: HashMap services = configContext.getAxisConfiguration()
184: .getServices();
185: String filePart = req.getRequestURL().toString();
186: String schema = filePart.substring(
187: filePart.lastIndexOf("/") + 1, filePart.length());
188: if ((services != null) && !services.isEmpty()) {
189: Iterator i = services.values().iterator();
190: while (i.hasNext()) {
191: AxisService service = (AxisService) i.next();
192: InputStream stream = service.getClassLoader()
193: .getResourceAsStream("META-INF/" + schema);
194: if (stream != null) {
195: OutputStream out = res.getOutputStream();
196: res.setContentType("text/xml");
197: copy(stream, out);
198: out.flush();
199: out.close();
200: return;
201: }
202: }
203: }
204: }
205:
206: /**
207: * Copies the input stream to the output stream
208: *
209: * @param stream the <code>InputStream</code>
210: * @param ostream the <code>OutputStream</code>
211: */
212: public static void copy(InputStream stream, OutputStream ostream)
213: throws IOException {
214: int nextValue = stream.read();
215: while (-1 != nextValue) {
216: ostream.write(nextValue);
217: nextValue = stream.read();
218: }
219: }
220:
221: public String extractServiceName(String urlString) {
222: int n = urlString
223: .indexOf(configContext.getServiceContextPath());
224: if (n != -1) {
225: String serviceName = urlString.substring(n
226: + configContext.getServiceContextPath().length(),
227: urlString.length());
228: if (serviceName.length() > 0) {
229: if (serviceName.charAt(0) == '/') {
230: serviceName = serviceName.substring(1);
231: }
232: return serviceName;
233: }
234: }
235: return urlString.substring(urlString.lastIndexOf("/") + 1,
236: urlString.length());
237: }
238:
239: public void processListService(HttpServletRequest req,
240: HttpServletResponse res) throws IOException,
241: ServletException {
242:
243: String url = req.getRequestURL().toString();
244: String serviceName = extractServiceName(url);
245: HashMap services = configContext.getAxisConfiguration()
246: .getServices();
247: String query = req.getQueryString();
248: int wsdl2 = query.indexOf("wsdl2");
249: int wsdl = query.indexOf("wsdl");
250: int xsd = query.indexOf("xsd");
251: int policy = query.indexOf("policy");
252:
253: if ((services != null) && !services.isEmpty()) {
254: Object serviceObj = services.get(serviceName);
255: if (serviceObj != null) {
256: boolean isHttp = "http".equals(req.getScheme());
257: if (wsdl2 >= 0) {
258: res.setContentType("text/xml");
259: String ip = extractHostAndPort(url, isHttp);
260: String wsdlName = req.getParameter("wsdl2");
261: if (wsdlName != null && wsdlName.length() > 0) {
262: InputStream in = ((AxisService) serviceObj)
263: .getClassLoader().getResourceAsStream(
264: DeploymentConstants.META_INF
265: + "/" + wsdlName);
266: if (in != null) {
267: OutputStream out = res.getOutputStream();
268: out.write(IOUtils.getStreamAsByteArray(in));
269: out.flush();
270: out.close();
271: } else {
272: res
273: .sendError(HttpServletResponse.SC_NOT_FOUND);
274: }
275: } else {
276: OutputStream out = res.getOutputStream();
277: ((AxisService) serviceObj).printWSDL2(out, ip);
278: out.flush();
279: out.close();
280: }
281: return;
282: } else if (wsdl >= 0) {
283: OutputStream out = res.getOutputStream();
284: res.setContentType("text/xml");
285: String ip = extractHostAndPort(url, isHttp);
286: String wsdlName = req.getParameter("wsdl");
287:
288: if (wsdlName != null && wsdlName.length() > 0) {
289: AxisService axisServce = (AxisService) serviceObj;
290: axisServce.printUserWSDL(out, wsdlName);
291: out.flush();
292: out.close();
293: } else {
294: ((AxisService) serviceObj).printWSDL(out, ip);
295: out.flush();
296: out.close();
297: }
298: return;
299: } else if (xsd >= 0) {
300: res.setContentType("text/xml");
301: AxisService axisService = (AxisService) serviceObj;
302: //call the populator
303: axisService.populateSchemaMappings();
304: Map schemaMappingtable = axisService
305: .getSchemaMappingTable();
306: ArrayList schemas = axisService.getSchema();
307:
308: //a name is present - try to pump the requested schema
309: String xsds = req.getParameter("xsd");
310: if (!"".equals(xsds)) {
311: XmlSchema schema = (XmlSchema) schemaMappingtable
312: .get(xsds);
313: if (schema == null) {
314: int dotIndex = xsds.indexOf('.');
315: if (dotIndex > 0) {
316: String schemaKey = xsds.substring(0,
317: dotIndex);
318: schema = (XmlSchema) schemaMappingtable
319: .get(schemaKey);
320: }
321: }
322: if (schema != null) {
323: //schema is there - pump it outs
324: OutputStream out = res.getOutputStream();
325: schema.write(new OutputStreamWriter(out,
326: "UTF8"));
327: out.flush();
328: out.close();
329: } else {
330: InputStream in = axisService
331: .getClassLoader()
332: .getResourceAsStream(
333: DeploymentConstants.META_INF
334: + "/" + xsds);
335: if (in != null) {
336: OutputStream out = res
337: .getOutputStream();
338: out.write(IOUtils
339: .getStreamAsByteArray(in));
340: out.flush();
341: out.close();
342: } else {
343: res
344: .sendError(HttpServletResponse.SC_NOT_FOUND);
345: }
346: }
347:
348: //multiple schemas are present and the user specified
349: //no name - in this case we cannot possibly pump a schema
350: //so redirect to the service root
351: } else if (schemas.size() > 1) {
352: res.sendRedirect("");
353: //user specified no name and there is only one schema
354: //so pump that out
355: } else {
356: ArrayList list = axisService.getSchema();
357: if (list.size() > 0) {
358: XmlSchema schema = axisService.getSchema(0);
359: if (schema != null) {
360: OutputStream out = res
361: .getOutputStream();
362: schema.write(new OutputStreamWriter(
363: out, "UTF8"));
364: out.flush();
365: out.close();
366: }
367: } else {
368: res.setContentType("text/xml");
369: String xsdNotFound = "<error>"
370: + "<description>Unable to access schema for this service</description>"
371: + "</error>";
372: OutputStream out = res.getOutputStream();
373: out.write(xsdNotFound.getBytes());
374: out.flush();
375: out.close();
376: }
377: }
378: return;
379: } else if (policy >= 0) {
380:
381: ExternalPolicySerializer serializer = new ExternalPolicySerializer();
382: serializer.setAssertionsToFilter(configContext
383: .getAxisConfiguration()
384: .getLocalPolicyAssertions());
385:
386: // check whether Id is set
387: String idParam = req.getParameter("id");
388:
389: if (idParam != null) {
390: // Id is set
391:
392: Policy targetPolicy = findPolicy(idParam,
393: (AxisService) serviceObj);
394:
395: if (targetPolicy != null) {
396: XMLStreamWriter writer;
397:
398: try {
399: OutputStream out = res
400: .getOutputStream();
401: writer = XMLOutputFactory.newInstance()
402: .createXMLStreamWriter(out);
403:
404: res
405: .setContentType("application/wspolicy+xml");
406: targetPolicy.serialize(writer);
407: writer.flush();
408:
409: } catch (XMLStreamException e) {
410: throw new ServletException(
411: "Error occured when serializing the Policy",
412: e);
413:
414: } catch (FactoryConfigurationError e) {
415: throw new ServletException(
416: "Error occured when serializing the Policy",
417: e);
418: }
419:
420: } else {
421:
422: OutputStream out = res.getOutputStream();
423: res.setContentType("text/html");
424: String outStr = "<b>No policy found for id="
425: + idParam + "</b>";
426: out.write(outStr.getBytes());
427: }
428:
429: } else {
430:
431: PolicyInclude policyInclude = ((AxisService) serviceObj)
432: .getPolicyInclude();
433: Policy effecPolicy = policyInclude
434: .getEffectivePolicy();
435:
436: if (effecPolicy != null) {
437: XMLStreamWriter writer;
438:
439: try {
440: OutputStream out = res
441: .getOutputStream();
442: writer = XMLOutputFactory.newInstance()
443: .createXMLStreamWriter(out);
444:
445: res
446: .setContentType("application/wspolicy+xml");
447: effecPolicy.serialize(writer);
448: writer.flush();
449:
450: } catch (XMLStreamException e) {
451: throw new ServletException(
452: "Error occured when serializing the Policy",
453: e);
454:
455: } catch (FactoryConfigurationError e) {
456: throw new ServletException(
457: "Error occured when serializing the Policy",
458: e);
459: }
460: } else {
461:
462: OutputStream out = res.getOutputStream();
463: res.setContentType("text/html");
464: String outStr = "<b>No effective policy for "
465: + serviceName + " servcie</b>";
466: out.write(outStr.getBytes());
467: }
468: }
469:
470: return;
471: } else {
472: req.getSession().setAttribute(
473: Constants.SINGLE_SERVICE, serviceObj);
474: }
475: } else {
476: req.getSession().setAttribute(Constants.SINGLE_SERVICE,
477: null);
478: res.sendError(HttpServletResponse.SC_NOT_FOUND, url);
479: }
480: }
481:
482: renderView(LIST_SINGLE_SERVICE_JSP_NAME, req, res);
483: }
484:
485: protected void processListServices(HttpServletRequest req,
486: HttpServletResponse res) throws IOException,
487: ServletException {
488:
489: populateSessionInformation(req);
490: req.getSession().setAttribute(
491: Constants.ERROR_SERVICE_MAP,
492: configContext.getAxisConfiguration()
493: .getFaultyServices());
494:
495: renderView(LIST_MULTIPLE_SERVICE_JSP_NAME, req, res);
496: }
497:
498: private Policy findPolicy(String id, AxisDescription des) {
499:
500: List policyElements = des.getPolicyInclude()
501: .getPolicyElements();
502: PolicyRegistry registry = des.getPolicyInclude()
503: .getPolicyRegistry();
504:
505: Object policyComponent;
506:
507: Policy policy = registry.lookup(id);
508:
509: if (policy != null) {
510: return policy;
511: }
512:
513: for (Iterator iterator = policyElements.iterator(); iterator
514: .hasNext();) {
515: policyComponent = iterator.next();
516:
517: if (policyComponent instanceof Policy) {
518: // policy found for the id
519:
520: if (id.equals(((Policy) policyComponent).getId())) {
521: return (Policy) policyComponent;
522: }
523: }
524: }
525:
526: AxisDescription child;
527:
528: for (Iterator iterator = des.getChildren(); iterator.hasNext();) {
529: child = (AxisDescription) iterator.next();
530: policy = findPolicy(id, child);
531:
532: if (policy != null) {
533: return policy;
534: }
535: }
536:
537: return null;
538: }
539:
540: /**
541: * This class is just to add tarnsport at the runtime if user send requet using
542: * diffrent schemes , simly to handle http/https seperetaly
543: */
544: private class HTTPSListener implements TransportListener {
545:
546: private int port;
547: private String schema;
548: private ConfigurationContext axisConf;
549:
550: public HTTPSListener(int port, String schema) {
551: this .port = port;
552: this .schema = schema;
553: }
554:
555: public void init(ConfigurationContext axisConf,
556: TransportInDescription transprtIn) throws AxisFault {
557: this .axisConf = axisConf;
558: Parameter param = transprtIn.getParameter(PARAM_PORT);
559: if (param != null) {
560: this .port = Integer.parseInt((String) param.getValue());
561: }
562: }
563:
564: public void start() throws AxisFault {
565: }
566:
567: public void stop() throws AxisFault {
568: }
569:
570: public EndpointReference[] getEPRsForService(
571: String serviceName, String ip) throws AxisFault {
572: String path = axisConf.getServiceContextPath() + "/"
573: + serviceName;
574: if (path.charAt(0) != '/') {
575: path = '/' + path;
576: }
577: return new EndpointReference[] { new EndpointReference(
578: schema + "://" + ip + ":" + port + path) };
579: }
580:
581: public EndpointReference getEPRForService(String serviceName,
582: String ip) throws AxisFault {
583: return getEPRsForService(serviceName, ip)[0];
584: }
585:
586: public SessionContext getSessionContext(
587: MessageContext messageContext) {
588: HttpServletRequest req = (HttpServletRequest) messageContext
589: .getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);
590: SessionContext sessionContext = (SessionContext) req
591: .getSession(true).getAttribute(
592: Constants.SESSION_CONTEXT_PROPERTY);
593: String sessionId = req.getSession().getId();
594: if (sessionContext == null) {
595: sessionContext = new SessionContext(null);
596: sessionContext.setCookieID(sessionId);
597: req.getSession().setAttribute(
598: Constants.SESSION_CONTEXT_PROPERTY,
599: sessionContext);
600: }
601: messageContext.setSessionContext(sessionContext);
602: messageContext.setProperty(AxisServlet.SESSION_ID,
603: sessionId);
604: return sessionContext;
605: }
606:
607: public void destroy() {
608: }
609:
610: }
611:
612: }
|