org.apache.activemq.transport.ws.AbstractMQTTSocket Maven / Gradle / Ivy
/**
* 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.activemq.transport.ws;
import java.io.IOException;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.BrokerServiceAware;
import org.apache.activemq.command.Command;
import org.apache.activemq.jms.pool.IntrospectionSupport;
import org.apache.activemq.transport.TransportSupport;
import org.apache.activemq.transport.mqtt.MQTTInactivityMonitor;
import org.apache.activemq.transport.mqtt.MQTTProtocolConverter;
import org.apache.activemq.transport.mqtt.MQTTTransport;
import org.apache.activemq.transport.mqtt.MQTTWireFormat;
import org.apache.activemq.util.IOExceptionSupport;
import org.apache.activemq.util.ServiceStopper;
import org.fusesource.mqtt.codec.MQTTFrame;
public abstract class AbstractMQTTSocket extends TransportSupport implements MQTTTransport, BrokerServiceAware {
protected ReentrantLock protocolLock = new ReentrantLock();
protected volatile MQTTProtocolConverter protocolConverter = null;
protected MQTTWireFormat wireFormat = new MQTTWireFormat();
protected final MQTTInactivityMonitor mqttInactivityMonitor = new MQTTInactivityMonitor(this, wireFormat);
protected final CountDownLatch socketTransportStarted = new CountDownLatch(1);
protected BrokerService brokerService;
protected volatile int receiveCounter;
protected final String remoteAddress;
protected X509Certificate[] peerCertificates;
private Map transportOptions;
public AbstractMQTTSocket(String remoteAddress) {
super();
this.remoteAddress = remoteAddress;
}
@Override
public void oneway(Object command) throws IOException {
protocolLock.lock();
try {
getProtocolConverter().onActiveMQCommand((Command)command);
} catch (Exception e) {
onException(IOExceptionSupport.create(e));
} finally {
protocolLock.unlock();
}
}
@Override
public void sendToActiveMQ(Command command) {
protocolLock.lock();
try {
doConsume(command);
} finally {
protocolLock.unlock();
}
}
@Override
protected void doStop(ServiceStopper stopper) throws Exception {
mqttInactivityMonitor.stop();
handleStopped();
}
@Override
protected void doStart() throws Exception {
socketTransportStarted.countDown();
mqttInactivityMonitor.setTransportListener(getTransportListener());
mqttInactivityMonitor.startConnectChecker(wireFormat.getConnectAttemptTimeout());
}
//----- Abstract methods for subclasses to implement ---------------------//
@Override
public abstract void sendToMQTT(MQTTFrame command) throws IOException;
/**
* Called when the transport is stopping to allow the dervied classes
* a chance to close WebSocket resources.
*
* @throws IOException if an error occurs during the stop.
*/
public abstract void handleStopped() throws IOException;
//----- Accessor methods -------------------------------------------------//
@Override
public MQTTInactivityMonitor getInactivityMonitor() {
return mqttInactivityMonitor;
}
@Override
public MQTTWireFormat getWireFormat() {
return wireFormat;
}
@Override
public String getRemoteAddress() {
return remoteAddress;
}
@Override
public int getReceiveCounter() {
return receiveCounter;
}
@Override
public X509Certificate[] getPeerCertificates() {
return peerCertificates;
}
@Override
public void setPeerCertificates(X509Certificate[] certificates) {
this.peerCertificates = certificates;
}
@Override
public void setBrokerService(BrokerService brokerService) {
this.brokerService = brokerService;
}
//----- Internal support methods -----------------------------------------//
protected MQTTProtocolConverter getProtocolConverter() {
if (protocolConverter == null) {
synchronized(this) {
if (protocolConverter == null) {
MQTTProtocolConverter newProtocolConverter = new MQTTProtocolConverter(this, brokerService);
IntrospectionSupport.setProperties(newProtocolConverter, transportOptions);
protocolConverter = newProtocolConverter;
}
}
}
return protocolConverter;
}
protected boolean transportStartedAtLeastOnce() {
return socketTransportStarted.getCount() == 0;
}
public void setTransportOptions(Map transportOptions) {
this.transportOptions = transportOptions;
}
}