Example #1
0
func NewFromMethod(method *amqp.ExchangeDeclare, system bool, exchangeDeleter chan *Exchange) (*Exchange, *amqp.AMQPError) {
	var classId, methodId = method.MethodIdentifier()
	var tp, err = ExchangeNameToType(method.Type)
	if err != nil || tp == EX_TYPE_HEADERS {
		return nil, amqp.NewHardError(503, "Bad exchange type", classId, methodId)
	}
	var ex = NewExchange(
		method.Exchange,
		tp,
		method.Durable,
		method.AutoDelete,
		method.Internal,
		method.Arguments,
		system,
		exchangeDeleter,
	)
	return ex, nil
}
Example #2
0
func (channel *Channel) exchangeDeclare(method *amqp.ExchangeDeclare) *amqp.AMQPError {
	var classId, methodId = method.MethodIdentifier()
	// The client I'm using for testing thought declaring the empty exchange
	// was OK. Check later
	// if len(method.Exchange) > 0 && !method.Passive {
	// 	var msg = "The empty exchange name is reserved"
	// 	channel.channelErrorWithMethod(406, msg, classId, methodId)
	// 	return nil
	// }

	// Check the name format
	var err = amqp.CheckExchangeOrQueueName(method.Exchange)
	if err != nil {
		return amqp.NewSoftError(406, err.Error(), classId, methodId)
	}

	// Declare!
	var ex, amqpErr = exchange.NewFromMethod(method, false, channel.server.exchangeDeleter)
	if amqpErr != nil {
		return amqpErr
	}
	tp, err := exchange.ExchangeNameToType(method.Type)
	if err != nil || tp == exchange.EX_TYPE_HEADERS {
		return amqp.NewHardError(503, err.Error(), classId, methodId)
	}
	existing, hasKey := channel.server.exchanges[ex.Name]
	if !hasKey && method.Passive {
		return amqp.NewSoftError(404, "Exchange does not exist", classId, methodId)
	}
	if hasKey {
		// if diskLoad {
		// 	panic(fmt.Sprintf("Can't disk load a key that exists: %s", ex.Name))
		// }
		if existing.ExType != ex.ExType {
			return amqp.NewHardError(530, "Cannot redeclare an exchange with a different type", classId, methodId)
		}
		if existing.EquivalentExchanges(ex) {
			if !method.NoWait {
				channel.SendMethod(&amqp.ExchangeDeclareOk{})
			}
			return nil
		}
		// Not equivalent, error in passive mode
		if method.Passive {
			return amqp.NewSoftError(406, "Exchange with this name already exists", classId, methodId)
		}
	}
	if method.Passive {
		if !method.NoWait {
			channel.SendMethod(&amqp.ExchangeDeclareOk{})
		}
		return nil
	}

	// outside of passive mode you can't create an exchange starting with
	// amq.
	if strings.HasPrefix(method.Exchange, "amq.") {
		return amqp.NewSoftError(403, "Exchange names starting with 'amq.' are reserved", classId, methodId)
	}

	err = channel.server.addExchange(ex)
	if err != nil {
		return amqp.NewSoftError(500, err.Error(), classId, methodId)
	}
	err = ex.Persist(channel.server.db)
	if err != nil {
		return amqp.NewSoftError(500, err.Error(), classId, methodId)
	}
	if !method.NoWait {
		channel.SendMethod(&amqp.ExchangeDeclareOk{})
	}
	return nil
}