001/* 002 * (C) Copyright 2018 Nuxeo (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Kevin Leturc <kleturc@nuxeo.com> 018 */ 019package org.nuxeo.jaxrs.test; 020 021import java.util.Collections; 022import java.util.HashMap; 023import java.util.Map; 024import java.util.Map.Entry; 025import java.util.function.Function; 026 027import org.junit.rules.TestRule; 028import org.junit.runner.Description; 029import org.junit.runners.model.Statement; 030 031import com.google.common.base.Splitter; 032import com.sun.jersey.api.client.Client; 033import com.sun.jersey.api.client.ClientResponse; 034import com.sun.jersey.api.client.WebResource; 035 036/** 037 * @since 10.1 038 */ 039public class HttpClientTestRule implements TestRule { 040 041 public static final String APPLICATION_JSON_NXENTITY = "application/json+nxentity"; 042 043 public static final String ADMINISTRATOR = "Administrator"; 044 045 private final String url; 046 047 private final String username; 048 049 private final String password; 050 051 private final String accept; 052 053 private final Map<String, String> headers; 054 055 protected Client client; 056 057 protected WebResource service; 058 059 private HttpClientTestRule(Builder builder) { 060 this.url = builder.url; 061 this.username = builder.username; 062 this.password = builder.password; 063 this.accept = builder.accept; 064 this.headers = builder.headers; 065 } 066 067 @Override 068 public Statement apply(Statement base, Description description) { 069 return new Statement() { 070 071 @Override 072 public void evaluate() throws Throwable { 073 starting(description); 074 try { 075 base.evaluate(); 076 } finally { 077 finished(description); 078 } 079 } 080 }; 081 } 082 083 protected void starting(Description description) { 084 client = JerseyClientHelper.clientBuilder().setCredentials(username, password).build(); 085 service = client.resource(url); 086 } 087 088 protected void finished(Description description) { 089 client.destroy(); 090 } 091 092 public CloseableClientResponse get(String path) { 093 return execute(path, builder -> builder.get(ClientResponse.class)); 094 } 095 096 public CloseableClientResponse post(String path, Object data) { 097 return execute(path, builder -> builder.post(ClientResponse.class, data)); 098 } 099 100 public CloseableClientResponse put(String path, Object data) { 101 return execute(path, builder -> builder.put(ClientResponse.class, data)); 102 } 103 104 public CloseableClientResponse delete(String path) { 105 return execute(path, builder -> builder.delete(ClientResponse.class)); 106 } 107 108 protected CloseableClientResponse execute(String path, Function<WebResource.Builder, ClientResponse> invoker) { 109 // extract queryParams from path 110 Map<String, String> queryParams = Collections.emptyMap(); 111 int interrogationIdx = path.indexOf('?'); 112 if (interrogationIdx >= 0) { 113 queryParams = Splitter.on('&').withKeyValueSeparator('=').split(path.substring(interrogationIdx + 1)); 114 path = path.substring(0, interrogationIdx); 115 } 116 WebResource webResource = service.path(path); 117 for (Entry<String, String> entry : queryParams.entrySet()) { 118 webResource = webResource.queryParam(entry.getKey(), entry.getValue()); 119 } 120 WebResource.Builder builder = webResource.accept(accept); 121 headers.forEach(builder::header); 122 return invoker.andThen(CloseableClientResponse::of).apply(builder); 123 } 124 125 /** 126 * The http client test rule builder. This builder is used to pass default parameters to client and requests. 127 */ 128 public static class Builder { 129 130 private String url; 131 132 private String username; 133 134 private String password; 135 136 private String accept; 137 138 private Map<String, String> headers; 139 140 public Builder() { 141 this.url = System.getProperty("nuxeoURL", "http://localhost:8080/nuxeo").replaceAll("/$", ""); 142 this.username = null; 143 this.password = null; 144 this.accept = APPLICATION_JSON_NXENTITY; 145 this.headers = new HashMap<>(); 146 } 147 148 public Builder url(String url) { 149 this.url = url; 150 return this; 151 } 152 153 public Builder adminCredentials() { 154 return credentials(ADMINISTRATOR, ADMINISTRATOR); 155 } 156 157 public Builder credentials(String username, String password) { 158 this.username = username; 159 this.password = password; 160 return this; 161 } 162 163 public Builder accept(String accept) { 164 this.accept = accept; 165 return this; 166 } 167 168 public Builder header(String key, String value) { 169 headers.put(key, value); 170 return this; 171 } 172 173 public HttpClientTestRule build() { 174 return new HttpClientTestRule(this); 175 } 176 177 } 178 179}