blob: 92635983bca07b2cbbf95f4833af38ca78d31b06 [file] [log] [blame]
/*
* 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.sling.commons.testing.integration;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
/** Client functions to interact with Sling in integration tests */
public class SlingIntegrationTestClient {
private final HttpClient httpClient;
public SlingIntegrationTestClient(HttpClient client) {
this.httpClient = client;
}
/** Upload a file to the Sling repository
* @return the HTTP status code
*/
public int upload(String toUrl, InputStream is) throws IOException {
final PutMethod put = new PutMethod(toUrl);
put.setRequestEntity(new InputStreamRequestEntity(is));
return httpClient.executeMethod(put);
}
/** Delete a file from the Sling repository
* @return the HTTP status code
*/
public int delete(String url) throws IOException {
final DeleteMethod delete = new DeleteMethod(url);
return httpClient.executeMethod(delete);
}
/** Create the given directory via WebDAV, if needed, under given URL */
public void mkdir(String url) throws IOException {
int status = 0;
status = httpClient.executeMethod(new GetMethod(url + ".txt"));
if(status != 200) {
status = httpClient.executeMethod(new HttpAnyMethod("MKCOL",url));
if(status!=201) {
throw new IOException("mkdir(" + url + ") failed, status code=" + status);
}
}
}
/** Create the given directory via WebDAV, including parent directories */
public void mkdirs(String baseUrl,String path) throws IOException {
final String [] paths = path.split("/");
if(baseUrl.endsWith("/")) {
baseUrl = baseUrl.substring(0,baseUrl.length() - 1);
}
String currentPath = baseUrl;
for(String pathElement : paths) {
if(pathElement.length() == 0) {
continue;
}
currentPath += "/" + pathElement;
mkdir(currentPath);
}
final String url = baseUrl + path;
final int status = httpClient.executeMethod(new GetMethod(url + ".txt"));
if(status!=200) {
throw new HttpStatusCodeException(200, status, "GET", url);
}
}
/** Call the other createNode method with headers==null */
public String createNode(String url, Map<String,String> nodeProperties) throws IOException {
return createNode(url, nodeProperties, null, false);
}
/** Create a node under given path, using a POST to Sling
* @param url under which node is created
* @param multiPart if true, does a multipart POST
* @return the URL that Sling provides to display the node
*/
public String createNode(String url, Map<String,String> clientNodeProperties, Map<String,String> requestHeaders,boolean multiPart)
throws IOException {
return createNode(url, new NameValuePairList(clientNodeProperties), requestHeaders, multiPart);
}
/** Create a node under given path, using a POST to Sling
* @param url under which node is created
* @param multiPart if true, does a multipart POST
* @return the URL that Sling provides to display the node
*/
public String createNode(String url, NameValuePairList clientNodeProperties, Map<String,String> requestHeaders, boolean multiPart)
throws IOException {
return createNode(url, clientNodeProperties, requestHeaders, multiPart, null, null, null);
}
/** Create a node under given path, using a POST to Sling
* @param url under which node is created
* @param multiPart if true, does a multipart POST
* @param localFile file to upload
* @param fieldName name of the file field
* @param typeHint typeHint of the file field
* @return the URL that Sling provides to display the node
*/
public String createNode(String url, NameValuePairList clientNodeProperties, Map<String,String> requestHeaders, boolean multiPart,
File localFile, String fieldName, String typeHint)
throws IOException {
final PostMethod post = new PostMethod(url);
post.setFollowRedirects(false);
// create a private copy of the properties to not tamper with
// the properties of the client
NameValuePairList nodeProperties = new NameValuePairList(clientNodeProperties);
// add sling specific properties
nodeProperties.prependIfNew(":redirect", "*");
nodeProperties.prependIfNew(":displayExtension", "");
nodeProperties.prependIfNew(":status", "browser");
// add fake property - otherwise the node is not created
if (clientNodeProperties == null) {
nodeProperties.add("jcr:created", "");
}
// force form encoding to UTF-8, which is what we use to convert the
// string parts into stream data
nodeProperties.addOrReplace("_charset_", "UTF-8");
if( nodeProperties.size() > 0) {
if(multiPart) {
final List<Part> partList = new ArrayList<Part>();
for(NameValuePair e : nodeProperties) {
if (e.getValue() != null) {
partList.add(new StringPart(e.getName(), e.getValue(), "UTF-8"));
}
}
if (localFile != null) {
partList.add(new FilePart(fieldName, localFile));
if (typeHint != null) {
partList.add(new StringPart(fieldName + "@TypeHint", typeHint));
}
}
final Part [] parts = partList.toArray(new Part[partList.size()]);
post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
} else {
post.getParams().setContentCharset("UTF-8");
for(NameValuePair e : nodeProperties) {
post.addParameter(e.getName(),e.getValue());
}
}
}
if(requestHeaders != null) {
for(Map.Entry<String,String> e : requestHeaders.entrySet()) {
post.addRequestHeader(e.getKey(), e.getValue());
}
}
final int expected = 302;
final int status = httpClient.executeMethod(post);
if(status!=expected) {
throw new HttpStatusCodeException(expected, status, "POST", url, HttpTestBase.getResponseBodyAsStream(post, 0));
}
String location = post.getResponseHeader("Location").getValue();
post.releaseConnection();
// simple check if host is missing
if (!location.startsWith("http://")) {
String host = HttpTestBase.HTTP_BASE_URL;
int idx = host.indexOf('/', 8);
if (idx > 0) {
host = host.substring(0, idx);
}
location = host + location;
}
return location;
}
/** Upload to an file node structure, see SLING-168 */
public void uploadToFileNode(String url, File localFile, String fieldName, String typeHint)
throws IOException {
final Part[] parts = new Part[typeHint == null ? 1 : 2];
parts[0] = new FilePart(fieldName, localFile);
if (typeHint != null) {
parts[1] = new StringPart(fieldName + "@TypeHint", typeHint);
}
final PostMethod post = new PostMethod(url);
post.setFollowRedirects(false);
post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
final int status = httpClient.executeMethod(post);
final int expected = 200;
if(status!=expected) {
throw new HttpStatusCodeException(expected, status, "POST", HttpTestBase.getResponseBodyAsStream(post, 0));
}
}
/** Upload multiple files to file node structures */
public void uploadToFileNodes(String url, File[] localFiles, String[] fieldNames, String[] typeHints)
throws IOException {
List<Part> partsList = new ArrayList<Part>();
for (int i=0; i < localFiles.length; i++) {
Part filePart = new FilePart(fieldNames[i], localFiles[i]);
partsList.add(filePart);
if (typeHints != null) {
Part typeHintPart = new StringPart(fieldNames[i] + "@TypeHint", typeHints[i]);
partsList.add(typeHintPart);
}
}
final Part[] parts = partsList.toArray(new Part[partsList.size()]);
final PostMethod post = new PostMethod(url);
post.setFollowRedirects(false);
post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
final int expected = 200;
final int status = httpClient.executeMethod(post);
if(status!=expected) {
throw new HttpStatusCodeException(expected, status, "POST", HttpTestBase.getResponseBodyAsStream(post, 0));
}
}
public int post(String url, Map<String,String> properties) throws HttpException, IOException {
final PostMethod post = new PostMethod(url);
post.getParams().setContentCharset("UTF-8");
for(Entry<String, String> e : properties.entrySet()) {
post.addParameter(e.getKey(), e.getValue());
}
return httpClient.executeMethod(post);
}
public int get(String url) throws HttpException, IOException {
final GetMethod get = new GetMethod(url);
get.getParams().setContentCharset("UTF-8");
return httpClient.executeMethod(get);
}
}