/* * 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 org.apache.usergrid.chop.client.rest; import javax.net.ssl.SSLHandshakeException; import org.apache.usergrid.chop.api.ChopUtils; import org.apache.usergrid.chop.api.CoordinatorFig; import org.apache.usergrid.chop.api.Project; import org.apache.usergrid.chop.api.RestParams; import org.apache.usergrid.chop.api.Result; import org.apache.usergrid.chop.api.Runner; import org.apache.usergrid.chop.api.StatsSnapshot; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; import com.sun.jersey.api.client.ClientHandlerException; import com.sun.jersey.api.client.WebResource; /** * Client REST request functions. */ public class RestRequests { private static final Logger LOG = LoggerFactory.getLogger( RestRequests.class ); private static void preparations( final Runner runner ) { Preconditions.checkNotNull( runner, "The runner parameter cannot be null." ); Preconditions.checkNotNull( runner.getHostname(), "The runner parameter's hostname property cannot be null." ); /** * This is because we are using self-signed uniform certificates for now, * it should be removed if we switch to a CA signed dynamic certificate scheme! * */ javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier( new javax.net.ssl.HostnameVerifier() { public boolean verify( String hostname, javax.net.ssl.SSLSession sslSession) { return hostname.equals( runner.getHostname() ); } } ); if ( ! ChopUtils.isTrusted( runner ) ) { try { ChopUtils.installRunnerKey( null, runner ); } catch ( Exception e ) { LOG.error( "Failed to install certificate for runner: {}", runner.getHostname() ); try { ChopUtils.installCert( runner.getHostname(), runner.getServerPort(), null ); } catch ( Exception e2 ) { LOG.error( "Failed to get certificate from server {} on port {}: dumping stack trace!", runner.getHostname(), runner.getServerPort() ); e.printStackTrace(); } } } } public static AbstractRestOperation<Result> newRestOp( HttpOp op, WebResource resource ) { return new AbstractRestOperation<Result>( op, resource ) {}; } public static AbstractRestOperation<Result> newRestOp( HttpOp op, String path, Runner runner ) { return new AbstractRestOperation<Result>( op, path, runner ) {}; } public static AbstractRestOperation<Result> newResetOp( WebResource resource ) { resource.path( Runner.RESET_POST ); return newRestOp( HttpOp.POST, resource ); } public static AbstractRestOperation<Result> newResetOp( Runner runner ) { return newRestOp( HttpOp.POST, Runner.RESET_POST, runner ); } public static AbstractRestOperation<Result> newStartOp( WebResource resource ) { resource.path( Runner.START_POST ); return newRestOp( HttpOp.POST, resource ); } public static AbstractRestOperation<Result> newStartOp( Runner runner ) { return newRestOp( HttpOp.POST, Runner.START_POST, runner ); } public static AbstractRestOperation<Result> newStopOp( WebResource resource ) { resource.path( Runner.STOP_POST ); return newRestOp( HttpOp.POST, resource ); } public static AbstractRestOperation<Result> newStopOp( Runner runner ) { return newRestOp( HttpOp.POST, Runner.STOP_POST, runner ); } public static AbstractRestOperation<Result> newStatusOp( WebResource resource ) { resource.path( Runner.STATUS_GET ); return newRestOp( HttpOp.GET, resource ); } public static AbstractRestOperation<Result> newStatusOp( Runner runner ) { return newRestOp( HttpOp.GET, Runner.STATUS_GET, runner ); } public static AbstractRestOperation<StatsSnapshot> newStatsOp( WebResource resource ) { resource.path( Runner.STATS_GET ); return new AbstractRestOperation<StatsSnapshot>( HttpOp.GET, resource ) {}; } public static AbstractRestOperation<StatsSnapshot> newStatsOp( Runner runner ) { return new AbstractRestOperation<StatsSnapshot>( HttpOp.GET, Runner.STATS_GET, runner ) {}; } /** * Performs a POST HTTP operation against the /start endpoint with a propagate query parameter. * * @param runner the runner which will perform the start operation * @return the result of the operation */ public static Result start( Runner runner ) { preparations( runner ); return newStartOp( runner ).execute( Result.class ); } /** * Performs a POST HTTP operation against the /reset endpoint with a propagate query parameter. * * @param runner the runner to perform the reset operation on * @return the result of the operation */ public static Result reset( Runner runner ) { preparations( runner ); return newResetOp( runner ).execute( Result.class ); } /** * Performs a POST HTTP operation against the /stop endpoint with a propagate query parameter. * * @param runner the runner which will perform the stop operation * @return the result of the operation */ public static Result stop( Runner runner ) { preparations( runner ); return newStopOp( runner ).execute( Result.class ); } /** * Performs a GET HTTP operation against the /status endpoint. * * @param runner the runner to perform the status operation on * * @return the result of the operation */ public static Result status( Runner runner ) { preparations( runner ); try { return newStatusOp( runner ).execute( Result.class ); } catch ( ClientHandlerException e ) { if ( e.getCause() instanceof SSLHandshakeException && e.getCause().toString().contains( "PKIX path building failed" ) ) { /* * Oddly this fails the first time but works the second time. Until * I get to the bottom of this and figure it out this is the work * around we will use to make sure this does not fail. We retry once * on the failure. */ return newStatusOp( runner ).execute( Result.class ); } } throw new RuntimeException( "If we got here then the retry also failed." ); } public static StatsSnapshot stats( Runner runner ) { preparations( runner ); return newStatsOp( runner ).execute( StatsSnapshot.class ); } public static WebResource addParams( WebResource resource, CoordinatorFig coordinator ) { Preconditions.checkNotNull( resource, "The 'resource' MUST NOT be null." ); Preconditions.checkNotNull( coordinator, "The 'coordinator' MUST NOT be null." ); resource = resource.queryParam( RestParams.USERNAME, coordinator.getUsername() ); return resource.queryParam( RestParams.PASSWORD, coordinator.getPassword() ); } public static WebResource addParams( WebResource resource, Runner runner ) { Preconditions.checkNotNull( resource, "The 'resource' MUST NOT be null." ); Preconditions.checkNotNull( runner, "The 'runner' MUST NOT be null." ); resource = resource.queryParam( RestParams.RUNNER_URL, runner.getUrl() ); resource = resource.queryParam( RestParams.RUNNER_HOSTNAME, runner.getHostname() ); resource = resource.queryParam( RestParams.RUNNER_IPV4_ADDRESS, runner.getIpv4Address() ); return resource.queryParam( RestParams.RUNNER_PORT, String.valueOf( runner.getServerPort() ) ); } public static WebResource addParams( WebResource resource, Project project ) { Preconditions.checkNotNull( resource, "The 'resource' MUST NOT be null." ); Preconditions.checkNotNull( project, "The 'project' MUST NOT be null." ); resource = resource.queryParam( RestParams.MODULE_ARTIFACTID, project.getArtifactId() ); resource = resource.queryParam( RestParams.MODULE_GROUPID, project.getGroupId() ); resource = resource.queryParam( RestParams.MODULE_VERSION, project.getVersion() ); resource = resource.queryParam( RestParams.COMMIT_ID, project.getVcsVersion() ); resource = resource.queryParam( RestParams.TEST_PACKAGE, project.getTestPackageBase() ); resource = resource.queryParam( RestParams.MD5, project.getMd5() ); return resource.queryParam( RestParams.VCS_REPO_URL, project.getVcsRepoUrl() ); } }