Issue #1786 - Initial checkin of https for thin client

Code review comments

Change-Id: I1fde9a276ecca44d87603be08a99232a5d7b441e

Former-commit-id: 0a33734e6f [formerly 6f206dad8ffbbd7b793b92b8a23bbce74a5b0017]
Former-commit-id: b9abbcdf37
This commit is contained in:
Mike Duff 2013-04-01 10:13:05 -05:00
parent 4c3dfc910c
commit f584e17aa7
42 changed files with 2140 additions and 177 deletions

View file

@ -34,7 +34,7 @@ Require-Bundle: org.eclipse.ui,
com.raytheon.uf.common.geospatial;bundle-version="1.12.1174"
Bundle-ActivationPolicy: lazy
Eclipse-BuddyPolicy: ext, registered, global
Eclipse-RegisterBuddy: org.apache.velocity, org.apache.log4j, com.raytheon.edex.common, com.raytheon.uf.common.serialization, com.raytheon.uf.common.serialization.comm, com.raytheon.uf.common.status, com.raytheon.uf.common.dataplugin.level
Eclipse-RegisterBuddy: org.apache.velocity, org.apache.log4j, com.raytheon.edex.common, com.raytheon.uf.common.serialization, com.raytheon.uf.common.serialization.comm, com.raytheon.uf.common.status, com.raytheon.uf.common.dataplugin.level, com.raytheon.uf.common.comm
Export-Package: com.raytheon.uf.viz.core,
com.raytheon.uf.viz.core.alerts,
com.raytheon.uf.viz.core.auth,

View file

@ -8,12 +8,18 @@
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<bean id="caveCredentialHandler" class="com.raytheon.uf.viz.core.comm.CaveHttpsCredentialsHandler" />
<bean id="httpsConfiguration" class="com.raytheon.uf.viz.core.comm.HttpsConfiguration" />
<bean id="httpClient" class="com.raytheon.uf.common.comm.HttpClient" factory-method="getInstance">
<property name="socketTimeout" value="330000"/>
<property name="connectionTimeout" value="10000"/>
<property name="maxConnectionsPerHost" value="10"/>
<property name="compressRequests" value="false"/>
<property name="gzipResponseHandling" value="false"/>
<property name="handler" ref="caveCredentialHandler" />
<property name="httpsConfiguration" ref="httpsConfiguration" />
</bean>
<bean id="baosPool" class="com.raytheon.uf.common.util.ByteArrayOutputStreamPool" factory-method="getInstance">

View file

@ -0,0 +1,57 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.core.comm;
import com.raytheon.uf.common.comm.IHttpsCredentialsHandler;
/**
* Cave implementation of the IHttpsCredentialsHandler. Displays the Cave login
* dialog to get the authorization credentials.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 4, 2013 1786 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class CaveHttpsCredentialsHandler implements IHttpsCredentialsHandler {
/**
* {@inheritDoc}
*/
@Override
public String[] getCredentials(String message) {
// If message contains an "=" split and take the value of the pair
if (message.contains("=")) {
message = message.split("=")[1];
}
HttpsLoginDlg login = new HttpsLoginDlg(message);
login.open();
return login.getCredentials();
}
}

View file

@ -19,14 +19,14 @@
**/
package com.raytheon.uf.viz.core.comm;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.net.URI;
import javax.jms.JMSException;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.http.client.methods.HttpGet;
import com.raytheon.uf.common.comm.HttpClient;
/**
* Class for checking connectivity of http servers, currently only used for
@ -43,6 +43,7 @@ import org.apache.activemq.ActiveMQConnectionFactory;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 12, 2009 mschenke Initial creation
* Mar 22, 2013 1786 mpduff Changed to use HttpClient for connectivity.
*
* </pre>
*
@ -71,16 +72,14 @@ public class ConnectivityManager {
* @return whether quit was selected. TODO: need to return two booleans, one
* for quit and one for connectivity
*/
public static void checkServer(String server, IConnectivityCallback callback) {
boolean good = true;
public static void checkHttpServer(String server, IConnectivityCallback callback) {
boolean good = false;
try {
new URL(server).openStream().close();
} catch (ConnectException e) {
good = false;
} catch (MalformedURLException e) {
good = false;
} catch (UnknownHostException e) {
good = false;
HttpClient client = HttpClient.getInstance();
HttpGet request = new HttpGet();
request.setURI(new URI(server));
client.executeRequest(request);
good = true;
} catch (Exception e) {
// ignore
}

View file

@ -0,0 +1,106 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.core.comm;
import java.net.URI;
import java.net.URISyntaxException;
import com.raytheon.uf.common.comm.IHttpsConfiguration;
import com.raytheon.uf.viz.core.localization.LocalizationManager;
/**
* Https Configuration Class.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 9, 2013 1786 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class HttpsConfiguration implements IHttpsConfiguration {
private int httpsPort = 443;
private int httpPort = 80;
/**
* Constructor.
*/
public HttpsConfiguration() {
init();
}
private void init() {
String localizationServer = LocalizationManager.getInstance()
.getLocalizationServer();
try {
URI uri = new URI(localizationServer);
if (uri.getScheme().equals("http")) {
httpPort = uri.getPort();
} else if (uri.getScheme().equals("https")) {
httpsPort = uri.getPort();
if (httpsPort == -1) {
httpsPort = 443; // The default https port
}
} else {
throw new URISyntaxException(uri.toString(), "Invalid server");
}
} catch (URISyntaxException e) {
System.err.println("Invalid localization server setting.");
}
}
/**
* {@inheritDoc}
*/
@Override
public int getHttpsPort() {
return httpsPort;
}
/**
* {@inheritDoc}
*/
@Override
public int getHttpPort() {
return httpPort;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("HTTP Port: ").append(this.httpPort).append("\n");
sb.append("HTTPS Port: ").append(this.httpsPort).append("\n");
return sb.toString();
}
}

View file

@ -0,0 +1,226 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.core.comm;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
/**
* CAVE Login Dialog.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 6, 2013 1786 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class HttpsLoginDlg extends Dialog {
private static final long serialVersionUID = 1L;
private Shell shell;
private Display display;
/** User name text field */
private Text userText;
/** Password text field */
private Text passwdText;
/** Array of User name and Password */
private String[] returnValue;
/** Authorization message */
private final String message;
/**
* Constructor
*
* @param message
* Message from server
*/
public HttpsLoginDlg(String message) {
super(new Shell(Display.getDefault(), SWT.TITLE));
this.message = message;
}
/**
* Open the dialog.
*/
public void open() {
Shell parent = getParent();
display = parent.getDisplay();
shell = new Shell(parent, SWT.DIALOG_TRIM);
shell.setText("Log in");
// Create the main layout for the shell.
GridLayout mainLayout = new GridLayout(1, true);
shell.setLayout(mainLayout);
init();
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
/**
* Build the gui
*/
private void init() {
Composite comp = new Composite(shell, SWT.NONE);
comp.setLayout(new GridLayout(2, false));
GridData gd = new GridData(SWT.RIGHT, SWT.None, true, true);
gd.widthHint = 500;
gd.horizontalSpan = 2;
Label authMessage = new Label(comp, SWT.CENTER);
authMessage.setText(this.message);
authMessage.setLayoutData(gd);
Label userIdLbl = new Label(comp, SWT.LEFT);
userIdLbl.setText("User Name: ");
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, true);
userText = new Text(comp, SWT.BORDER);
userText.setLayoutData(gd);
Label passLbl = new Label(comp, SWT.LEFT);
passLbl.setText("Password: ");
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, true);
passwdText = new Text(comp, SWT.BORDER);
passwdText.setEchoChar('*');
passwdText.setLayoutData(gd);
Composite buttonComp = new Composite(shell, SWT.NONE);
GridLayout gl = new GridLayout(2, false);
buttonComp.setLayout(gl);
gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
buttonComp.setLayoutData(gd);
gd = new GridData(80, SWT.DEFAULT);
Button okBtn = new Button(buttonComp, SWT.NONE);
okBtn.setText("OK");
okBtn.setLayoutData(gd);
shell.setDefaultButton(okBtn);
okBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
if (validateEntries()) {
returnValue = new String[] { userText.getText().trim(),
passwdText.getText().trim() };
}
shell.dispose();
}
});
gd = new GridData(80, SWT.DEFAULT);
Button cancelBtn = new Button(buttonComp, SWT.NONE);
cancelBtn.setText("Cancel");
cancelBtn.setLayoutData(gd);
cancelBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
cancel();
}
});
}
/**
* Validate the entries.
*
* @return true if entries are valid
*/
private boolean validateEntries() {
boolean valid = true;
if (this.userText.getText().trim().isEmpty()) {
valid = false;
}
if (this.passwdText.getText().trim().isEmpty()) {
valid = false;
}
return valid;
}
/**
* Get the user's credentials
*
* @return String array of Username and password
*/
public String[] getCredentials() {
return returnValue;
}
/**
* Cancel action
*/
private void cancel() {
// Check if CAVE is running and exit if it is not
if (!PlatformUI.isWorkbenchRunning()) {
System.exit(0);
}
shell.dispose();
}
/**
* Main for testing
*
* @param args
* args
*/
public static void main(String[] args) {
HttpsLoginDlg loginDlg = new HttpsLoginDlg(
"AWIPS II Thin Client Proxy: Use NOAA email address and password");
loginDlg.open();
String[] credentials = loginDlg.getCredentials();
if (credentials != null) {
System.out.println(credentials[0] + " " + credentials[1]);
} else {
System.out.println("Nothing entered");
}
}
}

