예제 #1
0
func TestJSONArray(t *testing.T) {
	validJSON := []byte("{\"slice\": [{\"x\": \"a\", \"y\": \"b\"}, " +
		"{\"x\": \"c\", \"y\": \"d\"}, {\"x\": \"e\", \"y\": \"f\"}, " +
		"{\"x\": \"g\", \"y\": \"h\"}, {\"x\": \"i\", \"y\": \"j\"}] }")

	expected := TestingSlice{
		Slice: []Nested{
			{X: "a", Y: "b"},
			{X: "c", Y: "d"},
			{X: "e", Y: "f"},
			{X: "g", Y: "h"},
			{X: "i", Y: "j"},
		},
	}

	var testVal TestingSlice
	err := strict_json.Unmarshal(validJSON, &testVal)

	if err != nil {
		fmt.Println(err)
		t.Error("unmarshing valid JSON into struct with slice failed")
	} else if !reflect.DeepEqual(testVal, expected) {
		t.Error("non-matching unmarshalling with slice")
	}

	expectedArray := TestingArray{
		Slice: [5]Nested{
			{X: "a", Y: "b"},
			{X: "c", Y: "d"},
			{X: "e", Y: "f"},
			{X: "g", Y: "h"},
			{X: "i", Y: "j"},
		},
	}

	var testArrayVal TestingArray
	err = strict_json.Unmarshal(validJSON, &testArrayVal)

	if err != nil {
		fmt.Println(err)
		t.Error("unmarshing valid JSON into struct with array failed")
	} else if !reflect.DeepEqual(testArrayVal, expectedArray) {
		t.Error("non-matching unmarshalling with array")
	}

	tooManyJSON := []byte("{\"slice\": [{\"x\": \"a\", \"y\": \"b\"}, " +
		"{\"x\": \"c\", \"y\": \"d\"}, {\"x\": \"e\", \"y\": \"f\"}, " +
		"{\"x\": \"g\", \"y\": \"h\"}, {\"x\": \"i\", \"y\": \"j\"}, " +
		"{\"x\": \"k\", \"y\": \"l\"}]}")

	var testTooManyVal TestingArray
	err = strict_json.Unmarshal(tooManyJSON, &testTooManyVal)

	if err == nil {
		t.Error("array too short - should have returned error")
	}
	fmt.Println(err)
}
예제 #2
0
func TestStrictJSON(t *testing.T) {
	validJSON := []byte("{\"a\": 5, \"b\": 23.45, \"c\": {\"x\": \"hi\", \"y\": \"sup\"}}")
	expected := TestingType{A: 5, B: 23.45, C: Nested{X: "hi", Y: "sup"}}

	var testVal TestingType
	err := strict_json.Unmarshal(validJSON, &testVal)

	if err != nil {
		t.Error("unmarshaling valid JSON failed")
	} else if testVal != expected {
		t.Error("non-matching unmarshalling.\nGot", testVal, "expected", expected)
	}

	wrongFieldType := []byte("{\"a\": \"aaa\", \"b\": 23.45, \"c\": {\"x\": \"hi\", \"y\": \"sup\"}}")
	err = strict_json.Unmarshal(wrongFieldType, &testVal)

	if err == nil {
		t.Error("wrong field type - should have returned error")
	}
	fmt.Println(err)

	missingField := []byte("{\"b\": 23.45, \"c\": {\"x\": \"hi\", \"y\": \"sup\"}}")
	err = strict_json.Unmarshal(missingField, &testVal)

	if err == nil {
		t.Error("missing field - should have returned error")
	}
	fmt.Println(err)

	var testPtrVal TestingPtrType
	expectedPtr := TestingPtrType{A: 5, B: 23.45, C: &Nested{X: "hi", Y: "sup"}}
	err = strict_json.Unmarshal(validJSON, &testPtrVal)

	if err != nil {
		t.Error("unmarshing valid JSON into struct with pointer failed")
	} else if !reflect.DeepEqual(testPtrVal, expectedPtr) {
		t.Error("non-matching unmarshalling with pointer")
	}

	fmt.Println(expectedPtr)
	fmt.Println(expectedPtr.C)

	expectedMap := TestingMapType{A: 5, B: 23.45, C: map[string]interface{}{"x": "hi", "y": "sup"}}
	var testMapVal TestingMapType
	err = strict_json.Unmarshal(validJSON, &testMapVal)

	if err != nil {
		t.Error("unmarshing valid JSON into struct with map failed")
	} else if !reflect.DeepEqual(testMapVal, expectedMap) {
		t.Error("non-matching unmarshalling with pointer")
	}

	fmt.Println(testMapVal)
}
예제 #3
0
func (b *Broker) handleRegConsumer(w http.ResponseWriter, r *http.Request, body []byte) {
	var msg RegisterConsumerMessage
	err := strict_json.Unmarshal(body, &msg)
	if err != nil {
		http.Error(w, err.Error(), 400)
		return
	}

	var consID [16]byte
	_, err = rand.Read(consID[:])
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

	b.RWLock.Lock()
	defer b.RWLock.Unlock()

	consumer := NewConsumer()
	consumer.Area = msg.Bounds()
	consumer.ID = base64.URLEncoding.EncodeToString(consID[:])
	consumer.TreeNode = b.ConsumerTree.Insert(consumer, consumer.Area)

	b.ConsumerMap[consumer.ID] = consumer

	consumer.Coroner = time.AfterFunc(CoronerTimeout, func() {
		if consumer.InWait {
			consumer.Coroner.Reset(CoronerTimeout)
		} else {
			b.RemoveConsumer(consumer)
		}
	})

	w.Write([]byte(fmt.Sprintf(`{"consumer_id": "%s"}`, consumer.ID)))
}
예제 #4
0
func (b *Broker) handleProduce(w http.ResponseWriter, r *http.Request, body []byte) {
	var msg ProducerMessage
	err := strict_json.Unmarshal(body, &msg)
	if err != nil {
		http.Error(w, err.Error(), 400)
		return
	}

	longitude := msg.Location.Longitude
	latitude := msg.Location.Latitude

	storedData := make([]interface{}, len(msg.Data))
	for i := 0; i < len(msg.Data); i++ {
		storedData[i] = &QueuedMessage{
			Location: msg.Location,
			Data:     msg.Data[i],
		}
	}

	b.RWLock.RLock()
	defer b.RWLock.RUnlock()

	b.ConsumerTree.Visit(longitude, latitude, func(value interface{}, bounds rtree.Rect) {
		consumer := value.(*Consumer)
		consumer.MessageQueue.PutMany(storedData)
	})

	w.Write([]byte("cheers"))
}
예제 #5
0
func (r *Registry) announceProducer(w http.ResponseWriter, req *http.Request, body []byte) {
	var msg AnnounceProducerMessage
	err := strict_json.Unmarshal(body, &msg)
	if err != nil {
		http.Error(w, err.Error(), 400)
		return
	}

	r.RWLock.RLock()
	defer r.RWLock.RUnlock()

	pointsMap := make(map[string]int, 20)
	for _, broker := range r.BrokerList {
		broker.ConsumerTree.Visit(msg.Longitude, msg.Latitude, func(value interface{}, bounds rtree.Rect) {
			consumer := value.(*Consumer)
			broker := consumer.Broker
			points, ok := pointsMap[broker.URL]
			if !ok {
				pointsMap[broker.URL] = 1
			} else {
				pointsMap[broker.URL] = points + 1
			}
		})
	}

	var bestURL string
	bestPoints := -1
	for k, v := range pointsMap {
		if v > bestPoints {
			bestURL = k
		}
	}

	w.Write([]byte(fmt.Sprintf(`{"broker_url": "%s"}`, bestURL)))
}
예제 #6
0
func (r *Registry) announceConsumer(w http.ResponseWriter, req *http.Request, body []byte) {
	registerConsumer := false
	consumerID := ""
	var consumer *Consumer

	var msg AnnounceConsumerMessage
	err := strict_json.Unmarshal(body, &msg)
	if err != nil {
		http.Error(w, err.Error(), 400)
		return
	}

	// Take the write lock - we will always be modifying the rtree
	r.RWLock.Lock()
	defer r.RWLock.Unlock()

	pathParts := strings.Split(req.URL.Path, "/")
	switch len(pathParts) {
	case 3:
		registerConsumer = true
	case 4:
		consumerID = pathParts[3]
		var ok bool
		consumer, ok = r.ConsumerMap[consumerID]
		if !ok {
			registerConsumer = true
		}
	}

	if registerConsumer {
		var consID [16]byte
		_, err = rand.Read(consID[:])
		if err != nil {
			http.Error(w, err.Error(), 500)
			return
		}
		consumer = NewConsumer()
		consumer.Area = msg.Bounds()
		consumer.ID = base64.URLEncoding.EncodeToString(consID[:])

		consumer.Coroner = time.AfterFunc(CoronerTimeout, func() {
			r.RemoveConsumer(consumer)
		})
	}

	err = r.AddConsumer(consumer)
	if err != nil {
		w.Write([]byte(err.Error()))
		return
	}

	consumer.Coroner.Reset(CoronerTimeout)

	w.Write([]byte(fmt.Sprintf(`{"consumer_id": "%s", "broker_url": "%s"}`, consumer.ID, consumer.Broker.URL)))
}
예제 #7
0
func (r *Registry) announceBroker(w http.ResponseWriter, req *http.Request, body []byte) {
	var msg AnnounceBrokerMessage
	err := strict_json.Unmarshal(body, &msg)
	if err != nil {
		http.Error(w, err.Error(), 400)
		return
	}

	r.RWLock.RLock()
	broker, ok := r.BrokerMap[msg.URL]

	if ok {
		broker.Coroner.Reset(CoronerTimeout)
		r.RWLock.RUnlock()
		w.Write([]byte("OK"))
		return
	}

	// Need to add the broker
	r.RWLock.RUnlock()
	r.RWLock.Lock()
	defer r.RWLock.Unlock()

	// Recheck condition in case it changed after we dropped the lock
	broker, ok = r.BrokerMap[msg.URL]

	if ok {
		broker.Coroner.Reset(CoronerTimeout)
		w.Write([]byte("OK"))
		return
	}

	broker = NewBroker()
	broker.URL = msg.URL

	broker.Coroner = time.AfterFunc(CoronerTimeout, func() {
		r.RemoveBroker(broker)
	})

	r.BrokerMap[msg.URL] = broker
	r.BrokerList = append(r.BrokerList, broker)

	w.Write([]byte("OK"))
}