All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ro.nextreports.server.api.client.WebServiceClient Maven / Gradle / Ivy

Go to download

NextReports Server allows you to schedule NextReports and Jasper reports and to automatically deliver reports via E-mail, FTP, SSH, Windows Share, WebDAV to your business contacts in most popular file formats like HTML, EXCEL, PDF, RTF, CSV, TSV, TXT, XML. NextReports Server will present your charts, table reports and alarm reports in real time inside dashboards. Users can perform data analyze using drill-down and pivot structures.

There is a newer version: 9.2
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ro.nextreports.server.api.client;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import ro.nextreports.engine.queryexec.QueryParameter;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.client.filter.LoggingFilter;
import com.sun.jersey.client.urlconnection.HTTPSProperties;

/**
 * @author Decebal Suiu
 */
public class WebServiceClient {	

	protected String httpProxy;
	protected String server;
	protected String username;
	protected String password;
	protected PasswordEncoder passwordEncoder;
//	protected WebResource resource;
	protected boolean debug;
	
	protected String keystoreFile;
	protected String keyStorePass;
	protected SSLContext sslContext;
	protected KeyStore ks;
	protected SavingTrustManager tm;
	
	private static final int UNDEFINED = -1;
	private int timeout = UNDEFINED;

	public String getHttpProxy() {
		return httpProxy;
	}

	/**
	 * Format: 192.168.16.1:128 
	 * 
	 * @param httpProxy
	 */
	public void setHttpProxy(String httpProxy) {
		this.httpProxy = httpProxy;
		
		if (httpProxy == null) {
//			throw new IllegalArgumentException("'httpProxy' cannot be null");
			return;
		}
		
		String[] tokens = httpProxy.split(":");
		int count = tokens.length; 
		if (count == 1) {
			System.setProperty("http.proxyHost", tokens[0]);
		} else if (count == 2) {
			System.setProperty("http.proxyHost", tokens[0]);
			System.setProperty("http.proxyPort", tokens[1]);
		}		
	}

	public String getServer() {
		return server;
	}

	/**
	 * Format: "http://localhost:8081/api"
	 * 
	 * @param server
	 */
	public void setServer(String server) {
		this.server = server;
	}
	
	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public PasswordEncoder getPasswordEncoder() {
		return passwordEncoder;
	}

