blob: 33dde2026f75a447fbde1d6824a43b1b0abe851d [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.systests.jms_1_1.extensions;
import java.io.Closeable;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Session;
import javax.naming.NamingException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.User;
import org.apache.qpid.server.security.FileKeyStore;
import org.apache.qpid.server.security.FileTrustStore;
import org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManager;
import org.apache.qpid.systests.AmqpManagementFacade;
import org.apache.qpid.systests.ConnectionBuilder;
public class BrokerManagementHelper implements Closeable
{
private final ConnectionBuilder _connectionBuilder;
private final AmqpManagementFacade _managementFacade;
private Connection _connection;
public BrokerManagementHelper(final ConnectionBuilder connectionBuilder,
final AmqpManagementFacade managementFacade)
{
_connectionBuilder = connectionBuilder;
_managementFacade = managementFacade;
}
public BrokerManagementHelper openManagementConnection() throws JMSException, NamingException
{
_connection = _connectionBuilder.setVirtualHost("$management").build();
_connection.start();
return this;
}
public BrokerManagementHelper createKeyStore(final String keyStoreName,
final String keyStoreLocation,
final String keyStorePassword)
throws JMSException
{
final Map<String, Object> keyStoreAttributes = new HashMap<>();
keyStoreAttributes.put("storeUrl", keyStoreLocation);
keyStoreAttributes.put("password", keyStorePassword);
keyStoreAttributes.put("keyStoreType", java.security.KeyStore.getDefaultType());
return createEntity(keyStoreName, FileKeyStore.class.getName(), keyStoreAttributes);
}
public BrokerManagementHelper createTrustStore(final String trustStoreName,
final String trustStoreLocation,
final String trustStorePassword) throws JMSException
{
final Map<String, Object> trustStoreAttributes = new HashMap<>();
trustStoreAttributes.put("storeUrl", trustStoreLocation);
trustStoreAttributes.put("password", trustStorePassword);
trustStoreAttributes.put("trustStoreType", java.security.KeyStore.getDefaultType());
return createEntity(trustStoreName, FileTrustStore.class.getName(), trustStoreAttributes);
}
public BrokerManagementHelper createAmqpTlsPort(final String portName,
final String authenticationProvider,
final String keyStoreName,
final boolean plainAndSsl,
final boolean needClientAuth,
final boolean wantClientAuth,
final String... trustStoreName) throws JMSException
{
try
{
final Map<String, Object> sslPortAttributes = new HashMap<>();
sslPortAttributes.put(Port.TRANSPORTS, plainAndSsl ? "[\"SSL\",\"TCP\"]" : "[\"SSL\"]");
sslPortAttributes.put(Port.PORT, 0);
sslPortAttributes.put(Port.AUTHENTICATION_PROVIDER, authenticationProvider);
sslPortAttributes.put(Port.NEED_CLIENT_AUTH, needClientAuth);
sslPortAttributes.put(Port.WANT_CLIENT_AUTH, wantClientAuth);
sslPortAttributes.put(Port.NAME, portName);
sslPortAttributes.put(Port.KEY_STORE, keyStoreName);
sslPortAttributes.put(Port.TRUST_STORES, new ObjectMapper().writeValueAsString(trustStoreName));
createEntity(portName, "org.apache.qpid.AmqpPort", sslPortAttributes);
}
catch (JsonProcessingException e)
{
throw new RuntimeException("Unexpected json processing exception", e);
}
return this;
}
public BrokerManagementHelper createExternalAuthenticationProvider(String providerName, boolean useFullDN)
throws JMSException
{
final Map<String, Object> providerAttributes = new HashMap<>();
providerAttributes.put("qpid-type", ExternalAuthenticationManager.PROVIDER_TYPE);
providerAttributes.put(ExternalAuthenticationManager.ATTRIBUTE_USE_FULL_DN, useFullDN);
return createEntity(providerName,
AuthenticationProvider.class.getName(),
providerAttributes);
}
public BrokerManagementHelper createAuthenticationProvider(final String providerName, final String providerType)
throws JMSException
{
return createEntity(providerName,
AuthenticationProvider.class.getName(),
Collections.singletonMap("qpid-type", providerType));
}
public BrokerManagementHelper createUser(final String providerName,
final String userName,
final String userPassword)
throws JMSException
{
final Map<String, Object> userAttributes = new HashMap<>();
userAttributes.put("qpid-type", "managed");
userAttributes.put(User.PASSWORD, userPassword);
userAttributes.put("object-path", providerName);
return createEntity(userName, User.class.getName(), userAttributes);
}
public BrokerManagementHelper createEntity(final String name,
final String type,
final Map<String, Object> attributes) throws JMSException
{
final Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
try
{
_managementFacade.createEntityAndAssertResponse(name, type, attributes, session);
}
finally
{
session.close();
}
return this;
}
public int getAmqpBoundPort(final String portName) throws JMSException
{
return (int) getEffectiveAttribute(portName, "org.apache.qpid.AmqpPort", "boundPort");
}
public Object getEffectiveAttribute(final String name, final String type, String attributeName) throws JMSException
{
final Map<String, Object> effectiveAttributes = getEffectiveAttributes(name, type);
if (effectiveAttributes.containsKey(attributeName))
{
return effectiveAttributes.get(attributeName);
}
throw new RuntimeException(String.format("Attribute '%s' is not found", attributeName));
}
public Map<String, Object> getEffectiveAttributes(final String name, final String type) throws JMSException
{
final Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
try
{
return _managementFacade.readEntityUsingAmqpManagement(session, type, name, false);
}
finally
{
session.close();
}
}
protected List<Map<String, Object>> queryEntitiesUsingAmqpManagement(final String type)
throws JMSException
{
Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
try
{
return _managementFacade.managementQueryObjects(session, type);
}
finally
{
session.close();
}
}
public String getConnectionPrincipalByClientId(String portName, String clientId) throws JMSException
{
final List<Map<String, Object>> connections = queryEntitiesUsingAmqpManagement("org.apache.qpid.Connection");
for (final Map<String, Object> connection : connections)
{
final String name = String.valueOf(connection.get(ConfiguredObject.NAME));
final Map<String, Object> attributes =
getEffectiveAttributes(portName + "/" + name, "org.apache.qpid.Connection");
if (attributes.get(org.apache.qpid.server.model.Connection.CLIENT_ID).equals(clientId))
{
return String.valueOf(attributes.get(org.apache.qpid.server.model.Connection.PRINCIPAL));
}
}
return null;
}
public void close()
{
if (_connection != null)
{
try
{
_connection.close();
}
catch (JMSException e)
{
throw new RuntimeException("Failure to close JMS connection", e);
}
}
}
public String getAuthenticationProviderNameForAmqpPort(final int brokerPort)
throws JMSException
{
String authenticationProvider = null;
Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
try
{
List<Map<String, Object>> ports =
_managementFacade.managementQueryObjects(session, "org.apache.qpid.AmqpPort");
for (Map<String, Object> port : ports)
{
String name = String.valueOf(port.get(Port.NAME));
Session s = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
try
{
Map<String, Object> attributes = _managementFacade.readEntityUsingAmqpManagement(s,
"org.apache.qpid.AmqpPort",
name,
false);
if (attributes.get("boundPort").equals(brokerPort))
{
authenticationProvider = String.valueOf(attributes.get(Port.AUTHENTICATION_PROVIDER));
break;
}
}
finally
{
s.close();
}
}
}
finally
{
session.close();
}
return authenticationProvider;
}
}