/* * JBoss, Home of Professional Open Source * Copyright 2011-2013 Red Hat Inc. and/or its affiliates and other contributors * as indicated by the @author tags. All rights reserved. * See the copyright.txt in the distribution for a * full listing of individual contributors. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU Lesser General Public License, v. 2.1. * This program is distributed in the hope that it will be useful, but WITHOUT A * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License, * v.2.1 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package org.infinispan.server.endpoint.subsystem; import static org.infinispan.server.endpoint.subsystem.PrefixResource.PREFIX_ATTRIBUTES; import static org.infinispan.server.endpoint.subsystem.SniResource.SNI_ATTRIBUTES; import java.util.Collections; import java.util.List; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import org.jboss.as.controller.AttributeDefinition; import org.jboss.as.controller.SimpleAttributeDefinition; import org.jboss.as.controller.SimpleListAttributeDefinition; import org.jboss.as.controller.StringListAttributeDefinition; import org.jboss.as.controller.persistence.SubsystemMarshallingContext; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; import org.jboss.dmr.Property; import org.jboss.staxmapper.XMLElementWriter; import org.jboss.staxmapper.XMLExtendedStreamWriter; /** * The XML writer for the endpoint subsystem configuration. * * @author <a href="http://gleamynode.net/">Trustin Lee</a> * @author <a href="http://www.dataforte.net/blog/">Tristan Tarrant</a> * */ class EndpointSubsystemWriter implements XMLStreamConstants, XMLElementWriter<SubsystemMarshallingContext> { EndpointSubsystemWriter() { } @Override public void writeContent(final XMLExtendedStreamWriter writer, final SubsystemMarshallingContext context) throws XMLStreamException { context.startSubsystemElement(Namespace.CURRENT.getUri(), false); final ModelNode node = context.getModelNode(); writeConnectors(writer, node); writer.writeEndElement(); } private void writeConnectors(final XMLExtendedStreamWriter writer, final ModelNode node) throws XMLStreamException { for (Property property : getConnectorsByType(node, ModelKeys.HOTROD_CONNECTOR)) { writeHotRodConnector(writer, property.getValue()); } for (Property property : getConnectorsByType(node, ModelKeys.MEMCACHED_CONNECTOR)) { writeMemcachedConnector(writer, property.getValue()); } for (Property property : getConnectorsByType(node, ModelKeys.REST_CONNECTOR)) { writeRestConnector(writer, property.getValue()); } for (Property property : getConnectorsByType(node, ModelKeys.WEBSOCKET_CONNECTOR)) { writeWebSocketConnector(writer, property.getValue()); } for (Property property : getConnectorsByType(node, ModelKeys.ROUTER_CONNECTOR)) { writeRouterConnector(writer, property.getValue()); } } private List<Property> getConnectorsByType(final ModelNode node, String connectorType) { if (node.hasDefined(connectorType)) { ModelNode connectors = node.get(connectorType); return connectors.asPropertyList(); } else { return Collections.emptyList(); } } private void writeHotRodConnector(final XMLExtendedStreamWriter writer, final ModelNode connector) throws XMLStreamException { writer.writeStartElement(Element.HOTROD_CONNECTOR.getLocalName()); writeCommonConnector(writer, connector); writeProtocolServerConnector(writer, connector); writeTopologyStateTransfer(writer, connector); writeAuthentication(writer, connector); writeEncryption(writer, connector); writer.writeEndElement(); } private void writeMemcachedConnector(final XMLExtendedStreamWriter writer, final ModelNode connector) throws XMLStreamException { writer.writeStartElement(Element.MEMCACHED_CONNECTOR.getLocalName()); writeCommonConnector(writer, connector); writeProtocolServerConnector(writer, connector); for (SimpleAttributeDefinition attribute : MemcachedConnectorResource.MEMCACHED_CONNECTOR_ATTRIBUTES) { attribute.marshallAsAttribute(connector, true, writer); } writer.writeEndElement(); } private void writeRestConnector(final XMLExtendedStreamWriter writer, final ModelNode connector) throws XMLStreamException { writer.writeStartElement(Element.REST_CONNECTOR.getLocalName()); writeCommonConnector(writer, connector); for (SimpleAttributeDefinition attribute : RestConnectorResource.REST_ATTRIBUTES) { attribute.marshallAsAttribute(connector, true, writer); } writeRestAuthentication(writer, connector); writeEncryption(writer, connector); writer.writeEndElement(); } private void writeWebSocketConnector(final XMLExtendedStreamWriter writer, final ModelNode connector) throws XMLStreamException { writer.writeStartElement(Element.WEBSOCKET_CONNECTOR.getLocalName()); writeCommonConnector(writer, connector); writeProtocolServerConnector(writer, connector); writer.writeEndElement(); } private void writeRouterConnector(final XMLExtendedStreamWriter writer, final ModelNode connector) throws XMLStreamException { writer.writeStartElement(Element.ROUTER_CONNECTOR.getLocalName()); for (SimpleAttributeDefinition attribute : RouterConnectorResource.ROUTER_CONNECTOR_ATTRIBUTES) { attribute.marshallAsAttribute(connector, true, writer); } writer.writeStartElement(Element.MULTI_TENANCY.getLocalName()); ModelNode multiTenancy = connector.get(ModelKeys.MULTI_TENANCY, ModelKeys.MULTI_TENANCY_NAME); writeHotrod(writer, multiTenancy); writeRest(writer, multiTenancy); writer.writeEndElement(); //multi-tenancy writer.writeEndElement(); //router-connector } private void writeHotrod(XMLExtendedStreamWriter writer, ModelNode parentNode) throws XMLStreamException { if (parentNode.hasDefined(ModelKeys.HOTROD)) { for (ModelNode hotrodNode: parentNode.get(ModelKeys.HOTROD).asList()) { writer.writeStartElement(Element.HOTROD.getLocalName()); for (SimpleAttributeDefinition hotrodAttribute : RouterHotRodResource.ROUTER_HOTROD_ATTRIBUTES) { hotrodAttribute.marshallAsAttribute(hotrodNode.get(0), true, writer); } writeSni(writer, hotrodNode.get(0)); writer.writeEndElement(); } } } private void writeRest(XMLExtendedStreamWriter writer, ModelNode parentNode) throws XMLStreamException { if (parentNode.hasDefined(ModelKeys.REST)) { for (ModelNode hotrodNode: parentNode.get(ModelKeys.REST).asList()) { writer.writeStartElement(Element.REST.getLocalName()); for (SimpleAttributeDefinition hotrodAttribute : RouterRestResource.ROUTER_REST_ATTRIBUTES) { hotrodAttribute.marshallAsAttribute(hotrodNode.get(0), true, writer); } writePrefix(writer, hotrodNode.get(0)); writer.writeEndElement(); } } } private void writeCommonConnector(final XMLExtendedStreamWriter writer, final ModelNode connector) throws XMLStreamException { for (SimpleAttributeDefinition attribute : CommonConnectorResource.COMMON_CONNECTOR_ATTRIBUTES) { attribute.marshallAsAttribute(connector, true, writer); } SimpleListAttributeDefinition ignoredCaches = CommonConnectorResource.IGNORED_CACHES; writeListAsAttribute(writer, ignoredCaches.getXmlName(), connector, ignoredCaches.getName()); } private void writeProtocolServerConnector(final XMLExtendedStreamWriter writer, final ModelNode connector) throws XMLStreamException { for (SimpleAttributeDefinition attribute : ProtocolServerConnectorResource.PROTOCOL_SERVICE_ATTRIBUTES) { attribute.marshallAsAttribute(connector, true, writer); } } private void writeTopologyStateTransfer(final XMLExtendedStreamWriter writer, final ModelNode connector) throws XMLStreamException { if (connector.hasDefined(ModelKeys.TOPOLOGY_STATE_TRANSFER)) { ModelNode topologyStateTransfer = connector.get(ModelKeys.TOPOLOGY_STATE_TRANSFER, ModelKeys.TOPOLOGY_STATE_TRANSFER_NAME); writer.writeStartElement(Element.TOPOLOGY_STATE_TRANSFER.getLocalName()); for (SimpleAttributeDefinition attribute : TopologyStateTransferResource.TOPOLOGY_ATTRIBUTES) { attribute.marshallAsAttribute(topologyStateTransfer, true, writer); } writer.writeEndElement(); } } private void writeSni(final XMLExtendedStreamWriter writer, final ModelNode parentNode) throws XMLStreamException { if (parentNode.hasDefined(ModelKeys.SNI)) { for (ModelNode mapping: parentNode.get(ModelKeys.SNI).asList()) { writer.writeStartElement(Element.SNI.getLocalName()); for (SimpleAttributeDefinition sniMappingAttribute : SNI_ATTRIBUTES) { sniMappingAttribute.marshallAsAttribute(mapping.get(0), true, writer); } writer.writeEndElement(); } } } private void writePrefix(final XMLExtendedStreamWriter writer, final ModelNode parentNode) throws XMLStreamException { if (parentNode.hasDefined(ModelKeys.PREFIX)) { for (ModelNode mapping: parentNode.get(ModelKeys.PREFIX).asList()) { writer.writeStartElement(Element.PREFIX.getLocalName()); for (SimpleAttributeDefinition prefixMappingAttribute : PREFIX_ATTRIBUTES) { prefixMappingAttribute.marshallAsAttribute(mapping.get(0), true, writer); } writer.writeEndElement(); } } } private void writeAuthentication(final XMLExtendedStreamWriter writer, final ModelNode connector) throws XMLStreamException { if (connector.hasDefined(ModelKeys.AUTHENTICATION)) { ModelNode authentication = connector.get(ModelKeys.AUTHENTICATION, ModelKeys.AUTHENTICATION_NAME); writer.writeStartElement(Element.AUTHENTICATION.getLocalName()); for (SimpleAttributeDefinition attribute : AuthenticationResource.AUTHENTICATION_ATTRIBUTES) { attribute.marshallAsAttribute(authentication, true, writer); } writeSasl(writer, authentication); writer.writeEndElement(); } } private void writeSasl(final XMLExtendedStreamWriter writer, final ModelNode authentication) throws XMLStreamException { if (authentication.hasDefined(ModelKeys.SASL)) { ModelNode sasl = authentication.get(ModelKeys.SASL, ModelKeys.SASL_NAME); writer.writeStartElement(Element.SASL.getLocalName()); for (AttributeDefinition attribute : SaslResource.SASL_ATTRIBUTES) { if (attribute instanceof SimpleAttributeDefinition) { ((SimpleAttributeDefinition)attribute).marshallAsAttribute(sasl, true, writer); } else if (attribute instanceof StringListAttributeDefinition) { writeListAsAttribute(writer, attribute.getXmlName(), sasl, attribute.getName()); } } writePolicy(writer, sasl); writeProperties(writer, sasl); writer.writeEndElement(); } } private void writePolicy(final XMLExtendedStreamWriter writer, final ModelNode sasl) throws XMLStreamException { if (sasl.hasDefined(ModelKeys.SASL_POLICY)) { ModelNode policy = sasl.get(ModelKeys.SASL_POLICY, ModelKeys.SASL_POLICY_NAME); writer.writeStartElement(Element.POLICY.getLocalName()); SaslPolicyResource.FORWARD_SECRECY.marshallAsElement(policy, writer); SaslPolicyResource.NO_ACTIVE.marshallAsElement(policy, writer); SaslPolicyResource.NO_ANONYMOUS.marshallAsElement(policy, writer); SaslPolicyResource.NO_DICTIONARY.marshallAsElement(policy, writer); SaslPolicyResource.NO_PLAIN_TEXT.marshallAsElement(policy, writer); SaslPolicyResource.PASS_CREDENTIALS.marshallAsElement(policy, writer); writer.writeEndElement(); } } private void writeRestAuthentication(final XMLExtendedStreamWriter writer, final ModelNode connector) throws XMLStreamException { if (connector.hasDefined(ModelKeys.AUTHENTICATION)) { ModelNode authentication = connector.get(ModelKeys.AUTHENTICATION, ModelKeys.AUTHENTICATION_NAME); writer.writeStartElement(Element.AUTHENTICATION.getLocalName()); for (SimpleAttributeDefinition attribute : RestAuthenticationResource.AUTHENTICATION_ATTRIBUTES) { attribute.marshallAsAttribute(authentication, true, writer); } writer.writeEndElement(); } } private void writeProperties(XMLExtendedStreamWriter writer, ModelNode sasl) throws XMLStreamException { if (sasl.hasDefined(ModelKeys.PROPERTY)) { for (Property property: sasl.get(ModelKeys.PROPERTY).asPropertyList()) { writer.writeStartElement(Element.PROPERTY.getLocalName()); writer.writeAttribute(Attribute.NAME.getLocalName(), property.getName()); Property complexValue = property.getValue().asProperty(); writer.writeCharacters(complexValue.getValue().asString()); writer.writeEndElement(); } } } private void writeEncryption(final XMLExtendedStreamWriter writer, final ModelNode connector) throws XMLStreamException { if (connector.hasDefined(ModelKeys.ENCRYPTION)) { ModelNode encryption = connector.get(ModelKeys.ENCRYPTION, ModelKeys.ENCRYPTION_NAME); writer.writeStartElement(Element.ENCRYPTION.getLocalName()); for (SimpleAttributeDefinition attribute : EncryptionResource.ENCRYPTION_ATTRIBUTES) { attribute.marshallAsAttribute(encryption, true, writer); } writeSni(writer, encryption); writer.writeEndElement(); } } private void writeListAsAttribute(XMLExtendedStreamWriter writer, String attributeName, ModelNode node, String key) throws XMLStreamException { if (node.hasDefined(key)) { StringBuilder result = new StringBuilder(); ModelNode list = node.get(key); if (list.isDefined() && list.getType() == ModelType.LIST) { List<ModelNode> nodeList = list.asList(); for (int i = 0; i < nodeList.size(); i++) { result.append(nodeList.get(i).asString()); if (i < nodeList.size() - 1) { result.append(" "); } } writer.writeAttribute(attributeName, result.toString()); } } } }