summaryrefslogtreecommitdiffstats
path: root/petascope/src/petascope/wcst/transaction/executeAsyncTransaction.java
blob: b1f2766e722554648c479dd17d1048a400a3a9e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
 * This file is part of rasdaman community.
 *
 * Rasdaman community is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Rasdaman community is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with rasdaman community.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
 rasdaman GmbH.
 *
 * For more information please see <http://www.rasdaman.org>
 * or contact Peter Baumann via <baumann@rasdaman.com>.
 */
package petascope.wcst.transaction;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;
import net.opengis.ows.v_1_0_0.ExceptionReport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import petascope.wcs.server.exceptions.BadResponseHandlerException;
import petascope.wcs.server.exceptions.InputOutputException;
import petascope.wcs.server.exceptions.WCSException;
import petascope.wcs.server.exceptions.XmlStructuresException;
import wcst.transaction.schema.TransactionResponseType;

/**
 * This class processes asynchronously an WCS Transaction request. 
 *
 * @author Andrei Aiordachioaie
 */
public class executeAsyncTransaction extends Thread {

    private static Logger LOG = LoggerFactory.getLogger(executeAsyncTransaction.class);
    private String responseHandler;
    private executeTransaction exec;

    /**
     * Default constructor.
     * @param exec a synchroneous executeTransaction object
     * @param responseHandler destination URL that should receive the processed output
     */
    public executeAsyncTransaction(executeTransaction exec, String responseHandler) {
        this.responseHandler = responseHandler;
        this.exec = exec;
    }

    /** Run the current thread. */
    public void run() {
        LOG.info("Started async thread...");
        String outString = null;
        try // only for WCSException
        {
            try {
                /* (1) Do the actual processing of the Transaction */
                LOG.debug("Starting async execution ...");
                TransactionResponseType output = exec.get();
                JAXBElement jaxbOutput = new JAXBElement(new QName("", "TransactionResponse"), TransactionResponseType.class, output);

                /* (2) Marshall the output XML into a String */
                LOG.debug("Marshalling transaction response into a string ...");
                JAXBContext jaxbCtx = JAXBContext.newInstance(output.getClass().getPackage().getName());
                Marshaller marshaller = jaxbCtx.createMarshaller();
                marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); //NOI18N
                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
                StringWriter strWriter = new StringWriter();

                marshaller.marshal(jaxbOutput, strWriter);
                outString = strWriter.toString();

                /* (3) Send the output to the destination response handler */
                sendPostRequest(outString, responseHandler);
            } catch (MalformedURLException ex) {
                LOG.error("Stack trace: " + ex);
                throw new BadResponseHandlerException("Response Handler URL is malformed.");
            } catch (IOException ex) {
                LOG.error("Stack trace: " + ex);
                throw new InputOutputException("Could not send asynchronous response to URL: " + responseHandler);
            } catch (JAXBException ex) {
                LOG.error("Stack trace: " + ex);
                throw new XmlStructuresException("Could not marshall the XML to a string !");
            }
        } catch (WCSException e) {
            LOG.error("Caught WCS Exception: " + e);
            ExceptionReport report = e.getReport();
            try {
                /* Build the error report */
                JAXBContext jaxbCtx = JAXBContext.newInstance(report.getClass().getPackage().getName());
                Marshaller marshaller = jaxbCtx.createMarshaller();
                marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
                StringWriter strWriter = new StringWriter();
                marshaller.marshal(report, strWriter);
                outString = strWriter.toString();
                LOG.trace("Done with the Error Report !");

                /* Send the error report to the responseHandler */
                sendPostRequest(outString, responseHandler);
            } catch (JAXBException e2) {
                LOG.error("Stack trace: " + e2);
            } catch (IOException e2) {
                LOG.error("Stack trace: " + e2);
            }
        }
    }

    /** Send string data to a URL end-point. Use this function to send the output 
     *
     * @param content
     * @param destinationUrl
     * @throws MalformedURLException
     * @throws IOException
     */
    private void sendPostRequest(String content, String destinationUrl) throws MalformedURLException, IOException {
        LOG.debug("sendPostRequest() ... to URL: " + destinationUrl);

        // connect to the destination 
        URL servlet = new URL(destinationUrl);
        HttpURLConnection conn = (HttpURLConnection) servlet.openConnection();

        // inform the connection that we will send output and will not accept input
        conn.setDoInput(false);
        conn.setDoOutput(true);

        // Don't use a cached version of URL connection.
        conn.setUseCaches(false);
        conn.setDefaultUseCaches(false);

        // Send POST request
        conn.setRequestMethod("POST");

        // Specify the content type that we will send binary data
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

        String data = "xml=" + URLEncoder.encode(content);
        DataOutputStream out = new DataOutputStream(conn.getOutputStream());

        out.writeBytes(data);
        out.flush();
        out.close();

        LOG.debug("Sent request to URL.");
    }
}