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.amqp; 018 019import java.io.IOException; 020import java.util.ArrayList; 021 022import org.apache.activemq.broker.BrokerService; 023import org.apache.activemq.command.Command; 024 025/** 026 * Used to assign the best implementation of a AmqpProtocolConverter to the 027 * AmqpTransport based on the AmqpHeader that the client sends us. 028 */ 029public class AMQPProtocolDiscriminator implements IAmqpProtocolConverter { 030 031 public static final int DEFAULT_PREFETCH = 1000; 032 033 private final AmqpTransport transport; 034 private final BrokerService brokerService; 035 036 private int prefetch = 0; 037 private int producerCredit = DEFAULT_PREFETCH; 038 039 interface Discriminator { 040 boolean matches(AmqpHeader header); 041 042 IAmqpProtocolConverter create(AmqpTransport transport, BrokerService brokerService); 043 } 044 045 static final private ArrayList<Discriminator> DISCRIMINATORS = new ArrayList<Discriminator>(); 046 static { 047 DISCRIMINATORS.add(new Discriminator() { 048 049 @Override 050 public IAmqpProtocolConverter create(AmqpTransport transport, BrokerService brokerService) { 051 return new AmqpProtocolConverter(transport, brokerService); 052 } 053 054 @Override 055 public boolean matches(AmqpHeader header) { 056 switch (header.getProtocolId()) { 057 case 0: 058 case 3: 059 if (header.getMajor() == 1 && header.getMinor() == 0 && header.getRevision() == 0) { 060 return true; 061 } 062 } 063 return false; 064 } 065 }); 066 } 067 068 final private ArrayList<Command> pendingCommands = new ArrayList<Command>(); 069 070 public AMQPProtocolDiscriminator(AmqpTransport transport, BrokerService brokerService) { 071 this.transport = transport; 072 this.brokerService = brokerService; 073 } 074 075 @Override 076 public void onAMQPData(Object command) throws Exception { 077 if (command.getClass() == AmqpHeader.class) { 078 AmqpHeader header = (AmqpHeader) command; 079 080 Discriminator match = null; 081 for (Discriminator discriminator : DISCRIMINATORS) { 082 if (discriminator.matches(header)) { 083 match = discriminator; 084 } 085 } 086 087 // Lets use first in the list if none are a good match. 088 if (match == null) { 089 match = DISCRIMINATORS.get(0); 090 } 091 092 IAmqpProtocolConverter next = match.create(transport, brokerService); 093 next.setPrefetch(prefetch); 094 next.setProducerCredit(producerCredit); 095 transport.setProtocolConverter(next); 096 for (Command send : pendingCommands) { 097 next.onActiveMQCommand(send); 098 } 099 pendingCommands.clear(); 100 next.onAMQPData(command); 101 } else { 102 throw new IllegalStateException(); 103 } 104 } 105 106 @Override 107 public void onAMQPException(IOException error) { 108 } 109 110 @Override 111 public void onActiveMQCommand(Command command) throws Exception { 112 pendingCommands.add(command); 113 } 114 115 @Override 116 public void updateTracer() { 117 } 118 119 @Override 120 public void setPrefetch(int prefetch) { 121 this.prefetch = prefetch; 122 } 123 124 @Override 125 public void setProducerCredit(int producerCredit) { 126 this.producerCredit = producerCredit; 127 } 128}