Beispiel #1
0
func (req *ArchiveRequest) GetSmapMessage(thing interface{}) *common.SmapMessage {
	var msg = new(common.SmapMessage)
	var rdg = new(common.SmapNumberReading)

	value := ob.Eval(req.value, thing)
	switch t := value.(type) {
	case int64:
		rdg.Value = float64(t)
	case uint64:
		rdg.Value = float64(t)
	case float64:
		rdg.Value = t
	}

	rdg.Time = req.getTime(thing)

	if len(req.uuid) > 0 && req.uuidActual == "" {
		req.uuidActual = common.UUID(ob.Eval(req.uuid, thing).(string))
	} else if req.uuidActual == "" {
		req.uuidActual = common.UUID(req.UUID)
	}
	msg.UUID = req.uuidActual
	msg.Path = req.URI + "/" + req.Value
	msg.Readings = []common.Reading{rdg}

	if len(req.metadataExpr) > 0 {
		msg.Metadata = make(common.Dict)
		msg.Properties = new(common.SmapProperties)
		if md, ok := ob.Eval(req.metadataExpr, thing).(map[string]interface{}); ok {
			for k, v := range md {
				val := fmt.Sprintf("%s", v)
				if k == "UnitofTime" {
					msg.Properties.UnitOfTime, _ = common.ParseUOT(val)
				} else if k == "UnitofMeasure" {
					msg.Properties.UnitOfMeasure = val
				}
				msg.Metadata[k] = val
			}
		}
	}

	return msg
}
Beispiel #2
0
// Takes an incoming common.SmapMessage object (from a client) and does the following:
//  - Checks the incoming message against the ApiKey to verify it is valid to write
//  - Saves the attached metadata (if any) to the metadata store
//  - Reevaluates any dynamic subscriptions and pushes to republish clients
//  - Saves the attached readings (if any) to the timeseries database
func (a *Archiver) AddData(msg *common.SmapMessage) (err error) {
	// save metadata
	err = a.mdStore.SaveTags(msg)
	if err != nil {
		return err
	}

	// fix inconsistencies
	var (
		uot common.UnitOfTime
		uom string
	)
	if uot, err = a.mdStore.GetUnitOfTime(msg.UUID); uot == 0 && err == nil {
		if len(msg.Readings) > 0 {
			uot = common.GuessTimeUnit(msg.Readings[0].GetTime())
		}
	} else if err != nil {
		return err
	}
	for _, rdg := range msg.Readings {
		rdg.SetUOT(uot)
	}

	if uom, err = a.mdStore.GetUnitOfMeasure(msg.UUID); uom == "" && err == nil {
		if msg.Properties == nil {
			msg.Properties = &common.SmapProperties{StreamType: common.NUMERIC_STREAM}
		}
		msg.Properties.UnitOfMeasure = "n/a"
		err = a.mdStore.SaveTags(msg)
		if err != nil {
			return err
		}
	} else if err != nil {
		return err
	}

	//save timeseries data
	a.metrics["adds"].Mark(1)
	a.tsStore.AddMessage(msg)
	a.broker.HandleMessage(msg)
	return err
}
Beispiel #3
0
func (req *ArchiveRequest) GetMetadata(msg *bw.SimpleMessage) *common.SmapMessage {
	var ret = new(common.SmapMessage)
	req.Lock()
	if req.UUID != "" && req.uuidActual == "" {
		req.uuidActual = common.UUID(req.UUID)
	}
	req.Unlock()
	ret.UUID = req.uuidActual
	ret.Path = req.URI + "/" + req.Value
	ret.Metadata = make(common.Dict)
	ret.Properties = new(common.SmapProperties)

	for _, po := range msg.POs {
		var md map[string]interface{}
		if po.IsTypeDF(bw.PODFMsgPack) {
			err := po.(bw.MsgPackPayloadObject).ValueInto(&md)
			if err != nil {
				log.Error(errors.Wrap(err, "Could not unmarshal msgpack metadata"))
				return nil
			}
		} else if po.IsTypeDF(bw.PODFSMetadata) {
			md = make(map[string]interface{})
			tuple := po.(bw.MetadataPayloadObject).Value()
			md[getMetadataKey(msg.URI)] = tuple.Value
		}
		for k, v := range md {
			val := fmt.Sprintf("%s", v)
			if k == "UnitofTime" {
				ret.Properties.UnitOfTime, _ = common.ParseUOT(val)
			} else if k == "UnitofMeasure" {
				ret.Properties.UnitOfMeasure = val
			}
			ret.Metadata[k] = val
		}
	}
	return ret
}
Beispiel #4
0
// First, we check that all the fields are valid and the necessary ones are populated.
// This also involves filling in the optional ones with sane values.
// Then we build a chain on the URI to the VK -- if this fails, then we stop
// Then we build the operator chains for the expressions required
// Then we subscribe to the URI indicated.
func (bwh *BOSSWaveHandler) ParseArchiveRequest(request *ArchiveRequest) (*URIArchiver, error) {
	if request.FromVK == "" {
		return nil, errors.New("VK was empty in ArchiveRequest")
	}
	request.value = ob.Parse(request.Value)

	if request.UUID == "" {
		request.UUID = uuid.NewV3(NAMESPACE_UUID, request.URI+string(request.PO)+request.Value).String()
	} else {
		request.uuid = ob.Parse(request.UUID)
	}

	if request.Time != "" {
		request.time = ob.Parse(request.Time)
	}

	if request.MetadataExpr != "" {
		request.metadataExpr = ob.Parse(request.MetadataExpr)
	}
	if request.InheritMetadata {
		md, _, err := bwh.bw.GetMetadata(request.URI)
		if err != nil {
			return nil, err
		}
		var ret = new(common.SmapMessage)
		request.Lock()
		if request.UUID != "" && request.uuidActual == "" {
			request.uuidActual = common.UUID(request.UUID)
		}
		request.Unlock()
		ret.UUID = request.uuidActual
		ret.Path = request.URI + "/" + request.Value
		ret.Metadata = make(common.Dict)
		ret.Properties = new(common.SmapProperties)
		for k, v := range md {
			val := fmt.Sprintf("%s", v.Value)
			if k == "UnitofTime" {
				ret.Properties.UnitOfTime, _ = common.ParseUOT(val)
			} else if k == "UnitofMeasure" {
				ret.Properties.UnitOfMeasure = val
			}
			ret.Metadata[k] = val
		}
		if err = bwh.a.AddData(ret); err != nil {
			log.Error(errors.Wrap(err, "Could not add data"))
		}
	}

	var metadataChan = make(chan *bw.SimpleMessage)
	if len(request.MetadataURIs) > 0 {
		for _, metadataURI := range request.MetadataURIs {
			sub1, err := bwh.bw.Subscribe(&bw.SubscribeParams{
				URI: strings.TrimSuffix(metadataURI, "/") + "/!meta/+",
			})
			if err != nil {
				return nil, err
			}
			go func() {
				for msg := range sub1 {
					metadataChan <- msg
				}
			}()

			q1, err := bwh.bw.Query(&bw.QueryParams{
				URI: strings.TrimSuffix(metadataURI, "/") + "/!meta/+",
			})
			if err != nil {
				return nil, err
			}
			go func() {
				for msg := range q1 {
					metadataChan <- msg
				}
			}()
		}
	}
	//TODO: subscribe then query MetadataBlock

	log.Debugf("Subscribing for Archival on %s", request.URI)
	sub, err := bwh.bw.Subscribe(&bw.SubscribeParams{
		URI: request.URI,
	})
	if err != nil {
		return nil, errors.Wrap(err, "Could not subscribe")
	}
	log.Debugf("Got archive request")
	request.Dump()

	archiver := &URIArchiver{sub, metadataChan, request}
	go archiver.Listen(bwh.a)

	return archiver, nil
}