示例#1
0
// setupRetainSubscriber returnes channel in order to read messages with retained flag
func setupRetainSubscriber(gw *gateway.Gateway, broker *broker.Broker, dummyDevice *device.DummyDevice) (chan [2]string, inidef.Error) {
	// Setup MQTT pub/sub client to confirm published content.
	//
	messageOutputChannel := make(chan [2]string)

	opts := MQTT.NewClientOptions()
	brokerUrl := fmt.Sprintf("tcp://%s:%d", broker.Host, broker.Port)
	opts.AddBroker(brokerUrl)
	opts.SetClientID(gw.Name + "testSubscriber") // to distinguish MQTT client from publisher
	opts.SetCleanSession(false)
	opts.SetDefaultPublishHandler(func(client *MQTT.Client, msg MQTT.Message) {
		messageOutputChannel <- [2]string{msg.Topic(), string(msg.Payload())}
	})

	client := MQTT.NewClient(opts)
	if client == nil {
		return nil, inidef.Error("NewClient failed")
	}

	if token := client.Connect(); token.Wait() && token.Error() != nil {
		return nil, inidef.Error(fmt.Sprintf("NewClient Start failed %q", token.Error()))
	}
	qos := 0
	retainedTopic := fmt.Sprintf("%s/%s/%s/%s", broker.TopicPrefix, gw.Name, dummyDevice.Name, dummyDevice.Type)
	client.Subscribe(retainedTopic, byte(qos), func(client *MQTT.Client, msg MQTT.Message) {
	})

	return messageOutputChannel, inidef.Error("")
}
示例#2
0
// setupWillSubscriber start subscriber process and returnes a channel witch can receive will message.
func setupWillSubscriber(gw *gateway.Gateway, broker *broker.Broker) (chan MQTT.Message, inidef.Error) {
	// Setup MQTT pub/sub client to confirm published content.
	//
	messageOutputChannel := make(chan MQTT.Message)

	opts := MQTT.NewClientOptions()
	brokerUrl := fmt.Sprintf("tcp://%s:%d", broker.Host, broker.Port)
	opts.AddBroker(brokerUrl)
	opts.SetClientID(gw.Name + "testSubscriber") // to distinguish MQTT client from publisher
	opts.SetCleanSession(false)
	opts.SetDefaultPublishHandler(func(client *MQTT.Client, msg MQTT.Message) {
		messageOutputChannel <- msg
	})

	client := MQTT.NewClient(opts)
	if client == nil {
		return nil, inidef.Error("NewClient failed")
	}
	if token := client.Connect(); token.Wait() && token.Error() != nil {
		return nil, inidef.Error(fmt.Sprintf("NewClient Start failed %q", token.Error()))
	}

	qos := 0
	// assume topicPrefix == ""
	willTopic := fmt.Sprintf("/%s/will", gw.Name)
	client.Subscribe(willTopic, byte(qos), func(client *MQTT.Client, msg MQTT.Message) {
		messageOutputChannel <- msg
	})

	return messageOutputChannel, inidef.Error("")
}
示例#3
0
文件: broker.go 项目: chansuke/fuji
// NewTLSConfig returns TLS config from CA Cert file path.
func NewTLSConfig(caCertFilePath string) (*tls.Config, error) {
	certPool := x509.NewCertPool()
	pemCerts, err := ioutil.ReadFile(caCertFilePath)
	if err != nil {
		return nil, inidef.Error("Cert File could not be read.")
	}
	appendCertOk := certPool.AppendCertsFromPEM(pemCerts)
	if appendCertOk != true {
		return nil, inidef.Error("Server Certificate parse failed")
	}

	// only server certificate checked
	return &tls.Config{
		RootCAs:    certPool,
		ClientAuth: tls.NoClientCert,
		ClientCAs:  nil,
		// InsecureSkipVerify = verify that cert contents
		// match server. IP matches what is in cert etc.
		InsecureSkipVerify: true,
	}, nil
}
示例#4
0
func genericWillTestDriver(t *testing.T, iniStr string, expectedTopic string, expectedPayload []byte) (ok bool) {
	assert := assert.New(t)

	conf, err := inidef.LoadConfigByte([]byte(iniStr))
	assert.Nil(err)
	commandChannel := make(chan string)
	go fuji.StartByFileWithChannel(conf, commandChannel)

	gw, err := gateway.NewGateway(conf)
	assert.Nil(err)

	brokers, err := broker.NewBrokers(conf, gw.BrokerChan)
	assert.Nil(err)

	go func() {
		time.Sleep(1 * time.Second)

		subscriberChannel, err := setupWillSubscriber(gw, brokers[0])
		if err != inidef.Error("") {
			t.Error(err)
		}

		time.Sleep(1 * time.Second)

		// kill publisher
		brokers[0].FourceClose()
		fmt.Println("broker killed for getting will message")

		// check will message
		willMsg := <-subscriberChannel

		assert.Equal(expectedTopic, willMsg.Topic())
		assert.Equal(expectedPayload, willMsg.Payload())
		assert.Equal(byte(0), willMsg.Qos())
	}()
	time.Sleep(3 * time.Second)
	ok = true
	return ok
}
示例#5
0
// TestRetainSubscribePublishClose
// 1. connect gateway to local broker
// 2. send data with retaind flag from dummy device
// 3. disconnect
// 4. reconnect
// 5. subscirbe and receive data
func TestRetainSubscribePublishClose(t *testing.T) {
	assert := assert.New(t)
	iniStr := `
	[gateway]
	
	    name = testRetainafterclose
	
	[broker "local/1"]
	
	    host = localhost
	    port = 1883
	
	[device "dora/dummy"]
	
	    broker = local
	    qos = 0
	
	    interval = 10
	    payload = Hello retained world to subscriber after close.
	
	    type = EnOcean
	    retain = true
`
	commandChannel := make(chan string)
	conf, err := inidef.LoadConfigByte([]byte(iniStr))
	assert.Nil(err)
	go fuji.StartByFileWithChannel(conf, commandChannel)

	gw, err := gateway.NewGateway(conf)
	if err != nil {
		t.Error("Cannot make Gateway")
	}

	brokerList, err := broker.NewBrokers(conf, gw.BrokerChan)
	if err != nil {
		t.Error("Cannot make BrokerList")
	}

	dummyDevice, err := device.NewDummyDevice(conf.Sections[3], brokerList, gw.DeviceChan)
	if err != nil {
		t.Error("Cannot make DummyDeviceList")
	}

	go func() {
		time.Sleep(2 * time.Second)

		// kill publisher
		gw.Stop()

		time.Sleep(2 * time.Second)

		subscriberChannel, err := setupRetainSubscriber(gw, brokerList[0], &dummyDevice)
		if err != inidef.Error("") {
			t.Error(err)
		}
		// check Retained message
		retainedMessage := <-subscriberChannel
		retainedTopic := retainedMessage[0]
		retainedPayload := retainedMessage[1]

		expectedTopic := fmt.Sprintf("%s/%s/%s/%s", brokerList[0].TopicPrefix, gw.Name, dummyDevice.Name, dummyDevice.Type)
		expectedPayload := dummyDevice.Payload

		assert.Equal(expectedTopic, retainedTopic)
		assert.Equal(expectedPayload, retainedPayload)
	}()
	time.Sleep(5 * time.Second)
}