blob: 7a76363a4cb72617821f052d8d99fb5231145aea [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.qpid.tests.http.rest.model;
import static java.util.Collections.singletonMap;
import static javax.servlet.http.HttpServletResponse.SC_CREATED;
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.oneOf;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Test;
import org.apache.qpid.server.logging.logback.VirtualHostFileLogger;
import org.apache.qpid.server.logging.logback.VirtualHostNameAndLevelLogInclusionRule;
import org.apache.qpid.server.model.AbstractConfiguredObject;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.User;
import org.apache.qpid.server.security.NonJavaKeyStore;
import org.apache.qpid.server.security.NonJavaTrustStore;
import org.apache.qpid.test.utils.tls.TlsResourceBuilder;
import org.apache.qpid.server.util.DataUrlUtils;
import org.apache.qpid.server.util.FileUtils;
import org.apache.qpid.test.utils.tls.KeyCertificatePair;
import org.apache.qpid.tests.http.HttpRequestConfig;
import org.apache.qpid.tests.http.HttpTestBase;
@HttpRequestConfig
public class ReadTest extends HttpTestBase
{
private static final String QUEUE1_NAME = "myqueue1";
private static final String QUEUE2_NAME = "myqueue2";
private static final String QUEUE1_URL = String.format("queue/%s", QUEUE1_NAME);
private static final String QUEUE2_URL = String.format("queue/%s", QUEUE2_NAME);
@Before
public void setUp()
{
getBrokerAdmin().createQueue(QUEUE1_NAME);
getBrokerAdmin().createQueue(QUEUE2_NAME);
}
@Test
public void readObject() throws Exception
{
final Map<String, Object> queue = getHelper().getJsonAsMap(QUEUE1_URL);
assertThat(queue.get(ConfiguredObject.NAME), is(equalTo(QUEUE1_NAME)));
assertThat(queue.get(ConfiguredObject.ID), is(notNullValue()));
}
@Test
public void notFound() throws Exception
{
getHelper().submitRequest("queue/unknown", "GET", SC_NOT_FOUND);
}
@Test
public void readObjectResponseAsList() throws Exception
{
final Map<String, Object> queue = getHelper().getJsonAsSingletonList(QUEUE1_URL + "?singletonModelObjectResponseAsList=true");
assertThat(queue.get(ConfiguredObject.NAME), is(equalTo(QUEUE1_NAME)));
assertThat(queue.get(ConfiguredObject.ID), is(notNullValue()));
}
@Test
public void readAll() throws Exception
{
List<Map<String, Object>> list = getHelper().getJsonAsList("queue");
assertThat(list.size(), is(equalTo(2)));
Set<String> queueNames = list.stream()
.map(map -> (String) map.get(ConfiguredObject.NAME))
.collect(Collectors.toSet());
assertThat(queueNames, containsInAnyOrder(QUEUE1_NAME, QUEUE2_NAME));
}
@Test
public void readFilter() throws Exception
{
final Map<String, Object> queue1 = getHelper().getJsonAsMap(QUEUE1_URL);
List<Map<String, Object>> list = getHelper().getJsonAsList(String.format("queue/?%s=%s",
ConfiguredObject.ID,
queue1.get(ConfiguredObject.ID)));
assertThat(list.size(), is(equalTo(1)));
final Map<String, Object> queue = list.get(0);
assertThat(queue.get(ConfiguredObject.NAME), is(equalTo(QUEUE1_NAME)));
assertThat(queue.get(ConfiguredObject.ID), is(notNullValue()));
}
@Test
public void filterNotFound() throws Exception
{
List<Map<String, Object>> list = getHelper().getJsonAsList(String.format("queue/?%s=%s",
ConfiguredObject.ID,
UUID.randomUUID()));
assertThat(list.size(), is(equalTo(0)));
}
@Test
public void readHierarchy() throws Exception
{
final Map<String, Object> virtualHost = getHelper().getJsonAsMap("virtualhost?depth=2");
assertThat(virtualHost.get(ConfiguredObject.ID), is(notNullValue()));
assertThat(virtualHost.get(ConfiguredObject.NAME), is(equalTo(getVirtualHost())));
@SuppressWarnings("unchecked")
List<Map<String, Object>> queues = (List<Map<String, Object>>) virtualHost.get("queues");
assertThat(queues.size(), is(equalTo(2)));
}
@Test
public void excludeInheritedContext() throws Exception
{
final String hostContextKey = "myvhcontextvar";
final String hostContextValue = UUID.randomUUID().toString();
final Map<String, Object> hostUpdateAttrs = singletonMap(ConfiguredObject.CONTEXT,
singletonMap(hostContextKey, hostContextValue));
getHelper().submitRequest("virtualhost", "POST", hostUpdateAttrs, SC_OK);
final String queueContextKey = "myqueuecontextvar";
final String queueContextValue = UUID.randomUUID().toString();
final Map<String, Object> queueUpdateAttrs = singletonMap(ConfiguredObject.CONTEXT,
singletonMap(queueContextKey, queueContextValue));
getHelper().submitRequest(QUEUE1_URL, "POST", queueUpdateAttrs, SC_OK);
final Map<String, Object> queue = getHelper().getJsonAsMap(QUEUE1_URL);
@SuppressWarnings("unchecked")
Map<String, Object> context = (Map<String, Object>) queue.get("context");
assertThat(context.size(), is(equalTo(1)));
assertThat(context.get(queueContextKey), is(equalTo(queueContextValue)));
final Map<String, Object> queue2 = getHelper().getJsonAsMap(QUEUE1_URL + "?excludeInheritedContext=false");
@SuppressWarnings("unchecked")
Map<String, Object> context2 = (Map<String, Object>) queue2.get("context");
assertThat(context2.size(), is(greaterThanOrEqualTo(2)));
assertThat(context2.get(queueContextKey), is(equalTo(queueContextValue)));
assertThat(context2.get(hostContextKey), is(equalTo(hostContextValue)));
}
@Test
public void actuals() throws Exception
{
final String queueContextKey = "myqueuecontextvar";
final String queueContextValue = UUID.randomUUID().toString();
final Map<String, Object> queueUpdateAttrs = new HashMap<>();
queueUpdateAttrs.put(ConfiguredObject.DESCRIPTION, "${myqueuecontextvar}");
queueUpdateAttrs.put(ConfiguredObject.CONTEXT, singletonMap(queueContextKey, queueContextValue));
getHelper().submitRequest(QUEUE1_URL, "POST", queueUpdateAttrs, SC_OK);
final Map<String, Object> queue = getHelper().getJsonAsMap(QUEUE1_URL);
assertThat(queue.get(ConfiguredObject.DESCRIPTION), is(equalTo(queueContextValue)));
final Map<String, Object> queueActuals = getHelper().getJsonAsMap(QUEUE1_URL + "?actuals=true");
assertThat(queueActuals.get(ConfiguredObject.DESCRIPTION), is(equalTo("${myqueuecontextvar}")));
}
@Test
public void wildcards() throws Exception
{
String rule1A = createLoggerAndRule("mylogger1", "myinclusionruleA");
String rule1B = createLoggerAndRule("mylogger1", "myinclusionruleB");
String rule2A = createLoggerAndRule("mylogger2", "myinclusionruleA");
{
List<Map<String, Object>> rules = getHelper().getJsonAsList("virtualhostloginclusionrule/*");
assertThat(rules.size(), is(equalTo(3)));
Set<String> ids = rules.stream().map(ReadTest::getId).collect(Collectors.toSet());
assertThat(ids, containsInAnyOrder(rule1A, rule1B, rule2A));
}
{
List<Map<String, Object>> rules = getHelper().getJsonAsList("virtualhostloginclusionrule/mylogger1/*");
assertThat(rules.size(), is(equalTo(2)));
Set<String> ids = rules.stream().map(ReadTest::getId).collect(Collectors.toSet());
assertThat(ids, containsInAnyOrder(rule1A, rule1B));
}
{
List<Map<String, Object>> rules = getHelper().getJsonAsList("virtualhostloginclusionrule/*/myinclusionruleA");
assertThat(rules.size(), is(equalTo(2)));
Set<String> ids = rules.stream().map(ReadTest::getId).collect(Collectors.toSet());
assertThat(ids, containsInAnyOrder(rule1A, rule2A));
}
}
@Test
@HttpRequestConfig(useVirtualHostAsHost = false)
public void secureAttributes() throws Exception
{
final String validUsername = getBrokerAdmin().getValidUsername();
final Map<String, Object> user = getHelper().getJsonAsMap("user/plain/" + validUsername);
assertThat(user.get(User.NAME), is(equalTo(validUsername)));
assertThat(user.get(User.PASSWORD), is(equalTo(AbstractConfiguredObject.SECURED_STRING_VALUE)));
}
@Test
@HttpRequestConfig(useVirtualHostAsHost = false)
public void valueFilteredSecureAttributes() throws Exception
{
final KeyCertificatePair keyCertPair = generateCertKeyPair();
final byte[] privateKey = keyCertPair.getPrivateKey().getEncoded();
final byte[] cert = keyCertPair.getCertificate().getEncoded();
final String privateKeyUrl = DataUrlUtils.getDataUrlForBytes(privateKey);
final String certUrl = DataUrlUtils.getDataUrlForBytes(cert);
final File privateKeyFile = File.createTempFile("foo" + System.currentTimeMillis(), "key");
privateKeyFile.deleteOnExit();
FileUtils.copy(new ByteArrayInputStream(privateKey), privateKeyFile);
Map<String, Object> base = new HashMap<>();
base.put(NonJavaKeyStore.TYPE, "NonJavaKeyStore");
base.put(NonJavaKeyStore.CERTIFICATE_URL, certUrl);
try
{
{
final String storeUrl = "keystore/mystoreDataUrl";
final Map<String, Object> attrs = new HashMap<>(base);
attrs.put(NonJavaKeyStore.PRIVATE_KEY_URL, privateKeyUrl);
getHelper().submitRequest(storeUrl, "PUT", attrs, SC_CREATED);
final Map<String, Object> store = getHelper().getJsonAsMap(storeUrl);
assertThat(store.get(NonJavaKeyStore.PRIVATE_KEY_URL),
is(equalTo(AbstractConfiguredObject.SECURED_STRING_VALUE)));
getHelper().submitRequest(storeUrl, "DELETE", SC_OK);
}
{
final String privateKeyFileUrl = privateKeyFile.toURI().toString();
final String storeUrl = "keystore/mystoreFileUrl";
final Map<String, Object> attrs = new HashMap<>(base);
attrs.put(NonJavaKeyStore.TYPE, "NonJavaKeyStore");
attrs.put(NonJavaKeyStore.PRIVATE_KEY_URL, privateKeyFileUrl);
getHelper().submitRequest(storeUrl, "PUT", attrs, SC_CREATED);
final Map<String, Object> store = getHelper().getJsonAsMap(String.format("%s?oversize=%d", storeUrl, privateKeyFileUrl.length()));
assertThat(store.get(NonJavaKeyStore.PRIVATE_KEY_URL), is(equalTo(privateKeyFileUrl)));
getHelper().submitRequest(storeUrl, "DELETE", SC_OK);
}
}
finally
{
privateKeyFile.delete();
}
}
@Test
@HttpRequestConfig(useVirtualHostAsHost = false)
public void oversizeAttribute() throws Exception
{
final byte[] encodedCert = generateCertKeyPair().getCertificate().getEncoded();
final String dataUrl = DataUrlUtils.getDataUrlForBytes(encodedCert);
final String storeUrl = "truststore/mystore";
final Map<String, Object> attrs = new HashMap<>();
attrs.put(NonJavaTrustStore.TYPE, "NonJavaTrustStore");
attrs.put(NonJavaTrustStore.CERTIFICATES_URL, dataUrl);
getHelper().submitRequest(storeUrl, "PUT", attrs, SC_CREATED);
final Map<String, Object> store = getHelper().getJsonAsMap(storeUrl);
assertThat(store.get(NonJavaTrustStore.CERTIFICATES_URL), is(equalTo(AbstractConfiguredObject.OVER_SIZED_ATTRIBUTE_ALTERNATIVE_TEXT)));
final Map<String, Object> full = getHelper().getJsonAsMap(storeUrl + String.format("?oversize=%d", dataUrl.length()));
assertThat(full.get(NonJavaTrustStore.CERTIFICATES_URL), is(equalTo(dataUrl)));
getHelper().submitRequest(storeUrl, "DELETE", SC_OK);
}
private String createLoggerAndRule(final String loggerName, final String inclusionRuleName) throws Exception
{
final String parentUrl = String.format("virtualhostlogger/%s", loggerName);
Map<String, Object> parentAttrs = Collections.singletonMap(ConfiguredObject.TYPE, VirtualHostFileLogger.TYPE);
int response = getHelper().submitRequest(parentUrl, "PUT", parentAttrs);
assertThat(response, is(oneOf(SC_CREATED, SC_OK)));
final String childUrl = String.format("virtualhostloginclusionrule/%s/%s", loggerName, inclusionRuleName);
Map<String, Object> childAttrs = Collections.singletonMap(ConfiguredObject.TYPE, VirtualHostNameAndLevelLogInclusionRule.TYPE);
getHelper().submitRequest(childUrl, "PUT", childAttrs, SC_CREATED);
final Map<String, Object> child = getHelper().getJsonAsMap(childUrl);
return (String) child.get(ConfiguredObject.ID);
}
private static String getId(Map<String, Object> object)
{
return ((String) object.get(ConfiguredObject.ID));
}
private KeyCertificatePair generateCertKeyPair() throws Exception
{
return TlsResourceBuilder.createSelfSigned("CN=foo");
}
}