View file

@ -363,7 +363,7 @@ public class ConnectivityPreferenceDialog extends Dialog {
}
private void validateLocalization() {
ConnectivityManager.checkServer(localization, localizationCallback);
ConnectivityManager.checkHttpServer(localization, localizationCallback);
}
private void validateAlertviz() {

View file

@ -217,7 +217,7 @@ public class LocalizationPreferences extends FieldEditorPreferencePage
private void checkConnectivity() {
final ConnectivityResult result = new ConnectivityResult(false, "");
Text text = localizationEditor.getTextControl(getFieldEditorParent());
ConnectivityManager.checkServer(text.getText().trim(),
ConnectivityManager.checkHttpServer(text.getText().trim(),
new IConnectivityCallback() {
@Override
public void connectionChecked(ConnectivityResult results) {

View file

@ -83,7 +83,7 @@ public class LocalizationServerEditor extends StringFieldEditor implements
@Override
protected boolean doCheckState() {
if (httpCheck) {
ConnectivityManager.checkServer(this.getTextControl().getText(),
ConnectivityManager.checkHttpServer(this.getTextControl().getText(),
this);
} else {
ConnectivityManager.checkJmsServer(this.getTextControl().getText(),

View file

@ -124,8 +124,6 @@ public class SystemRuleManager {
*/
private SystemRuleManager() {
createContext();
loadLatencyRules();
loadPriorityRules();
}
/**
@ -409,6 +407,10 @@ public class SystemRuleManager {
*/
private LatencyRulesXML getLatencyRules(boolean reread) {
if (latencyRules == null || reread) {
if (latencyRulesLocFile == null) {
loadLatencyRules();
}
if (this.latencyRulesLocFile != null
&& latencyRulesLocFile.exists()) {
try {
@ -434,7 +436,11 @@ public class SystemRuleManager {
* @return The priority rules xml object
*/
private PriorityRulesXML getPriorityRules(boolean reread) {
if (priorityRules == null || reread)
if (priorityRules == null || reread) {
if (priorityRulesLocFile == null) {
loadPriorityRules();
}
if (this.priorityRulesLocFile != null
&& priorityRulesLocFile.exists()) {
try {
@ -446,7 +452,7 @@ public class SystemRuleManager {
priorityRules = new PriorityRulesXML();
}
}
}
return priorityRules;
}

View file

@ -7,6 +7,7 @@ Bundle-Activator: com.raytheon.uf.viz.spring.dm.Activator
Bundle-Vendor: RAYTHEON
Require-Bundle: org.eclipse.core.runtime,
org.springframework;bundle-version="2.5.6",
org.apache.commons.logging;bundle-version="1.1.1"
org.apache.commons.logging;bundle-version="1.1.1",
com.raytheon.uf.common.comm;bundle-version="1.12.1174"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy

View file

@ -135,7 +135,7 @@ public class ThinClientServerPreferences extends FieldEditorPreferencePage {
// check HTTP Server
Text text = servicesServer.getTextControl(getFieldEditorParent());
ConnectivityManager.checkServer(text.getText().trim(),
ConnectivityManager.checkHttpServer(text.getText().trim(),
new IConnectivityCallback() {
@Override
public void connectionChecked(ConnectivityResult results) {
@ -154,7 +154,7 @@ public class ThinClientServerPreferences extends FieldEditorPreferencePage {
// check Pypies Server
Text textPypies = pypiesServer.getTextControl(getFieldEditorParent());
ConnectivityManager.checkServer(textPypies.getText().trim(),
ConnectivityManager.checkHttpServer(textPypies.getText().trim(),
new IConnectivityCallback() {
@Override
public void connectionChecked(ConnectivityResult results) {

View file

@ -237,11 +237,11 @@ public class ThinClientConnectivityDialog extends ConnectivityPreferenceDialog {
}
private void validateServices() {
ConnectivityManager.checkServer(services, servicesCallback);
ConnectivityManager.checkHttpServer(services, servicesCallback);
}
private void validatePypies() {
ConnectivityManager.checkServer(pypies, pypiesCallback);
ConnectivityManager.checkHttpServer(pypies, pypiesCallback);
}
private void updateProxyEnabled() {

View file

@ -12,14 +12,39 @@ Require-Bundle: org.apache.commons.codec,
Bundle-Vendor: Raytheon-bundled OSS
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Export-Package: org.apache.http,
org.apache.http.annotation,
org.apache.http.auth,
org.apache.http.auth.params,
org.apache.http.client,
org.apache.http.client.cache,
org.apache.http.client.entity,
org.apache.http.client.methods,
org.apache.http.client.params,
org.apache.http.client.protocol,
org.apache.http.client.utils,
org.apache.http.conn,
org.apache.http.conn.params,
org.apache.http.conn.routing,
org.apache.http.conn.scheme,
org.apache.http.conn.ssl,
org.apache.http.conn.util,
org.apache.http.cookie,
org.apache.http.cookie.params,
org.apache.http.entity,
org.apache.http.entity.mime,
org.apache.http.entity.mime.content,
org.apache.http.impl,
org.apache.http.impl.auth,
org.apache.http.impl.client,
org.apache.http.impl.client.cache,
org.apache.http.impl.client.cache.ehcache,
org.apache.http.impl.client.cache.memcached,
org.apache.http.impl.conn,
org.apache.http.impl.conn.tsccm,
org.apache.http.impl.cookie,
org.apache.http.impl.entity,
org.apache.http.impl.io,
org.apache.http.io,
org.apache.http.message,
org.apache.http.params,
org.apache.http.protocol,

View file

@ -103,4 +103,4 @@
<taskdef resource="net/sf/antcontrib/antlib.xml"
classpath="${basedir}/lib/ant/ant-contrib-1.0b3.jar" />
</project>
</project>

View file

@ -10,6 +10,8 @@ Require-Bundle: org.apache.http,
com.raytheon.uf.common.util,
com.raytheon.uf.common.auth;bundle-version="1.12.1174",
com.raytheon.uf.common.serialization;bundle-version="1.12.1174",
com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174"
com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174",
com.raytheon.uf.common.time;bundle-version="1.12.1174"
Export-Package: com.raytheon.uf.common.comm,
com.raytheon.uf.common.comm.stream
Eclipse-BuddyPolicy: ext, registered, global

View file

@ -24,26 +24,49 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.GZIPOutputStream;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.AbstractHttpEntity;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.HttpConnectionParams;
@ -78,6 +101,7 @@ import com.raytheon.uf.common.util.ByteArrayOutputStreamPool.ByteArrayOutputStre
* Jan 24, 2013 1526 njensen Added postDynamicSerialize()
* Feb 20, 2013 1628 bsteffen clean up Inflaters used by
* HttpClient.
* Mar 11, 2013 1786 mpduff Add https capability.
*
* </pre>
*
@ -85,7 +109,6 @@ import com.raytheon.uf.common.util.ByteArrayOutputStreamPool.ByteArrayOutputStre
* @version 1
*/
public class HttpClient {
public static class HttpClientResponse {
public final int code;
@ -97,13 +120,213 @@ public class HttpClient {
}
}
/**
* This is using the initialization on demand holder pattern to lazily
* initialize the singleton instance of DefaultHttpClient.
*
* http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom
*/
private static class HttpsHolder {
private static final DefaultHttpClient sslClient;
static {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
// blank
}
@Override
public void checkServerTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
// blank
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
X509HostnameVerifier verifier = new X509HostnameVerifier() {
@Override
public void verify(String string, X509Certificate xc)
throws SSLException {
// blank
}
@Override
public void verify(String string, String[] strings,
String[] strings1) throws SSLException {
// blank
}
@Override
public void verify(String arg0, SSLSocket arg1)
throws IOException {
// blank
}
@Override
public boolean verify(String arg0, SSLSession arg1) {
// always return true to accept the self signed cert
return true;
}
};
ctx.init(null, new TrustManager[] { tm }, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx, verifier);
SchemeRegistry registry = new SchemeRegistry();
// registry.register(new Scheme("https", 443, ssf));
IHttpsConfiguration httpsConf = HttpClient.getInstance()
.getHttpsConfiguration();
if (httpsConf == null) {
throw new ExceptionInInitializerError(
"Https configuration required.");
}
registry.register(new Scheme("https", httpsConf.getHttpsPort(),
ssf));
registry.register(new Scheme("http", httpsConf.getHttpPort(),
new PlainSocketFactory()));
sslClient = new DefaultHttpClient(
new ThreadSafeClientConnManager(registry));
sslClient.addRequestInterceptor(new HttpRequestInterceptor() {
@Override
public void process(final HttpRequest request,
final HttpContext context) throws HttpException,
IOException {
if (request.getFirstHeader("Content-Length") != null) {
logBytes(
Long.valueOf(request.getFirstHeader(
"Content-Length").getValue()), 0);
}
}
});
sslClient.addResponseInterceptor(new HttpResponseInterceptor() {
@Override
public void process(final HttpResponse response,
final HttpContext context) throws HttpException,
IOException {
logBytes(0, response.getEntity().getContentLength());
}
});
// Set the proxy info
ProxyConfiguration proxySettings = ProxyUtil.getProxySettings();
if (proxySettings != null) {
String proxyHost = proxySettings.getHost();
int proxyPort = proxySettings.getPort();
HttpHost proxy = new HttpHost(proxyHost, proxyPort);
sslClient.getParams().setParameter(
ConnRoutePNames.DEFAULT_PROXY, proxy);
}
((ThreadSafeClientConnManager) sslClient.getConnectionManager())
.setDefaultMaxPerRoute(instance
.getMaxConnectionsPerHost());
HttpConnectionParams.setTcpNoDelay(sslClient.getParams(), true);
HttpConnectionParams.setSoTimeout(sslClient.getParams(),
instance.getSocketTimeout());
HttpConnectionParams.setConnectionTimeout(
sslClient.getParams(), instance.getConnectionTimeout());
HttpsHolder.sslClient.getParams().setParameter(
"http.protocol.expect-continue", true);
if (instance.isGzipResponseHandling()) {
// Add gzip compression handlers
// advertise we accept gzip
sslClient
.addRequestInterceptor(new GzipRequestInterceptor());
// handle gzip contents
sslClient
.addResponseInterceptor(new GzipResponseInterceptor());
}
} catch (KeyManagementException e) {
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
e);
throw new ExceptionInInitializerError(
"Error setting up SSL Client");
} catch (NoSuchAlgorithmException e) {
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
e);
throw new ExceptionInInitializerError(
"Error setting up SSL Client");
}
}
}
/**
* This is using the initialization on demand holder pattern to lazily
* initialize the singleton instance of DefaultHttpClient.
*
* http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom
*/
private static class HttpHolder {
private static final DefaultHttpClient client;
static {
client = new DefaultHttpClient(new ThreadSafeClientConnManager());
client.addRequestInterceptor(new HttpRequestInterceptor() {
@Override
public void process(final HttpRequest request,
final HttpContext context) throws HttpException,
IOException {
if (request.getFirstHeader("Content-Length") != null) {
logBytes(
Long.valueOf(request.getFirstHeader(
"Content-Length").getValue()), 0);
}
}
});
client.addResponseInterceptor(new HttpResponseInterceptor() {
@Override
public void process(final HttpResponse response,
final HttpContext context) throws HttpException,
IOException {
logBytes(0, response.getEntity().getContentLength());
}
});
connManager = client.getConnectionManager();
((ThreadSafeClientConnManager) connManager)
.setDefaultMaxPerRoute(instance.getMaxConnections());
HttpConnectionParams.setConnectionTimeout(client.getParams(),
instance.getConnectionTimeout());
HttpConnectionParams.setTcpNoDelay(client.getParams(), true);
HttpConnectionParams.setSoTimeout(client.getParams(),
instance.getSocketTimeout());
if (instance.isGzipResponseHandling()) {
// Add gzip compression handlers
// advertise we accept gzip
client.addRequestInterceptor(new GzipRequestInterceptor());
// handle gzip contents
client.addResponseInterceptor(new GzipResponseInterceptor());
}
}
}
private static final int SUCCESS_CODE = 200;
private final org.apache.http.client.HttpClient client;
private static final String HTTPS = "https";
private static final String WWW_AUTHENTICATE = "WWW-Authenticate";
private boolean previousConnectionFailed;
private static HttpClient instance;
private static final HttpClient instance = new HttpClient();
/**
* Number of times to retry in the event of a connection exception. Default
@ -114,7 +337,9 @@ public class HttpClient {
private static final IUFStatusHandler statusHandler = UFStatus.getHandler(
HttpClient.class, "DEFAULT");
private ThreadSafeClientConnManager connManager = null;
private static ClientConnectionManager connManager = null;
private final ClientConnectionManager sslConnManager = null;
private final NetworkStatistics stats = new NetworkStatistics();
@ -125,43 +350,40 @@ public class HttpClient {
/** number of requests currently in process by the application per host */
private final Map<String, AtomicInteger> currentRequestsCount = new ConcurrentHashMap<String, AtomicInteger>();
private int socketTimeout = 330000;
private int connectionTimeout = 10000;
private int maxConnections = 10;
private IHttpsCredentialsHandler handler;
private IHttpsConfiguration httpsConfiguration;
/**
* Private constructor.
*/
private HttpClient() {
connManager = new ThreadSafeClientConnManager();
DefaultHttpClient client = new DefaultHttpClient(connManager);
}
client.addRequestInterceptor(new HttpRequestInterceptor() {
private org.apache.http.client.HttpClient getHttpsInstance() {
return HttpsHolder.sslClient;
}
@Override
public void process(final HttpRequest request,
final HttpContext context) throws HttpException,
IOException {
try {
stats.log(
Long.valueOf(request.getFirstHeader(
"Content-Length").getValue()), 0);
} catch (Throwable t) {
// Ignore any errors when logging
}
}
private org.apache.http.client.HttpClient getHttpInstance() {
return HttpHolder.client;
}
});
private static void logBytes(long bytesSent, long bytesReceived) {
instance.log(bytesSent, bytesReceived);
}
client.addResponseInterceptor(new HttpResponseInterceptor() {
@Override
public void process(final HttpResponse response,
final HttpContext context) throws HttpException,
IOException {
try {
stats.log(0, response.getEntity().getContentLength());
} catch (Throwable t) {
// Ignore any errors when logging
}
}
});
HttpConnectionParams.setTcpNoDelay(client.getParams(), true);
this.client = client;
previousConnectionFailed = false;
private void log(long bytesSent, long bytesReceived) {
try {
stats.log(bytesSent, bytesReceived);
} catch (Throwable t) {
// Ignore any errors when logging
}
}
/**
@ -173,24 +395,18 @@ public class HttpClient {
* whether or not to handle gzip responses
*/
public void setGzipResponseHandling(boolean acceptGzip) {
if (acceptGzip && !handlingGzipResponses) {
// Add gzip compression handlers
// advertise we accept gzip
((AbstractHttpClient) client)
.addRequestInterceptor(new GzipRequestInterceptor());
// handle gzip contents
((AbstractHttpClient) client)
.addResponseInterceptor(new GzipResponseInterceptor());
} else if (!acceptGzip && handlingGzipResponses) {
((AbstractHttpClient) client)
.removeRequestInterceptorByClass(GzipRequestInterceptor.class);
((AbstractHttpClient) client)
.removeResponseInterceptorByClass(GzipResponseInterceptor.class);
}
handlingGzipResponses = acceptGzip;
}
/**
* Get if the instance is gzipping responses
*
* @return true if gzipping responses
*/
public boolean isGzipResponseHandling() {
return this.handlingGzipResponses;
}
/**
* Sets whether or not to compress the outgoing requests to reduce bandwidth
* sent by the client.
@ -201,11 +417,12 @@ public class HttpClient {
gzipRequests = compress;
}
public static synchronized HttpClient getInstance() {
if (instance == null) {
instance = new HttpClient();
}
/**
* Get an instance of this class
*
* @return instance
*/
public static final HttpClient getInstance() {
return instance;
}
@ -255,7 +472,43 @@ public class HttpClient {
*/
private HttpResponse postRequest(HttpUriRequest put) throws IOException,
CommunicationException {
HttpResponse resp = client.execute(put);
HttpResponse resp = null;
if (put.getURI().getScheme().equalsIgnoreCase(HTTPS)) {
org.apache.http.client.HttpClient client = getHttpsInstance();
resp = execute(client, put);
// Check for not authorized, 401
while (resp.getStatusLine().getStatusCode() == 401) {
String authValue = null;
if (resp.containsHeader(WWW_AUTHENTICATE)) {
authValue = resp.getFirstHeader(WWW_AUTHENTICATE)
.getValue();
}
String[] credentials = null;
if (handler != null) {
credentials = handler.getCredentials(authValue);
}
if (credentials == null) {
return resp;
}
URI uri = put.getURI();
String host = uri.getHost();
int port = uri.getPort();
this.setCredentials(host, port, null, credentials[0],
credentials[1]);
try {
resp = execute(client, put);
} catch (Exception e) {
statusHandler.handle(Priority.ERROR,
"Error retrying http request", e);
return resp;
}
}
} else {
resp = getHttpInstance().execute(put);
}
if (previousConnectionFailed) {
previousConnectionFailed = false;
statusHandler.handle(Priority.INFO,
@ -264,6 +517,22 @@ public class HttpClient {
return resp;
}
/**
* Execute the HttpUriRequest using the provided HttpClient instance.
*
* @param client
* The HttpClient instance
* @param request
* The request
* @return HttpResponse
* @throws ClientProtocolException
* @throws IOException
*/
private HttpResponse execute(org.apache.http.client.HttpClient client,
HttpUriRequest request) throws ClientProtocolException, IOException {
return client.execute(request);
}
/**
* Posts the request to the server and passes the response stream to the
* handler callback. Will also retry the request if it fails due to a
@ -292,9 +561,13 @@ public class HttpClient {
}
int currentCount = ongoing.incrementAndGet();
if (currentCount > getMaxConnectionsPerHost()) {
String msg = currentCount + " ongoing http requests to " + host
+ ". Likely waiting for free connection from pool.";
statusHandler.debug(msg);
if (statusHandler.isPriorityEnabled(Priority.DEBUG)) {
String msg = currentCount
+ " ongoing http requests to "
+ host
+ ". Likely waiting for free connection from pool.";
statusHandler.debug(msg);
}
}
while (retry) {
retry = false;
@ -310,6 +583,9 @@ public class HttpClient {
errorMsg += ". Currently " + ongoing.get()
+ " requests ongoing";
exc = e;
} catch (SSLPeerUnverifiedException e) {
errorMsg = "Problem with security certificates.\nCannot make a secure connection.\nContact server administrator";
throw new CommunicationException(errorMsg, e);
} catch (IOException e) {
errorMsg = "Error occurred communicating with server: "
+ e.getMessage();
@ -467,6 +743,7 @@ public class HttpClient {
HttpPost put = new HttpPost(address);
DynamicSerializeEntity dse = new DynamicSerializeEntity(obj, stream,
gzipRequests);
put.setEntity(dse);
if (gzipRequests) {
put.setHeader("Content-Encoding", "gzip");
@ -588,22 +865,77 @@ public class HttpClient {
}
public void setMaxConnectionsPerHost(int maxConnections) {
connManager.setDefaultMaxPerRoute(maxConnections);
this.maxConnections = maxConnections;
}
/**
* Get the maximum number of connections.
*
* @return the max connections
*/
public int getMaxConnections() {
return this.maxConnections;
}
public int getMaxConnectionsPerHost() {
return connManager.getDefaultMaxPerRoute();
if (connManager != null) {
return ((ThreadSafeClientConnManager) connManager)
.getDefaultMaxPerRoute();
}
if (sslConnManager != null) {
return ((ThreadSafeClientConnManager) sslConnManager)
.getDefaultMaxPerRoute();
}
return maxConnections;
}
/**
* Set the socket timeout value
*
* @param socketTimeout
* the timeout value
*/
public void setSocketTimeout(int socketTimeout) {
HttpConnectionParams.setSoTimeout(client.getParams(), socketTimeout);
// client.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT,
// socketTimeout);
this.socketTimeout = socketTimeout;
}
/**
* Get the socket timeout
*
* @return the socket timeout
*/
public int getSocketTimeout() {
return this.socketTimeout;
}
/**
* Set the connection timeout value
*
* @param connectionTimeout
* The timeout value
*/
public void setConnectionTimeout(int connectionTimeout) {
HttpConnectionParams.setConnectionTimeout(client.getParams(),
connectionTimeout);
this.connectionTimeout = connectionTimeout;
}
/**
* Get the connection timeout
*
* @return the connection timeout
*/
public int getConnectionTimeout() {
return this.connectionTimeout;
}
/**
* Set the handler.
*
* @param handler
* The IHttpsCredentialsHandler
*/
public void setHandler(IHttpsCredentialsHandler handler) {
this.handler = handler;
}
/**
@ -753,14 +1085,48 @@ public class HttpClient {
HeaderElement[] codecs = ceheader.getElements();
for (HeaderElement codec : codecs) {
if (codec.getName().equalsIgnoreCase("gzip")) {
response.setEntity(new SafeGzipDecompressingEntity(response
.getEntity()));
response.setEntity(new SafeGzipDecompressingEntity(
response.getEntity()));
return;
}
}
}
}
}
/**
* Set the credentials for SSL.
*
* @param host
* The host
* @param port
* The port
* @param realm
* The realm
* @param username
* The username
* @param password
* The password
*/
public void setCredentials(String host, int port, String realm,
String username, String password) {
(HttpsHolder.sslClient).getCredentialsProvider().setCredentials(
new AuthScope(host, port),
new UsernamePasswordCredentials(username, password));
}
/**
* @param httpsConfiguration
* the httpsConfiguration to set
*/
public void setHttpsConfiguration(IHttpsConfiguration httpsConfiguration) {
this.httpsConfiguration = httpsConfiguration;
}
/**
* @return the httpsConfiguration
*/
public IHttpsConfiguration getHttpsConfiguration() {
return httpsConfiguration;
}
}

View file

@ -0,0 +1,45 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.comm;
/**
* Https Configuration interface.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 9, 2013 1786 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public interface IHttpsConfiguration {
/** Get the HTTPS port */
int getHttpsPort();
/** Get the HTTP port */
int getHttpPort();
}

View file

@ -0,0 +1,51 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.comm;
/**
* Interface for collecting https Credentials.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 4, 2013 1786 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public interface IHttpsCredentialsHandler {
/**
* Get the https credentials.
*
* @param authValue
* The authorization message, typically returned from the server
* requesting authentication.
*
* @return String Array, username and password
*/
String[] getCredentials(String authValue);
}

View file

@ -0,0 +1,103 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.comm;
/**
* Structure to hold proxy settings
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 3, 2013 1786 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class ProxyConfiguration {
private String host;
private int port;
/**
* Default constructor.
*/
public ProxyConfiguration() {
}
/**
* Constructor.
*
* @param host
* The host string
* @param port
* The port string
*/
public ProxyConfiguration(String host, String port) {
this.host = host;
this.port = Integer.parseInt(port);
}
/**
* @return the host
*/
public String getHost() {
return host;
}
/**
* @param host
* the host to set
*/
public void setHost(String host) {
this.host = host;
}
/**
* @return the port
*/
public int getPort() {
return port;
}
/**
* @param port
* the port to set
*/
public void setPort(int port) {
this.port = port;
}
/**
* Get the port as a String.
*
* @return the port as a String
*/
public String getPortString() {
return String.valueOf(port);
}
}

View file

@ -0,0 +1,90 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.comm;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
import com.raytheon.uf.common.util.PropertiesUtil;
/**
* Proxy Utility Class
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 1, 2013 1786 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class ProxyUtil {
/** Proxy host environment variable name */
public static final String HTTP_PROXY_HOST = "http.proxyHost";
/** Proxy port environment variable name */
public static final String HTTP_PROXY_PORT = "http.proxyPort";
/**
* Get the proxy server settings if any are present.
*
* @return ProxyConfiguration object or null if no settings
*/
public static ProxyConfiguration getProxySettings() {
String host = System.getProperty(HTTP_PROXY_HOST);
String port = System.getProperty(HTTP_PROXY_PORT);
if (host != null && port != null) {
return new ProxyConfiguration(host, port);
}
return null;
}
/**
* Get the proxy settings from the provided properties file.
*
* @param proxyFile
* The properties file
* @return ProxyConfiguration object, or null if no settings
* @throws IOException
* If error reading properties file
*/
public static ProxyConfiguration getProxySettings(File proxyFile)
throws IOException {
ProxyConfiguration proxySettings = null;
Properties properties = PropertiesUtil.read(proxyFile);
String host = properties.getProperty(HTTP_PROXY_HOST);
String port = properties.getProperty(HTTP_PROXY_PORT);
if (host != null && port != null) {
proxySettings = new ProxyConfiguration(host, port);
}
return proxySettings;
}
}

View file

@ -19,9 +19,6 @@
**/
package com.raytheon.uf.common.serialization.comm;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.util.registry.GenericRegistry;
import com.raytheon.uf.common.util.registry.RegistryException;
@ -38,6 +35,8 @@ import com.raytheon.uf.common.util.registry.RegistryException;
* Nov 15, 2012 1322 djohnson Add ability to route by server key.
* Mar 05, 2013 1754 djohnson Prevent infinite loop when request.server router not registered,
* info log when router registered.
* Apr 04, 2013 1786 mpduff Remove StatusHandler and logging. Prevents thrift logging
* requests from happening before the VIZ platform is ready.
*
* </pre>
*
@ -46,9 +45,6 @@ import com.raytheon.uf.common.util.registry.RegistryException;
*/
public final class RequestRouter {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(RequestRouter.class);
static final String REQUEST_SERVICE = "request.server";
/**
@ -69,8 +65,7 @@ public final class RequestRouter {
+ s.getClass().getName()
+ "] already registered for key [" + t + "]"));
}
statusHandler.info("Registered request router for key [" + t
+ "] of type [" + s.getClass().getName() + "]");
return super.register(t, s);
}
@ -127,19 +122,10 @@ public final class RequestRouter {
final IRequestRouter router = routerRegistry
.getRegisteredObject(service);
if (router == null) {
if (REQUEST_SERVICE.equals(service)) {
final String errorMessage = "There is no registered router for service ["
+ service + "]. The request cannot be processed!";
statusHandler.handle(Priority.FATAL, errorMessage);
final String errorMessage = "There is no registered router for service ["
+ service + "]. The request cannot be processed!";
throw new IllegalStateException(errorMessage);
} else {
statusHandler
.error("There is no registered router for service ["
+ service
+ "]. Routing to the request service, but the request may not be able to be processed!");
return route(request);
}
throw new IllegalStateException(errorMessage);
} else {
return router.route(request);
}

View file

@ -31,7 +31,8 @@ Require-Bundle: org.eclipse.core.runtime,
com.raytheon.uf.common.datadelivery.retrieval;bundle-version="1.0.0",
com.raytheon.uf.edex.registry.ebxml;bundle-version="1.0.0",
com.raytheon.uf.common.registry.ebxml;bundle-version="1.0.0",
com.raytheon.uf.common.stats;bundle-version="1.0.0"
com.raytheon.uf.common.stats;bundle-version="1.0.0",
com.raytheon.uf.common.comm;bundle-version="1.12.1174"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Export-Package: com.raytheon.uf.edex.datadelivery.harvester;uses:="com.raytheon.uf.edex.datadelivery.harvester.crawler",

View file

@ -13,6 +13,7 @@ import java.util.regex.Pattern;
import com.google.common.annotations.VisibleForTesting;
import com.raytheon.edex.util.Util;
import com.raytheon.uf.common.comm.ProxyConfiguration;
import com.raytheon.uf.common.datadelivery.registry.Collection;
import com.raytheon.uf.common.serialization.SerializationException;
import com.raytheon.uf.common.serialization.SerializationUtil;
@ -68,7 +69,7 @@ public abstract class Crawler {
protected final HarvesterConfig hconfig;
protected final String[] proxyParameters;
protected final ProxyConfiguration proxyParameters;
protected static final ThreadFactory THREAD_FACTORY = new ThreadFactory() {
@Override
@ -158,9 +159,9 @@ public abstract class Crawler {
if (!lockFileDir.exists()) {
lockFileDir.mkdirs();
}
File lockFile = new File(lockFileDir, crawlType + "-crawl.lock");
try {
// if lock file doesn't exist, create it
if (!lockFile.exists()) {
@ -172,7 +173,7 @@ public abstract class Crawler {
// Try acquiring the lock without blocking. This method returns
// null or throws an exception if the file is already locked.
FileLock lock = channel.tryLock();
if (lock == null) {
// Someone else has the lock
statusHandler
@ -285,11 +286,11 @@ public abstract class Crawler {
* Do you need to set a proxy? If so, you can use:
*/
if (proxyParameters != null) {
String host = proxyParameters[0];
String port = proxyParameters[1];
String host = proxyParameters.getHost();
int port = proxyParameters.getPort();
config.setProxyHost(host);
config.setProxyPort(new Integer(port).intValue());
config.setProxyPort(port);
}
/*

View file

@ -216,7 +216,8 @@ public class MainSequenceCrawler extends Crawler {
if (proxyParameters != null) {
statusHandler.debug(String.format(
"proxy host:[%s] proxy port: [%s]",
proxyParameters[0], proxyParameters[1]));
proxyParameters.getHost(),
proxyParameters.getPortString()));
} else {
statusHandler.debug("No proxy information configured.");
}

View file

@ -113,7 +113,8 @@ public class SeedCrawler extends Crawler {
if (proxyParameters != null) {
statusHandler.debug(String.format(
"proxy host:[%s] proxy port: [%s]",
proxyParameters[0], proxyParameters[1]));
proxyParameters.getHost(),
proxyParameters.getPortString()));
} else {
statusHandler.debug("No proxy information configured.");
}

View file

@ -35,6 +35,7 @@ import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import com.google.common.annotations.VisibleForTesting;
import com.raytheon.uf.common.comm.ProxyConfiguration;
import com.raytheon.uf.common.datadelivery.registry.DataSetMetaData;
import com.raytheon.uf.common.datadelivery.registry.OpenDapGriddedDataSetMetaData;
import com.raytheon.uf.common.datadelivery.registry.Provider;
@ -105,10 +106,11 @@ class OpenDapGriddedPurgeImpl implements IOpenDapGriddedPurge {
@VisibleForTesting
HttpClient getHttpClient() {
HttpClient httpClient = new DefaultHttpClient();
String[] proxyParameters = ConnectionUtil.getProxyParameters();
ProxyConfiguration proxyParameters = ConnectionUtil
.getProxyParameters();
if (proxyParameters != null) {
HttpHost proxy = new HttpHost(proxyParameters[0],
Integer.parseInt(proxyParameters[1]));
HttpHost proxy = new HttpHost(proxyParameters.getHost(),
proxyParameters.getPort());
httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,
proxy);
}

View file

@ -22,15 +22,15 @@ package com.raytheon.uf.edex.datadelivery.retrieval.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import com.raytheon.edex.colormap.ColorMapManager;
import com.raytheon.uf.common.comm.ProxyConfiguration;
import com.raytheon.uf.common.comm.ProxyUtil;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.util.PropertiesUtil;
import dods.dap.DConnect;
@ -44,6 +44,7 @@ import dods.dap.DConnect;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 28, 2012 819 djohnson Initial creation
* Apr 01, 2013 1786 mpduff Pulled proxy settings out to util class.
*
* </pre>
*
@ -58,19 +59,15 @@ public class ConnectionUtil {
private static final String PROXY_PROPERTIES_FILE = "datadelivery"
+ File.separator + "proxy.properties";
static final String HTTP_PROXY_HOST = "http.proxyHost";
static final String HTTP_PROXY_PORT = "http.proxyPort";
static ConnectionUtil instance = new ConnectionUtil();
static volatile boolean initialized;
private String[] proxySettings;
private ProxyConfiguration proxySettings;
static void clearSettings() {
System.clearProperty(HTTP_PROXY_HOST);
System.clearProperty(HTTP_PROXY_PORT);
System.clearProperty(ProxyUtil.HTTP_PROXY_HOST);
System.clearProperty(ProxyUtil.HTTP_PROXY_PORT);
instance = new ConnectionUtil();
initialized = false;
}
@ -88,10 +85,10 @@ public class ConnectionUtil {
if (!initialized) {
initialize();
}
String[] proxyInformation = instance.getProxyInformation();
ProxyConfiguration proxyInformation = instance.getProxyInformation();
if (proxyInformation != null) {
return new DConnect(urlString, proxyInformation[0],
proxyInformation[1]);
return new DConnect(urlString, proxyInformation.getHost(),
proxyInformation.getPortString());
} else {
return new DConnect(urlString);
}
@ -103,7 +100,7 @@ public class ConnectionUtil {
* @return [0] = proxy host, [1] proxy port or null if there is no proxy
* information
*/
public static String[] getProxyParameters() {
public static ProxyConfiguration getProxyParameters() {
if (!initialized) {
initialize();
}
@ -111,11 +108,13 @@ public class ConnectionUtil {
}
private static synchronized void initialize() {
String[] proxyInformation = instance.getProxyInformation();
ProxyConfiguration proxyInformation = instance.getProxyInformation();
if (proxyInformation != null) {
System.setProperty(HTTP_PROXY_HOST, proxyInformation[0]);
System.setProperty(HTTP_PROXY_PORT, proxyInformation[1]);
System.setProperty(ProxyUtil.HTTP_PROXY_HOST,
proxyInformation.getHost());
System.setProperty(ProxyUtil.HTTP_PROXY_PORT,
proxyInformation.getPortString());
}
initialized = true;
}
@ -132,7 +131,7 @@ public class ConnectionUtil {
* @return [0] = proxy host, [1] proxy port or null if there is no proxy
* information
*/
String[] getProxyInformation() {
ProxyConfiguration getProxyInformation() {
if (proxySettings == null) {
IPathManager pathMgr = PathManagerFactory.getPathManager();
LocalizationContext context = pathMgr.getContext(
@ -140,42 +139,27 @@ public class ConnectionUtil {
LocalizationContext.LocalizationLevel.CONFIGURED);
try {
File file = pathMgr.getFile(context,
PROXY_PROPERTIES_FILE);
File proxyFile = pathMgr
.getFile(context, PROXY_PROPERTIES_FILE);
// If the configured version doesn't exist, default to the base
// version
if (!file.exists()) {
if (!proxyFile.exists()) {
context = pathMgr.getContext(
LocalizationContext.LocalizationType.COMMON_STATIC,
LocalizationContext.LocalizationLevel.BASE);
file = pathMgr.getFile(context,
PROXY_PROPERTIES_FILE);
proxyFile = pathMgr.getFile(context, PROXY_PROPERTIES_FILE);
}
Properties properties = PropertiesUtil.read(file);
String host = properties.getProperty(HTTP_PROXY_HOST);
String port = properties.getProperty(HTTP_PROXY_PORT);
if (host != null && port != null) {
proxySettings = new String[] { host, port };
statusHandler.debug(String
.format("proxy host:[%s] proxy port: [%s]",
host, port));
} else {
statusHandler.debug("No proxy information configured.");
}
proxySettings = ProxyUtil.getProxySettings(proxyFile);
} catch (FileNotFoundException e) {
statusHandler.error("Unable to find a file with name "
+ PROXY_PROPERTIES_FILE + "!", e);
} catch (IOException e) {
statusHandler.error("Unable to read file " + PROXY_PROPERTIES_FILE + "!",
e);
statusHandler.error("Unable to read file "
+ PROXY_PROPERTIES_FILE + "!", e);
}
}
return proxySettings;
}
}

View file

@ -8,6 +8,7 @@
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/org.junit"/>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/org.apache.commons.codec"/>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/org.slf4j"/>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/org.eclipse.jetty"/>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/com.raytheon.uf.common.util"/>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/com.raytheon.uf.common.comm"/>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/org.apache.http"/>
@ -84,5 +85,11 @@
<classpathentry kind="lib" path="/opt/uframe-eclipse/plugins/org.eclipse.swt.gtk.linux.x86_3.6.1.v3655c.jar"/>
<classpathentry kind="lib" path="/opt/uframe-eclipse/plugins/org.eclipse.swt.gtk.linux.x86_64.source_3.6.1.v3655c.jar"/>
<classpathentry kind="lib" path="/opt/uframe-eclipse/plugins/org.eclipse.swt.gtk.linux.x86_64_3.6.1.v3655c.jar"/>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/org.jep">
<attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="org.jep.linux32"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="lib/javax.servlet_2.5.0.v200910301333.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,98 @@
package com.raytheon.uf.common.comm;
import static org.junit.Assert.assertEquals;
import java.net.URI;
import org.apache.http.client.methods.HttpGet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.raytheon.uf.common.comm.HttpClient.HttpClientResponse;
import com.raytheon.uf.common.util.JettyServer;
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
/**
* HttpClient test class. This case tests the https connection with no
* credentials provided.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 20, 2013 1786 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class HttpClientNoCredentialsTest {
private static JettyServer server;
@Before
public void startHttpsServer() {
server = new JettyServer(HttpTestConstants.HTTPS_PORT);
server.addServlet(new TestServletInstance(), "/test");
try {
server.startSSLServer(true);
} catch (Exception e) {
throw new RuntimeException("Error starting Jetty Server", e);
}
}
@After
public void stopServer() {
try {
server.stopServer();
} catch (Exception e) {
throw new RuntimeException("Error stopping Jetty Server", e);
}
}
@Test
public void testHttpsCallNoCredentialsThenCredentials() {
int expectedCode = 200;
int actualCode = 0;
HttpClient client = HttpClient.getInstance();
client.setHandler(new TestHttpsCredentialsHandler());
client.setHttpsConfiguration(new TestHttpsConfiguration());
try {
HttpGet request = new HttpGet();
request.setURI(new URI(HttpTestConstants.HTTPS_URI));
System.out.println("Requesting: " + HttpTestConstants.HTTPS_URI);
HttpClientResponse response = client.executeRequest(request);
actualCode = response.code;
} catch (Exception e) {
throw new RuntimeException(e);
}
assertEquals(expectedCode, actualCode);
}
}

View file

@ -0,0 +1,137 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.comm;
import static org.junit.Assert.assertEquals;
import java.net.URI;
import org.apache.http.client.methods.HttpGet;
import org.junit.After;
import org.junit.Test;
import com.raytheon.uf.common.comm.HttpClient.HttpClientResponse;
import com.raytheon.uf.common.util.JettyServer;
/**
* HttpClient test class. This case tests the HTTP and HTTPS connections.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 27, 2013 1786 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class HttpClientTest {
private static JettyServer server;
public void startHttpsServer() {
server = new JettyServer(HttpTestConstants.HTTPS_PORT);
server.addServlet(new TestServletInstance(), "/test");
try {
server.startSSLServer(true);
} catch (Exception e) {
throw new RuntimeException("Error starting Jetty Server", e);
}
}
public void startHttpServer() {
server = new JettyServer(HttpTestConstants.HTTP_PORT);
server.addServlet(new TestServletInstance(), "/test");
try {
server.startServer();
} catch (Exception e) {
throw new RuntimeException("Error starting Jetty Server", e);
}
}
@After
public void stopServer() {
try {
server.stopServer();
} catch (Exception e) {
throw new RuntimeException("Error stopping Jetty Server", e);
}
}
@Test
public void testHttpCall() {
startHttpServer();
int expectedCode = 200;
int actualCode = 0;
HttpClient client = HttpClient.getInstance();
client.setHttpsConfiguration(new TestHttpsConfiguration());
HttpGet request = new HttpGet();
HttpClientResponse response = null;
try {
request.setURI(new URI(HttpTestConstants.HTTP_URI));
response = client.executeRequest(request);
actualCode = response.code;
} catch (Exception e) {
throw new RuntimeException(e);
}
assertEquals(expectedCode, actualCode);
}
/**
*
*/
@Test
public void testHttpsMultipleCallsWithValidCredentials() {
startHttpsServer();
int expectedCode = 200;
int actualCode = 0;
HttpClient client = HttpClient.getInstance();
client.setHandler(new TestHttpsCredentialsHandler());
client.setHttpsConfiguration(new TestHttpsConfiguration());
try {
client.setCredentials(HttpTestConstants.HOST,
HttpTestConstants.HTTPS_PORT, HttpTestConstants.REALM,
HttpTestConstants.USERNAME, HttpTestConstants.PASSWD);
HttpGet request = new HttpGet();
request.setURI(new URI(HttpTestConstants.HTTPS_URI));
for (int i = 0; i < 5; i++) {
HttpClientResponse response = client.executeRequest(request);
actualCode = response.code;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
assertEquals(expectedCode, actualCode);
}
}

View file

@ -0,0 +1,102 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.comm;
import static org.junit.Assert.assertEquals;
import java.net.URI;
import org.apache.http.client.methods.HttpGet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.raytheon.uf.common.comm.HttpClient.HttpClientResponse;
import com.raytheon.uf.common.util.JettyServer;
/**
* HttpClient test class. This case tests the https connection with invalid
* credentials provided.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 20, 2013 1786 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class HttpClientTestHttpsWithInvalidCredentials {
private static JettyServer server;
@Before
public void startHttpsServer() {
server = new JettyServer(HttpTestConstants.HTTPS_PORT);
server.addServlet(new TestServletInstance(), "/test");
try {
server.startSSLServer(true);
} catch (Exception e) {
throw new RuntimeException("Error starting Jetty Server", e);
}
}
@After
public void stopServer() {
try {
server.stopServer();
} catch (Exception e) {
throw new RuntimeException("Error stopping Jetty Server", e);
}
}
/**
* Test with invalid credentials provided initially.
*/
@Test
public void testHttpsConnectionWithInvalidCredentialsThenValidCredentials() {
int expectedCode = 200;
int actualCode = 0;
HttpClient client = HttpClient.getInstance();
client.setHandler(new TestHttpsCredentialsHandler());
client.setHttpsConfiguration(new TestHttpsConfiguration());
try {
client.setCredentials(HttpTestConstants.HOST,
HttpTestConstants.HTTP_PORT, HttpTestConstants.REALM,
"badusername", "badpassword");
HttpGet request = new HttpGet();
request.setURI(new URI(HttpTestConstants.HTTPS_URI));
HttpClientResponse response = client.executeRequest(request);
actualCode = response.code;
} catch (Exception e) {
throw new RuntimeException(e);
}
assertEquals(expectedCode, actualCode);
}
}

View file

@ -0,0 +1,99 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.comm;
import static org.junit.Assert.assertEquals;
import java.net.URI;
import org.apache.http.client.methods.HttpGet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.raytheon.uf.common.comm.HttpClient.HttpClientResponse;
import com.raytheon.uf.common.util.JettyServer;
/**
* HttpClient test class. This case tests the https connection with valid
* credentials already provided.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 20, 2013 1786 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class HttpClientValidCredentialsTest {
private static JettyServer server;
@Before
public void startHttpsServer() {
server = new JettyServer(HttpTestConstants.HTTPS_PORT);
server.addServlet(new TestServletInstance(), "/test");
try {
server.startSSLServer(true);
} catch (Exception e) {
throw new RuntimeException("Error starting Jetty Server", e);
}
}
@After
public void stopServer() {
try {
server.stopServer();
} catch (Exception e) {
throw new RuntimeException("Error stopping Jetty Server", e);
}
}
@Test
public void testHttpsConnectionWithValidCredentials() {
int expectedCode = 200;
int actualCode = 200;
HttpClient client = HttpClient.getInstance();
client.setHandler(new TestHttpsCredentialsHandler());
client.setHttpsConfiguration(new TestHttpsConfiguration());
try {
client.setCredentials(HttpTestConstants.HOST,
HttpTestConstants.HTTPS_PORT, HttpTestConstants.REALM,
HttpTestConstants.USERNAME, HttpTestConstants.PASSWD);
HttpGet request = new HttpGet();
request.setURI(new URI(HttpTestConstants.HTTPS_URI));
HttpClientResponse response = client.executeRequest(request);
actualCode = response.code;
} catch (Exception e) {
throw new RuntimeException(e);
}
assertEquals(expectedCode, actualCode);
}
}

View file

@ -0,0 +1,58 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.comm;
/**
* Http constants
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 20, 2013 1786 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class HttpTestConstants {
public static final int HTTPS_PORT = 8443;
public static final String USERNAME = "user";
public static final String PASSWD = "password";
public static final String REALM = "Private!";
public static final String HOST = "localhost";
public static final int HTTP_PORT = 8888;
public static final String HTTPS_URI = "https://localhost:8443/test";
public static final String HTTP_URI = "http://localhost:8888/test";
public static final int PORT = 8888;
}

View file

@ -0,0 +1,61 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.comm;
/**
* Test implementation.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 9, 2013 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class TestHttpsConfiguration implements IHttpsConfiguration {
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.common.comm.IHttpsConfiguration#getHttpsPort()
*/
@Override
public int getHttpsPort() {
return HttpTestConstants.HTTPS_PORT;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.common.comm.IHttpsConfiguration#getHttpPort()
*/
@Override
public int getHttpPort() {
return HttpTestConstants.HTTP_PORT;
}
}

View file

@ -0,0 +1,47 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.comm;
/**
* Test Https credentials handler. Returns valid credentials for HttpClient Test
* Cases.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 6, 2013 1786 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class TestHttpsCredentialsHandler implements IHttpsCredentialsHandler {
@Override
public String[] getCredentials(String message) {
return new String[] { HttpTestConstants.USERNAME,
HttpTestConstants.PASSWD };
}
}

View file

@ -0,0 +1,37 @@
package com.raytheon.uf.common.comm;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* A test Servlet.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 27, 2013 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class TestServletInstance extends HttpServlet {
/**
* Output
*/
public static final String OUTPUT = "<h1>Test Successful</h1>";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().print(OUTPUT);
}
}

View file

@ -0,0 +1,239 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.util;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.security.Constraint;
import org.eclipse.jetty.http.security.Credential;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.security.SecurityHandler;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.bio.SocketConnector;
import org.eclipse.jetty.server.ssl.SslSocketConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import com.raytheon.uf.common.comm.HttpTestConstants;
/**
* This class sets up a Jetty Server that can serve up HttpServlets in either
* http or https mode. When in https mode the authentication credentials are
* username = user and password = password as defined in TestHttpConstants. This
* server can be run as part of a unit test or stand alone from the main.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 27, 2013 1786 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class JettyServer {
/** The port number */
private int port = HttpTestConstants.PORT;
/** Jetty server instance */
private Server server;
private final ServletContextHandler servletContextHandler;
/**
* Construct the Jetty Server instance.
*
* @param port
* The port number
*/
public JettyServer(int port) {
this.port = port;
servletContextHandler = new ServletContextHandler(
ServletContextHandler.SESSIONS);
servletContextHandler.setContextPath("/");
}
/**
* Start the server as an SSL server not requiring authentication.
*
* @throws Exception
* if error occurs
*/
public void startSSLServer() throws Exception {
startSSLServer(false);
}
/**
* Start the server as an SSL server
*
* @param useAuthentication
* true to use authentication. user/password
*
* @throws Exception
* if error occurs
*/
public void startSSLServer(boolean useAuthentication) throws Exception {
String keystorePath = TestUtil.getFileForResource(JettyServer.class,
"/http/keystore").getAbsolutePath();
server = new Server();
SslSocketConnector sslConnector = new SslSocketConnector();
sslConnector.setPort(port);
sslConnector.setMaxIdleTime(30000);
sslConnector.setKeystore(keystorePath);
sslConnector.setPassword(HttpTestConstants.PASSWD);
sslConnector.setKeyPassword(HttpTestConstants.PASSWD);
sslConnector.setTruststore(keystorePath);
sslConnector.setTrustPassword(HttpTestConstants.PASSWD);
server.addConnector(sslConnector);
if (useAuthentication) {
servletContextHandler.setSecurityHandler(basicAuth(
HttpTestConstants.USERNAME, HttpTestConstants.PASSWD,
HttpTestConstants.REALM));
}
server.setHandler(servletContextHandler);
server.start();
}
/**
* Start the server as a standard http server
*
* @throws Exception
* exception
*/
public void startServer() throws Exception {
server = new Server();
Connector connector = new SocketConnector();
connector.setPort(port);
server.setConnectors(new Connector[] { connector });
server.addConnector(connector);
server.setHandler(servletContextHandler);
server.start();
}
/**
* Stop the server.
*
* @throws Exception
* If error occurs
*/
public void stopServer() throws Exception {
server.stop();
}
/**
* Add a servlet to the server.
*
* @param servlet
* The servlet to add
* @param pathSpec
* The path of the servlet
*/
public void addServlet(HttpServlet servlet, String pathSpec) {
servletContextHandler.addServlet(new ServletHolder(servlet), pathSpec);
}
/**
* Create a SecurityHandler for the SSL server.
*
* @param username
* The username
* @param password
* The password
* @param realm
* The realm name
* @return The SecurityHandler
*/
private final SecurityHandler basicAuth(String username, String password,
String realm) {
HashLoginService l = new HashLoginService();
l.putUser(username, Credential.getCredential(password),
new String[] { HttpTestConstants.USERNAME });
l.setName(realm);
Constraint constraint = new Constraint();
constraint.setName(Constraint.__BASIC_AUTH);
constraint.setRoles(new String[] { HttpTestConstants.USERNAME });
constraint.setAuthenticate(true);
ConstraintMapping cm = new ConstraintMapping();
cm.setConstraint(constraint);
cm.setPathSpec("/*");
ConstraintSecurityHandler csh = new ConstraintSecurityHandler();
csh.setAuthenticator(new BasicAuthenticator());
// csh.setRealmName("myrealm");
csh.setRealmName(HttpTestConstants.REALM);
csh.addConstraintMapping(cm);
csh.setLoginService(l);
return csh;
}
/**
* A test servlet
*/
public class TestServletInstance extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().print("<h1>Test Successful</h1>");
}
}
/**
* Main method. Uncomment to run in the desired mode.
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// Https
JettyServer server = new JettyServer(8443);
server.addServlet(server.new TestServletInstance(), "/test");
server.startSSLServer();
// Http
// JettyServer server = new JettyServer(8888);
// server.addServlet(server.new TestServletInstance(), "/test");
// server.startServer();
}
}

View file

@ -30,6 +30,8 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
@ -167,8 +169,7 @@ public final class TestUtil {
*/
@SuppressWarnings("unchecked")
public static List<List<String>> getInputsAndOutputs(Class<?> callingClass,
String file)
throws IOException {
String file) throws IOException {
List<String> inputs = new ArrayList<String>();
List<String> outputs = new ArrayList<String>();
@ -227,7 +228,7 @@ public final class TestUtil {
objectUnderTest, objectUnderTest);
assertEquals("The specified object should have a consistent hashcode!",
objectUnderTest.hashCode(), objectUnderTest.hashCode());
for (T equalObject : equalObjects) {
assertEquals(
"The specified object should have been equal, but wasn't!",
@ -268,9 +269,8 @@ public final class TestUtil {
* object under test
*/
public static <T extends Comparable<? super T>> void assertCompareToContract(
T objectUnderTest,
Collection<T> lessThanObjects, Collection<T> equalObjects,
Collection<T> greaterThanObjects) {
T objectUnderTest, Collection<T> lessThanObjects,
Collection<T> equalObjects, Collection<T> greaterThanObjects) {
assertEquals(
"The specified object should have been equal with itself!", 0,
objectUnderTest.compareTo(objectUnderTest));
@ -332,6 +332,25 @@ public final class TestUtil {
return bos.toByteArray();
}
/**
* Get a file.
*
* @param callingClass
* The calling class
* @param resource
* The resource to get
* @return File instance
*/
public static File getFileForResource(Class<?> callingClass, String resource) {
URL url = callingClass.getResource(resource);
try {
return new File(url.toURI());
} catch (URISyntaxException e) {
return new File(url.getPath());
}
}
/**
* Sets up a unique directory specific to the class requesting it. This
* method will also delete any existing version that exists.