001/* 002 * (C) Copyright 2013 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl-2.1.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * dmetzler 016 */ 017package org.nuxeo.ecm.restapi.test; 018 019import static org.junit.Assert.assertEquals; 020import static org.junit.Assert.assertTrue; 021 022import java.io.IOException; 023import java.io.InputStream; 024import java.util.ArrayList; 025import java.util.Iterator; 026import java.util.List; 027import java.util.Map; 028 029import javax.inject.Inject; 030import javax.ws.rs.core.MediaType; 031import javax.ws.rs.core.MultivaluedMap; 032import javax.ws.rs.core.Response; 033 034import org.codehaus.jackson.JsonNode; 035import org.codehaus.jackson.JsonProcessingException; 036import org.codehaus.jackson.map.ObjectMapper; 037import org.junit.Before; 038import org.nuxeo.ecm.core.api.CoreSession; 039import org.nuxeo.ecm.core.api.DocumentModel; 040import org.nuxeo.runtime.transaction.TransactionHelper; 041 042import com.sun.jersey.api.client.Client; 043import com.sun.jersey.api.client.ClientResponse; 044import com.sun.jersey.api.client.WebResource; 045import com.sun.jersey.api.client.WebResource.Builder; 046import com.sun.jersey.api.client.config.ClientConfig; 047import com.sun.jersey.api.client.config.DefaultClientConfig; 048import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter; 049import com.sun.jersey.multipart.MultiPart; 050import com.sun.jersey.multipart.impl.MultiPartWriter; 051 052/** 053 * @since 5.7.2 054 */ 055public class BaseTest { 056 057 private static final Integer TIMEOUT = Integer.valueOf(1000 * 60 * 5); // 5min 058 059 protected static enum RequestType { 060 GET, POST, DELETE, PUT, POSTREQUEST, GETES 061 } 062 063 protected ObjectMapper mapper; 064 065 protected Client client; 066 067 protected WebResource service; 068 069 @Before 070 public void doBefore() throws Exception { 071 service = getServiceFor("Administrator", "Administrator"); 072 073 mapper = new ObjectMapper(); 074 075 } 076 077 /** 078 * @param user 079 * @param password 080 * @return 081 * @since 5.7.3 082 */ 083 protected WebResource getServiceFor(String user, String password) { 084 ClientConfig config = new DefaultClientConfig(); 085 config.getClasses().add(MultiPartWriter.class); 086 client = Client.create(config); 087 client.setConnectTimeout(TIMEOUT); 088 client.setReadTimeout(TIMEOUT); 089 client.addFilter(new HTTPBasicAuthFilter(user, password)); 090 091 return client.resource("http://localhost:18090/api/v1/"); 092 } 093 094 @Inject 095 public CoreSession session; 096 097 protected ClientResponse getResponse(RequestType requestType, String path) { 098 return getResponse(requestType, path, null, null, null, null); 099 } 100 101 protected ClientResponse getResponse(RequestType requestType, String path, Map<String, String> headers) { 102 return getResponse(requestType, path, null, null, null, headers); 103 } 104 105 protected ClientResponse getResponse(RequestType requestType, String path, MultiPart mp) { 106 return getResponse(requestType, path, null, null, mp, null); 107 } 108 109 protected ClientResponse getResponse(RequestType requestType, String path, MultiPart mp, Map<String, String> headers) { 110 return getResponse(requestType, path, null, null, mp, headers); 111 } 112 113 protected ClientResponse getResponse(RequestType requestType, String path, 114 MultivaluedMap<String, String> queryParams) { 115 return getResponse(requestType, path, null, queryParams, null, null); 116 } 117 118 protected ClientResponse getResponse(RequestType requestType, String path, String data) { 119 return getResponse(requestType, path, data, null, null, null); 120 } 121 122 protected ClientResponse getResponse(RequestType requestType, String path, String data, Map<String, String> headers) { 123 return getResponse(requestType, path, data, null, null, headers); 124 } 125 126 protected ClientResponse getResponse(RequestType requestType, String path, String data, 127 MultivaluedMap<String, String> queryParams, MultiPart mp, Map<String, String> headers) { 128 WebResource wr = service.path(path); 129 130 if (queryParams != null && !queryParams.isEmpty()) { 131 wr = wr.queryParams(queryParams); 132 } 133 Builder builder; 134 if (requestType == RequestType.GETES) { 135 builder = wr.accept("application/json+esentity"); 136 } else { 137 builder = wr.accept(MediaType.APPLICATION_JSON).header("X-NXDocumentProperties", "dublincore"); 138 } 139 if (mp != null) { 140 builder = wr.type(MediaType.MULTIPART_FORM_DATA_TYPE); 141 } 142 143 if (headers == null || !(headers.containsKey("Content-Type"))) { 144 if (requestType == RequestType.POSTREQUEST) { 145 builder.header("Content-Type", "application/json+nxrequest"); 146 } else { 147 builder.header("Content-Type", "application/json+nxentity"); 148 } 149 } 150 151 // Adding some headers if needed 152 if (headers != null && !headers.isEmpty()) { 153 for (String headerKey : headers.keySet()) { 154 builder.header(headerKey, headers.get(headerKey)); 155 } 156 } 157 switch (requestType) { 158 case GET: 159 case GETES: 160 return builder.get(ClientResponse.class); 161 case POST: 162 case POSTREQUEST: 163 if (mp != null) { 164 return builder.post(ClientResponse.class, mp); 165 } else { 166 return builder.post(ClientResponse.class, data); 167 } 168 case PUT: 169 if (mp != null) { 170 return builder.put(ClientResponse.class, mp); 171 } else { 172 return builder.put(ClientResponse.class, data); 173 } 174 case DELETE: 175 return builder.delete(ClientResponse.class, data); 176 default: 177 throw new RuntimeException(); 178 } 179 } 180 181 protected JsonNode getResponseAsJson(RequestType responseType, String url) throws IOException, 182 JsonProcessingException { 183 return getResponseAsJson(responseType, url, null); 184 } 185 186 /** 187 * @param get 188 * @param string 189 * @param queryParamsForPage 190 * @return 191 * @throws IOException 192 * @throws JsonProcessingException 193 * @since 5.8 194 */ 195 protected JsonNode getResponseAsJson(RequestType responseType, String url, 196 MultivaluedMap<String, String> queryParams) throws JsonProcessingException, IOException { 197 ClientResponse response = getResponse(responseType, url, queryParams); 198 assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); 199 return mapper.readTree(response.getEntityInputStream()); 200 } 201 202 /** 203 * Fetch session invalidations. 204 * 205 * @since 5.9.3 206 */ 207 protected void fetchInvalidations() { 208 session.save(); 209 if (TransactionHelper.isTransactionActiveOrMarkedRollback()) { 210 TransactionHelper.commitOrRollbackTransaction(); 211 TransactionHelper.startTransaction(); 212 } 213 } 214 215 protected void assertNodeEqualsDoc(JsonNode node, DocumentModel note) throws Exception { 216 assertEquals("document", node.get("entity-type").getValueAsText()); 217 assertEquals(note.getPathAsString(), node.get("path").getValueAsText()); 218 assertEquals(note.getId(), node.get("uid").getValueAsText()); 219 assertEquals(note.getTitle(), node.get("title").getValueAsText()); 220 } 221 222 protected List<JsonNode> getLogEntries(JsonNode node) { 223 assertEquals("documents", node.get("entity-type").getValueAsText()); 224 assertTrue(node.get("entries").isArray()); 225 List<JsonNode> result = new ArrayList<>(); 226 Iterator<JsonNode> elements = node.get("entries").getElements(); 227 while (elements.hasNext()) { 228 result.add(elements.next()); 229 } 230 return result; 231 } 232 233 /** 234 * @since 7.1 235 */ 236 protected String getErrorMessage(JsonNode node) { 237 assertEquals("exception", node.get("entity-type").getValueAsText()); 238 assertTrue(node.get("message").isTextual()); 239 return node.get("message").getValueAsText(); 240 } 241 242 protected void assertEntityEqualsDoc(InputStream in, DocumentModel doc) throws Exception { 243 244 JsonNode node = mapper.readTree(in); 245 assertNodeEqualsDoc(node, doc); 246 247 } 248}