001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.activemq.transport.stomp; 018 019import java.io.IOException; 020 021import javax.jms.JMSException; 022 023import org.apache.activemq.broker.BrokerContext; 024import org.apache.activemq.command.Command; 025import org.apache.activemq.transport.Transport; 026import org.apache.activemq.transport.TransportFilter; 027import org.apache.activemq.transport.TransportListener; 028import org.apache.activemq.util.IOExceptionSupport; 029import org.apache.activemq.wireformat.WireFormat; 030import org.slf4j.Logger; 031import org.slf4j.LoggerFactory; 032 033/** 034 * The StompTransportFilter normally sits on top of a TcpTransport that has been 035 * configured with the StompWireFormat and is used to convert STOMP commands to 036 * ActiveMQ commands. All of the conversion work is done by delegating to the 037 * ProtocolConverter. 038 * 039 * @author <a href="http://hiramchirino.com">chirino</a> 040 */ 041public class StompTransportFilter extends TransportFilter implements StompTransport { 042 private static final Logger TRACE = LoggerFactory.getLogger(StompTransportFilter.class.getPackage().getName() + ".StompIO"); 043 private final ProtocolConverter protocolConverter; 044 private StompInactivityMonitor monitor; 045 private StompWireFormat wireFormat; 046 047 private boolean trace; 048 049 public StompTransportFilter(Transport next, WireFormat wireFormat, BrokerContext brokerContext) { 050 super(next); 051 this.protocolConverter = new ProtocolConverter(this, brokerContext); 052 053 if (wireFormat instanceof StompWireFormat) { 054 this.wireFormat = (StompWireFormat) wireFormat; 055 } 056 } 057 058 @Override 059 public void oneway(Object o) throws IOException { 060 try { 061 final Command command = (Command) o; 062 protocolConverter.onActiveMQCommand(command); 063 } catch (JMSException e) { 064 throw IOExceptionSupport.create(e); 065 } 066 } 067 068 @Override 069 public void onCommand(Object command) { 070 try { 071 if (trace) { 072 TRACE.trace("Received: \n" + command); 073 } 074 075 protocolConverter.onStompCommand((StompFrame) command); 076 } catch (IOException e) { 077 onException(e); 078 } catch (JMSException e) { 079 onException(IOExceptionSupport.create(e)); 080 } 081 } 082 083 @Override 084 public void sendToActiveMQ(Command command) { 085 TransportListener l = transportListener; 086 if (l != null) { 087 l.onCommand(command); 088 } 089 } 090 091 @Override 092 public void sendToStomp(StompFrame command) throws IOException { 093 if (trace) { 094 TRACE.trace("Sending: \n" + command); 095 } 096 Transport n = next; 097 if (n != null) { 098 n.oneway(command); 099 } 100 } 101 102 public boolean isTrace() { 103 return trace; 104 } 105 106 public void setTrace(boolean trace) { 107 this.trace = trace; 108 } 109 110 @Override 111 public StompInactivityMonitor getInactivityMonitor() { 112 return monitor; 113 } 114 115 public void setInactivityMonitor(StompInactivityMonitor monitor) { 116 this.monitor = monitor; 117 } 118 119 @Override 120 public StompWireFormat getWireFormat() { 121 return this.wireFormat; 122 } 123 124 public String getDefaultHeartBeat() { 125 return protocolConverter != null ? protocolConverter.getDefaultHeartBeat() : null; 126 } 127 128 public void setDefaultHeartBeat(String defaultHeartBeat) { 129 protocolConverter.setDefaultHeartBeat(defaultHeartBeat); 130 } 131 132 /** 133 * Returns the currently configured Read check grace period multiplier. 134 * 135 * @return the hbGracePeriodMultiplier 136 */ 137 public float getHbGracePeriodMultiplier() { 138 return protocolConverter != null ? protocolConverter.getHbGracePeriodMultiplier() : null; 139 } 140 141 /** 142 * Sets the read check grace period multiplier. New CONNECT frames that indicate a heart beat 143 * value with a read check interval will have that value multiplied by this value to add a 144 * grace period before the connection is considered invalid. By default this value is set to 145 * zero and no grace period is given. When set the value must be larger than 1.0 or it will 146 * be ignored. 147 * 148 * @param hbGracePeriodMultiplier the hbGracePeriodMultiplier to set 149 */ 150 public void setHbGracePeriodMultiplier(float hbGracePeriodMultiplier) { 151 if (hbGracePeriodMultiplier > 1.0f) { 152 protocolConverter.setHbGracePeriodMultiplier(hbGracePeriodMultiplier); 153 } 154 } 155 156}