0

I need to write an XMLA proxy class on Java, which communicates with the cube (Mondrian or MS SSAS) on one side and Kendo UI PivotGrid on another. It must do 2 things:

  • make autorization on OLAP server
  • translate queries from UI to OLAP Cube and back

Kendo PivotGrid can connect directly to XMLA server, but it's not good idea because client side (browser) can read the User and Password, needed for connection. So, I decided to write proxy, which hide them.

Assuming this, could you provide some guidance on how to implemen it?

Javasick
  • 2,753
  • 1
  • 23
  • 35

1 Answers1

0

After some research, I found solution in olap4j sources. Here one chenged method, member of org.olap4j.driver.xmla.proxy.XmlaOlap4jAbstractHttpProxy class

public byte[] getResponse(String server_url, String request) throws IOException {
    URLConnection urlConnection = null;
    try {
        URL url = new URL(server_url);
        urlConnection = url.openConnection();
        urlConnection.setDoOutput(true);
        // Set headers
        urlConnection.setRequestProperty("content-type", "text/xml; charset=".concat("UTF-8"));
        urlConnection.setRequestProperty("User-Agent", "Olap4j");
        urlConnection.setRequestProperty("Accept", "text/xml;q=1");
        urlConnection.setRequestProperty("Accept-Charset", "UTF-8;q=1");
        urlConnection.setRequestProperty("Accept-Encoding", "gzip"); // Tell the server that we support gzip encoding
        // Some servers expect a SOAPAction header.
        if (request.contains("DISCOVER")) {
            urlConnection.setRequestProperty("SOAPAction", "\"urn:schemas-microsoft-com:xml-analysis:Discover\"");
        } else if (request.contains("EXECUTE")) {
            urlConnection.setRequestProperty("SOAPAction", "\"urn:schemas-microsoft-com:xml-analysis:Execute\"");
        }
        // Send data (i.e. POST). Use same encoding as specified in the
        // header.
        final String encoding1 = "UTF-8";
        urlConnection.getOutputStream().write(request.getBytes(encoding1));
        // Get the response, again assuming default encoding.
        InputStream is = urlConnection.getInputStream();
        // Detect that the server used gzip encoding
        String contentEncoding =
                urlConnection.getHeaderField("Content-Encoding");
        if ("gzip".equals(contentEncoding)) {
            is = new GZIPInputStream(is);
        }
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buf = new byte[1024];
        int count;
        while ((count = is.read(buf)) > 0) {
            baos.write(buf, 0, count);
        }
        return baos.toByteArray();
    } catch (Exception e) {
        // In order to prevent the JDK from keeping this connection
        // in WAIT mode, we need to empty the error stream cache.
        final int espCode =
                ((HttpURLConnection) urlConnection).getResponseCode();
        InputStream errorStream =
                ((HttpURLConnection) urlConnection).getErrorStream();
        final ByteArrayOutputStream baos =
                new ByteArrayOutputStream();
        final byte[] buf = new byte[1024];
        int count;
        if (errorStream != null) {
            while ((count = errorStream.read(buf)) > 0) {
                baos.write(buf, 0, count);
            }
            errorStream.close();
        }
        baos.close();
    }
    return null;
}
Javasick
  • 2,753
  • 1
  • 23
  • 35
  • I'm facing the same problem; did you manage to write the proxy? did you use the class you posted in the answer? thanks – ps0604 Sep 03 '18 at 13:42
  • @ps0604 Yeah, it works. I have changed some domain related things like security, but main idea and code still the same – Javasick Sep 04 '18 at 16:01