	public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
		this.passwordEncoder = passwordEncoder;
	}

	public boolean isDebug() {
		return debug;
	}

	public void setDebug(boolean debug) {
		this.debug = debug;
	}
	
	
	public void setKeystoreFile(String keystoreFile) {
		this.keystoreFile = keystoreFile;
	}

	public void setKeyStorePass(String keyStorePass) {
		this.keyStorePass = keyStorePass;
	}

	public void publishReport(ReportMetaData reportMetaData) throws WebServiceException {
		if (reportMetaData.getMainFile() == null) {
			throw new WebServiceException("No file content");
		}
				
		ClientResponse response = createRootResource().path("storage/publishReport")
			.post(ClientResponse.class, reportMetaData);

		checkForException(response);
	}

    public void publishChart(ChartMetaData chartMetaData) throws WebServiceException {
		if (chartMetaData.getMainFile() == null) {
			throw new WebServiceException("No file content");
		}

		ClientResponse response = createRootResource().path("storage/publishChart")
			.post(ClientResponse.class, chartMetaData);

		checkForException(response);
	}

    @SuppressWarnings("unchecked")
	public List getEntities(String path) throws WebServiceException {
		ClientResponse response = createRootResource().path("storage/getEntities")
			.queryParam("path", path)
			.get(ClientResponse.class);
	
		checkForException(response);
		
		return response.getEntity(List.class);
	}
	
	public void publishDataSource(DataSourceMetaData dataSourceMetaData) throws WebServiceException {
		ClientResponse response = createRootResource().path("storage/publishDataSource")
			.post(ClientResponse.class, dataSourceMetaData);

		checkForException(response);
	}
	
	public boolean isAuthorized() throws WebServiceException {
		ClientResponse response = createRootResource().path("storage").get(ClientResponse.class);
		
		if (response.getStatus() == 401) {
			return false;
		}
		
		checkForException(response);
		
		return true;
	}
	
	public boolean isAuthorized(int timeout) throws WebServiceException {
		
		this.timeout = timeout;  
		ClientResponse response = createRootResource().path("storage").get(ClientResponse.class);
		// use timeout just for isAuthorized
		this.timeout = UNDEFINED;
		
		if (response.getStatus() == 401) {
			return false;
		}
		
		checkForException(response);
		
		return true;
	}
	
	public byte getVersionStatus(String localVersion) throws WebServiceException {
		ClientResponse response = createRootResource().path("storage/version")
				.queryParam("localVersion", localVersion)
				.get(ClientResponse.class);

		checkForException(response);

		return response.getEntity(Byte.class);
	}
	
	public ReportMetaData getReport(String path) throws WebServiceException {
		ClientResponse response = createRootResource().path("storage/getReport")
			.queryParam("path", path)
			.get(ClientResponse.class);

		checkForException(response);
	
		return response.getEntity(ReportMetaData.class);		
	}

    public ChartMetaData getChart(String path) throws WebServiceException {
		ClientResponse response = createRootResource().path("storage/getChart")
			.queryParam("path", path)
			.get(ClientResponse.class);

		checkForException(response);

		return response.getEntity(ChartMetaData.class);		
	}
    
    public DataSourceMetaData getDataSource(String path) throws WebServiceException {
		ClientResponse response = createRootResource().path("storage/getDataSource")
			.queryParam("path", path)
			.get(ClientResponse.class);

		checkForException(response);

		return response.getEntity(DataSourceMetaData.class);		
	}

    public int entityExists(String path) throws WebServiceException {
		ClientResponse response = createRootResource().path("storage/entityExists")
			.queryParam("path", path)
			.get(ClientResponse.class);

		checkForException(response);

		return response.getEntity(Integer.class);				
	}
	
	public void createFolder(String path) throws WebServiceException {
		ClientResponse response = createRootResource().path("storage/createFolder")
			.post(ClientResponse.class, path);

		checkForException(response);
	}
	
	public String runReport(RunReportMetaData runReportMetaData) throws WebServiceException {
		ClientResponse response = createRootResource().path("report/runReport")
			.post(ClientResponse.class, runReportMetaData);

		checkForException(response);
	
		return response.getEntity(String.class);
	}
	
	public List getWidgetParameters(String widgetId) throws WebServiceException {
		ClientResponse response = createRootResource().path("dashboard/getWidgetParameters")
			.queryParam("widgetId", widgetId)
			.get(ClientResponse.class);
	
		checkForException(response);
		
		return response.getEntity(List.class);
	}
	
	public List getDashboards(String user) throws WebServiceException {
		ClientResponse response = createRootResource().path("dashboard/getDashboards").queryParam("user", user)
				.get(ClientResponse.class);

		checkForException(response);
		return response.getEntity(List.class);
	}
	
	public List getWidgets(String dashboardPath) throws WebServiceException {
		ClientResponse response = createRootResource().path("dashboard/getWidgets").queryParam("dashboardPath", dashboardPath)
				.get(ClientResponse.class);

		checkForException(response);
		return response.getEntity(List.class);
	}
	
	protected Client createJerseyClient() {
		ClientConfig config = new DefaultClientConfig();
//		DefaultApacheHttpClientConfig config = new DefaultApacheHttpClientConfig();  
		config.getClasses().add(XStreamXmlProvider.class);
//		ApacheHttpClient client = ApacheHttpClient.create(config);
		
		if (server.startsWith("https")) {
			log("* Use https protocol");			
			try {				
				initSSL(config);								
			} catch (Exception ex) {	
				if (tm != null) {
					try {
					    installCertificates();					    
					    initSSL(config);	
					} catch (Exception e) {
						throw new RuntimeException(e);
					}
				} else {				
					throw new RuntimeException(ex);
				}
			}
		}
		
		Client client = Client.create(config);
		
		if (isDebug()) {
			client.addFilter(new LoggingFilter());
		}
		if ((username != null) && (password != null)) {
//			client.addFilter(new HTTPBasicAuthFilter(username, password));
			String encodedPassword = password;
			if (passwordEncoder != null) {
				encodedPassword = passwordEncoder.encode(password);
			} 
			client.addFilter(new HttpBasicAuthenticationFilter(username, encodedPassword));
//			config.getState().setCredentials(null, null, -1, username, encodedPassword);
		}
		
		if (timeout != UNDEFINED) {
			client.setConnectTimeout(timeout);
		}
		
		return client;
	}
	
	protected WebResource createRootResource() {
		return createJerseyClient().resource(server);
		/*
		if (resource == null) {
			resource = createJerseyClient().resource(server);
		}
		
		return resource;
		*/
	}
	
	protected void checkForException(ClientResponse response) throws WebServiceException {
		int statusCode = response.getStatus();		
		if (!((statusCode >=200) && (statusCode < 300))) { // 2xx is OK
			log("statusCode = " + statusCode);
			throw new WebServiceException(response);
		}
	}
	
	private class NullHostnameVerifier implements HostnameVerifier {
	    public boolean verify(String hostname, SSLSession session) {
	        return true;
	    }
	}
	
	private class SavingTrustManager implements X509TrustManager {

		private final X509TrustManager tm;		
		private X509Certificate[] chain;

		SavingTrustManager(X509TrustManager tm) {
			this.tm = tm;
		}
		
		public X509Certificate[] getAcceptedIssuers() {
			return tm.getAcceptedIssuers();
		}

		public void checkClientTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
			tm.checkClientTrusted(chain,authType );
		}

		public void checkServerTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {	
			this.chain = chain;
			tm.checkServerTrusted(chain, authType);
		}
	}
	
	protected HostnameVerifier createHostnameVerifier() {
		return new NullHostnameVerifier();
	}
	
	protected SavingTrustManager createTrustManager() throws Exception {
		InputStream in = new FileInputStream(keystoreFile);
		ks = KeyStore.getInstance(KeyStore.getDefaultType());
		ks.load(in, keyStorePass.toCharArray());
		in.close();				
		TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
		tmf.init(ks);
		X509TrustManager defaultTrustManager = (X509TrustManager)tmf.getTrustManagers()[0];
		SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);		
		return tm;
	}
	
	private void initSSL(ClientConfig config) throws Exception {
		
		log("* Init SSL connection ...");		
		sslContext = SSLContext.getInstance("SSL");
		tm = createTrustManager();
		sslContext.init(null, new TrustManager[] {tm}, null);
		config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
				new HTTPSProperties(createHostnameVerifier(), sslContext));		
		
		SSLSocketFactory factory = sslContext.getSocketFactory();

		URL url = new URL(server);
		String host = url.getHost();
		int port = url.getPort();
		log("  -> Opening connection to " + host + ":" + port + "...");
		SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
		socket.setSoTimeout(10000);

		log("  -> Starting SSL handshake...");
		socket.startHandshake();
		socket.close();		
		log("  -> No errors, certificate is already trusted");		
	}
	
	private void installCertificates() throws Exception {

		log("  -> Error, certificate is not trusted");	
		log("* Install SSL certificates ...");
		URL url = new URL(server);
		String host = url.getHost();		
		X509Certificate[] chain = tm.chain;
		if (chain == null) {
			throw new Exception("Could not obtain server certificate chain.");
		}
		
		log("  -> Server sent " + chain.length + " certificate(s):");		
		OutputStream out = new FileOutputStream(keystoreFile);
		for (int i = 0; i < chain.length; i++) {
			X509Certificate cert = chain[i];
			log("       " + (i + 1) + " Subject " + cert.getSubjectDN());
			log("       Issuer  " + cert.getIssuerDN());			

			String alias = host + "-" + (i + 1);
			ks.setCertificateEntry(alias, cert);
			ks.store(out, keyStorePass.toCharArray());
			log("  -> Added certificate : " + alias);
		}
		out.close();		
	}
	
	private void log(String message) {
		System.out.println(message);
	}
		
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy