Can a Orion Context Broker entity have two attributes with the same name but different type? - fiware-orion

Can a Orion Context Broker entity have two attributes with the same name but different type?
If yes, is it controlled by Orion? Is an error returned when such an entity is created?
If no, what happens when a convenience operation tries to get the value of one of the 2 attributes (AFAIK, the attribute type is not passed in the operation).

From Orion 0.17.0 on, type is no longer used to identify an attribute. Thus, attributes are identified by name plus (optionally) metadata ID. I will assume version >=0.17.0 in the rest of this answer.
Orion doesn't control violation of that rule when processing operations to create entities or append attribute on existing entities. In those cases, only one instance of the attributes with the same identification is taken an stored in the DB, the others are ignored. It is not recommended at all that a client do such kind of operations (in the future, Orion may check that condition and return an error to the client).
Taking account the above paragraph and regarding what happens when a convenience operation tries to get the value of one of the 2 attributes (AFAIK, the attribute type is not passed in the operation)? note that situation cannot happend. I mean, at Orion DB will never store two attributes with the same identification associated to the same entity.
Some additional comment regarding metadata ID: I don't recommend the use of metadata ID as any potential ID can be included in the name and you will get your client much simpler, e.g. you don't need and attribute with name=temperature and id=outside if you use name=temperature::outside or any other namespacing technique.

Related

How to define the entityId in Orion

I have to use Orion (NGSI v2), and I have a question about the name of entityId of my context;
could I use a simple ID or URN (like NGSI-LD spec)?
What is the best practice?
Thanks a lot
From a NGSIv2 point of view, any entity ID that complies with the identifiers syntax restrictions is valid.
Having said this, in general the simpler entity ID, the better from an integration point of view. For instance, if you are persisting context data using Cygnus sink for PostgreSQL, note that PostGresSQL could use tables which name includes the entity ID (for instance, if the dm-by-entity-database-schema DM is used, see this reference).
Thus, better to use simple entity IDs than URN-like entity IDs, from my point of view.
I think it is better to use URIs for your entities, your path to Linked Data will be smoother. The problem with table names should be fixed by the data storage component for instance by calculating a hash of the URI and converting it to the proper alphabet supported by the database concerning table names ...

Multi Object Unbound Action for updating Contained Entities in OData

In OData, a contained entity does not have an entity set. All operations on it should be through the parent entity. And this is true for single-object APIs.
Can we have an unbound action to update multiple such contained entities by directly providing the ID with no parent in context? Would this be according to the Odata specs?
Thanks and Regards,
Jyothi
You could do it, but as an Unbound Function that is technically all it is, Unbound, there is nothing in the specification preventing you from doing it this way but it would not be constrained to a specific resource by route. That makes the Action unintuitive in terms of both discovery and expectations.
The OData way to do this would be to bind the operation to the Parent Entity. If the operation affects or retrieves data across multiple entities or you really want to avoid needing to resolve the Parent key, then it should still be bound to the Collection rather than being Unbound.
Reserve Unbound Actions for operations that are outside of the model, diagnostics or other esoteric implementations that otherwise don't have a single natural place in the OData Schema.
Having an Action That targets single or multiple Contained Entities without reference to the Parent is in the vicinity of being an Anti-Pattern, though I can not cite any sources that explicitly support this claim, the general reason for Contained Entities at all is because you can't directly reference the contained entity without the Parent Key, it was designed for scenarios where the Parent Key forms part of the Key for the contained item.
A classic example is Invoice and InvoiceLines. If your InvoiceLines Key is a simple Line Number and is only unique within the Invoice parent, so in the Database this might be a composite key using InvoiceId and LineNumber. In this case we can only expose this Entity as being Contained within a specific Invoice because there is no other way to uniquely reference a single InvoiceLine item.
If your Contained Entity has a unique Key AND you intend on performing operations directly against these Entities without reference to the Parent Entity then that Entity really should be exposed as a top-level collection of it's own.

FIWARE Orion: change entity type

In Orion, is it possible to change the type of an entity?
Related question, it is possible to change the type of an attribute?
Edit: Changing the type of an entity doesn't seem to be possible. So creating a new entity seems to be a solution. But how to preserve dateCreated and dateModified?
In Orion, is it possible to change the type of an entity
Not directly. Entity id and entity type are immutable. However, you can create a copy of the entity with the new type, then delete the old entity. That will have effectively the same effect.
Related question, it is possible to change the type of an attribute?
Yes, it is. When you update an attribute, not only the value but also the type (and metadata) can be changed.
EDIT: dateModified and dateCreation attributes and metadata are designed to be managed by Context Broker automatically. Clients cannot modify them, they are "read-only". The idea is that a given context consumer client (which, in principle, is independent of the context producer client creating/updating the entity) has a trustable timestamp that nobody could alter.
So, you have basically two alternatives:
Use your custom timestamp attributes and metadata. They can be "moved" to the new entity when you create it. However, CB will not maintain them automatically so your application would have to do it.
Use an out-of-API process, moving the entity at DB level. However, this can be complicated, as you need direct access to DB.
EDIT2: for the second case (DB based process) take into account the Orion DB model. In particular:
_id.type is for the entity type
creDate is for the entity creation date
modDate is for the entity modification date
attrs.A.creDate is for the attribute A creation date
attrs.A.modDate is for the attribute A modification date

Web services and partial entity updates

We are implementing CRUD interface to manage entities with SOAP messages. What are good practices to allow partial updating of the entity? Meaning the client could update just some attributes of the entity, without having to post the whole entity? Is there more general approach to this than distinct methods for each attribute update?
HTTP Patch can be used for partial updates, only sending the fields of the object you want to change. There's an interesting discussion about partial updates here.
I'd say it would be more important to make sure the partial update is idempotent, i.e. the same update fields in the request result in the same end state of the resource. So if you have internal logic that determines the state of a resource attribute based on the value of another resource attribute that is being updated that might be something to look into. e.g. if the resource as a whole has rules for when parts of it are updated but other parts are not specified (default values for some attributes?), that may cause different outcomes based on the current state of the resource.
If the resource as a whole is just a collection of unrelated attributes then partial updates make sense but if there are dependencies among some attributes and some get updated while others don't, then the end state of the resource has to be idempotent. e.g. does it make sense to update an address but not update the phone number? What happens to the phone number if it's a landline and the address gets updated? Is it set to null? and vice versa. So when doing partial updates it might be worth 'partitioning' the allowed partials based on the domain being updated.

New entity ID in domain event

I'm building an application with a domain model using CQRS and domain events concepts (but no event sourcing, just plain old SQL). There was no problem with events of SomethingChanged kind. Then I got stuck in implementing SomethingCreated events.
When I create some entity which is mapped to a table with identity primary key then I don't know the Id until the entity is persisted. Entity is persistence ignorant so when publishing an event from inside the entity, Id is just not known - it's magically set after calling context.SaveChanges() only. So how/where/when can I put the Id in the event data?
I was thinking of:
Including the reference to the entity in the event. That would work inside the domain but not necesarily in a distributed environment with multiple autonomous system communicating by events/messages.
Overriding SaveChanges() to somehow update events enqueued for publishing. But events are meant to be immutable, so this seems very dirty.
Getting rid of identity fields and using GUIDs generated in the entity constructor. This might be the easiest but could hit performance and make other things harder, like debugging or querying (where id = 'B85E62C3-DC56-40C0-852A-49F759AC68FB', no MIN, MAX etc.). That's what I see in many sample applications.
Hybrid approach - leave alone the identity and use it mainly for foreign keys and faster joins but use GUID as the unique identifier by which i pull the entities from the repository in the application.
Personally I like GUIDs for unique identifiers, especially in multi-user, distributed environments where numeric ids cause problems. As such, I never use database generated identity columns/properties and this problem goes away.
Short of that, since you are following CQRS, you undoubtedly have a CreateSomethingCommand and corresponding CreateSomethingCommandHandler that actually carries out the steps required to create the new instance and persist the new object using the repository (via context.SaveChanges). I will raise the SomethingCreated event here rather than in the domain object itself.
For one, this solves your problem because the command handler can wait for the database operation to complete, pull out the identity value, update the object then pass the identity in the event. But, more importantly, it also addresses the tricky question of exactly when is the object 'created'?
Raising a domain event in the constructor is bad practice as constructors should be lean and simply perform initialization. Plus, in your model, the object isn't really created until it has an ID assigned. This means there are additional initialization steps required after the constructor has executed. If you have more than one step, do you enforce the order of execution (another anti-pattern) or put a check in each to recognize when they are all done (ooh, smelly)? Hopefully you can see how this can quickly spiral out of hand.
So, my recommendation is to raise the event from the command handler. (NOTE: Even if you switch to GUID identifiers, I'd follow this approach because you should never raise events from constructors.)