gs1 / EPCIS

Draft files being shared for EPCIS 2.0 development
Other
22 stars 7 forks source link

Source vs Destination class #230

Closed VladimirAlexiev closed 3 years ago

VladimirAlexiev commented 3 years ago

The EPCIS.ttl ontology defines classes Source vs Destination.

However, from https://ns.mh1.eu/epcis/ and examples (eg WithDigitalLinkID/Example_9.6.2-ObjectEventWithDigitalLink.ttl) it becomes clear these have the same structure:

<event> epcis:sourceList           [ epcis:source  <urn:epc:id:sgln:4012345.00001.0> ;
                                     epcis:type    <urn:epcglobal:cbv:sdt:possessing_party>
                                   ] .
        epcis:destinationList      [ epcis:destination  <urn:epc:id:sgln:0614141.00001.0> ;
                                     epcis:type         <urn:epcglobal:cbv:sdt:owning_party>
                                   ] ;

where type is a cbv:SDT.

Questions @mgh128 :

1) Can the source/destination be pgln or are they always sgln? 2) Is it allowed to use mixed source & destination types? The example shows so, but the class comment says "Within a specified type of transfer, the business transfer is from the Source to the Destination." 3) With what type of Events, BizSteps, and Dispositions can this be used?

Recommendations:

10) Instead of classes Source, Destination use a single class, eg SourceOrDestination (not BizLocationWithRole because that could be Location OR Organization). 11) Instead of two props source, destination that do the same thing (and are exclusive), use a single prop sourceOrDestination (because sourceList, destinationList already take care of the distinction) 12) Optionally, could map JSONLD type to RDF prop epcis:role using a nested context: such prop can use a defined range cbv:SDT instead of having to use a union (#222) 13) Allow an optional id attribute to specify the SourceOrDestination URI (which currently is always a blank node)

All this will allow reuse, eg

<event> epcis:sourceList      <ni: (of urn:epc:id:sgln:4012345.00001.0 and 'possessing_party')> ;
        epcis:destinationList <ni: (of urn:epc:id:sgln:0614141.00001.0 and 'location')>.

<ni: (of urn:epc:id:sgln:4012345.00001.0 and possessing_party)> a epcis:SourceOrDestination;
  epcis:sourceOrDestination <urn:epc:id:sgln:4012345.00001.0>;
  epcis:role cbv:SDT-possessing_party.

<ni: (of urn:epc:id:sgln:0614141.00001.0 and location)> a epcis:SourceOrDestination;
  epcis:sourceOrDestination <urn:epc:id:sgln:0614141.00001.0>;
  epcis:role cbv:SDT-location.
mgh128 commented 3 years ago

A1) source/destination can (ideally should) be a pgln when the source/destination type is urn:epcglobal:cbv:sdt:possessing_party or urn:epcglobal:cbv:sdt:owning_party (or Web URI equivalents) but shall only be an sgln (or non-GS1 Web URI) when the source/destination type is urn:epcglobal:cbv:sdt: (or Web URI equivalent).

A2) It is possible for each shipping / receiving event to declare multiple sources (each qualified by a type) and multiple destinations (each qualified by a type). For example, a shipping event might indicate a destination location, a destination possessing party and a destination owning party, which might be three distinct values. This does not contradict the statement that the flow is from the source (typically the party generated the 'shipping' event) to the destination (typically the party generating the 'receiving' event) - and the type qualifiers are used to correlate each of these transfers of location, possession and ownership, where asserted.

A3) source/destination are typically used with bizStep values of shipping, receiving, possibly also departing, arriving , accepting. Most often used in ObjectEvent but could be used in AggregationEvent (which can be used to report the observation of a parent/child aggregation when action='OBSERVE') and I'm not aware of a validation restriction that prevents their use in any event type. A typical disposition value would be in_transit but other values might be appropriate.

Your recommendations might have worked if this was a green field exercise but it isn't and I suspect that it will be quite disruptive to do a major restructuring of how source / destination are handled. It's probably not even something where we can decide that the RDF triples can be radically different from the XML/JSON structures.

Furthermore, we can't just write or if the GLN extension itself [ AI (254) ] is not literally '0-possessing_party' or '0-owning_party' , which seems extremely unlikely anyway.

pgln corresponds to AI (417) and does not support the GLN extension (254), so there is no option to even do this when pgln is used correctly for possessing_party or owning_party .

VladimirAlexiev commented 3 years ago

Can I write <urn:epc:id:sgln:0614141.00001.0#owning_party> (hash instead of dash)?

mgh128 commented 3 years ago

The GS1 Tag Data Standard makes no mention of fragments or anchors.

The ABNF grammar in section 6.3.3 Global Location Number With or Without Extension (SGLN) of TDS does not provide a way for the fragment to be disentangled from the final GS3A3Component , though the definition of GS3A3Component at lines 728-730 does not include a literal octothorpe without percent-encoding as %23.

Until TDS formally mentions fragment identifiers for EPC URNs, I don't think it's a good idea to propose this use in EPCIS/CBV.

You've had a URN resolver all this time and not told anyone? ;-)

VladimirAlexiev commented 3 years ago

On the web, anyone is free to mint a URI (and anyone is free to emit any triples they like). What's the trouble if those URIs doesn't match the GS1 standards you cite?

I think we should recommend (but not require) that people put some id (rather than using blank node), and the example URIs I gave are viable. This will allow sharing of epcis:BizLocationRole nodes and is not disruptive.

VladimirAlexiev commented 3 years ago

PersistentDisposition-example-improved shows this (implemented for both BizTransactionDocument and BizLocationRole). All the nodes on the bottom are shared between the two events. Without id, we'd have a bunch of unshared blank nodes.

image

mgh128 commented 3 years ago

As explained in https://github.com/gs1/EPCIS/issues/252#issuecomment-819915384 , <urn:epc:id:sgln:0614141.00001.0#owning_party> or <urn:epc:id:sgln:0614141.00001.0-owning_party> is problematic for numerous reasons.

VladimirAlexiev commented 3 years ago

@mgh128 Quoting from the spec: "Source/Destination ID: An example is an identifier that denotes “Acme 1005 Corporation (an owning party)": I read this to mean an identifier for the node with two fields <bizLocation,type>. Which could be that identifier, and what it could look like?

If you dislike appending to a URN, let's use a UUID.

@mgh128 @RalphTro @CraigRe Please comment on items 10-13 from the very first issue comment. Thanks!

mgh128 commented 3 years ago

No. Not a UUID. Nor a URI with some appended suffix to indicate whether it's an owning party or possessing party.

If anything, the current definition is clumsy and needs to be improved. It is already quite clear from the examples for source and destination that these should be handled via two attributes, id pointing to the SGLN / PGLN URI, type expressing the role.

UUID is completely unhelpful here because it does not identify the organisation or location. If the identifier is an SGLN / PGLN URI without some weird suffix, it's then possible to use a resolver for GS1 Digital Link to lookup that value and iteratively find a URL of the EPCIS repository of the destination party.

It's already too late to handle this as three distinct source properties and three distinct destination properties.

VladimirAlexiev commented 3 years ago

@mgh128 you don't see the extra intermediate node that I see. I'm not asking to replace source/destination with UUID, I'm asking for the option to specify an id field (UUID, URL, or whatever) to allow sharing of those extra nodes.

Currently the JSON schema allows only this

"sourceList": [
  {"type":"urn:epcglobal:cbv:sdt:possessing_party","source":"urn:epc:id:sgln:4012345.00001.0"}],
"destinationList": [
  {"type":"urn:epcglobal:cbv:sdt:owning_party","destination":"urn:epc:id:sgln:0614141.00001.0"}],

Which results in blank nodes:

<event> epcis:sourceList           [ epcis:source  <urn:epc:id:sgln:4012345.00001.0> ;
                                     epcis:type    <urn:epcglobal:cbv:sdt:possessing_party>
                                   ] .
        epcis:destinationList      [ epcis:destination  <urn:epc:id:sgln:0614141.00001.0> ;
                                     epcis:type         <urn:epcglobal:cbv:sdt:owning_party>
                                   ] ;

I'm asking to allow this:

"sourceList": [
  {"id":"urn:uuid:blah-blah",
   "type":"urn:epcglobal:cbv:sdt:possessing_party","source":"urn:epc:id:sgln:4012345.00001.0"}],
"destinationList": [
  {"id":"urn:uuid:foo-bar",
   "type":"urn:epcglobal:cbv:sdt:owning_party","destination":"urn:epc:id:sgln:0614141.00001.0"}],

Assuming we have this in the context:

"id":"@id", // have it
"source": {"@id":"epcis:bizLocation", "@type":"@id"},
"destination": {"@id":"epcis:bizLocation", "@type":"@id"},
"sourceList": {"type":"@id",
   // nested context, allows the prop to have precise domain & range
  "@context": {"type":{"@id":"epcis:bizLocationRole", "@type":"@id"}},
"destinationList": {"type":"@id",
  // nested context, allows the prop to have precise domain & range
  "@context": {"type":{"@id":"epcis:bizLocationRole", "@type":"@id"}}, 

And this in the ontology:

epcis:BizLocation a rdfs:Class, owl:Class; 
  rdfs:comment "A business location identified by PGLN (Organization) or SGLN (Place)".
epcis:BizLocationWithRole a rdfs:Class, owl:Class; 
  rdfs:comment "A business location together with role (eg owning party, possessing party or location), used as source or destination".
epcis:bizLocationRole a owl:ObjectProperty;
 rdfs:domain epcis:BizLocationWithRole; rdfs:range cbv:SDT.
epcis:bizLocation a owl:ObjectProperty;
  rdfs:domainIncludes epcis:EPCISEvent, epcis:BizLocationWithRole;
  rdfs:range epcis:BizLocation;
  rdfs:comment "Business location of the EPCISEvent, or the 'ultimate' business location of BizLocationWithRole".
epcis:sourceList a owl:ObjectProperty;
  rdfs:domain epcis:EPCISEvent;
  rdfs:range epcis:BizLocationWithRole.
epcis:destinationList a owl:ObjectProperty;
  rdfs:domain epcis:EPCISEvent;
  rdfs:range epcis:BizLocationWithRole.

This enables the intermediate node to be well-defined (with URI and type), and to be shared between events:

<event> epcis:sourceList      <urn:uuid:blah-blah> ;
        epcis:destinationList <urn:uuid:foo-bar>.

<urn:uuid:blah-blah> a epcis:BizLocationWithRole;
  epcis:bizLocation <urn:epc:id:sgln:4012345.00001.0>;
  epcis:bizLocationRole cbv:SDT-possessing_party.

<urn:uuid:foo-bar> a epcis:BizLocationWithRole;
  epcis:bizLocation <urn:epc:id:sgln:0614141.00001.0>;
  epcis:bizLocationRole cbv:SDT-owning_party.
VladimirAlexiev commented 3 years ago

@mgh128 @RalphTro @CraigRe Please vote on items 10-13 from the very first issue comment, one by one. Thanks!

mgh128 commented 3 years ago

@VladimirAlexiev Thanks for the clarification that you want to avoid a blank node. I'm still not completely convinced of the need. Here is an analogy:

A local business is identified by a URI Sometimes the local business is open for business. Sometimes the local business is closed for business.

How many URIs does that local business really need to identify itself? 1 or 3 ?

In a supply chain, there are situations where the same organisation might take possession for some products / in some contractual arrangements but takes ownership for other products / in other contractual arrangements. Does that organisation need 1 identifier or really need 3 ?

The only reason you're seeing that blank node at all is because we failed to split source, destination into separate subproperties for destination_location, destination_possessing_party, destination_owning_party etc. in a previous version of the standard.

mgh128 commented 3 years ago

10) No - because in 2/3 of the options for type, source and destination do not point to a location or business location ; they point to an organisation, ideally identified by a PGLN. 11) No - because in 2/3 of the options for type, source and destination do not point to a location or business location ; they point to an organisation, ideally identified by a PGLN. 12) No - because in 2/3 of the options for type, source and destination do not point to a location or business location ; they point to an organisation, ideally identified by a PGLN. 13) please provide a really strong justification for this; the blank node you see is only because we failed to split source, destination into separate subproperties for destination_location, destination_possessing_party, destination_owning_party etc. in a previous version of the standard.

VladimirAlexiev commented 3 years ago

That intermediate node is a Role. Roles occur very often in data models (especially RDF models, which have only binary relations). They are not insignificant.

  1. The only reason you're seeing that blank node at all is because we failed to ... subproperties

But the fact is that your model includes a Role node. The best practice is for every node to have a defined class (and URI).

With hindsight, perhaps a more elegant approach would have been to define 3 distinct subproperties of source and 3 subproperties of destination, so that we could have written that: epcis:destinationLocation rdfs:range gs1:Place . epcis:destinationPossessingParty rdfs:range gs1:Organization . epcis:destinationOwningParty rdfs:range gs1:Organization .

Yes, that's a great way to express the dependency between type and target class. But it's not absolutely necessary since we'll have a common superclass (epcis:BizLocation), and we can express the dependency with SHACL.

Subproperties have a defect: cbv:SDT now has 3 values, but tomorrow it MIGHT have 4 values and you don't want to have to change the EPCIS ontology to introduce another subproperty.

Your "open/close business" example is not good because that's a State not a Role. A better example would be from the domain of customs:

Now you see how a Role gains in importance. (I could give many more examples, eg see W3 Org ontology and the Membership class between Person and Organization: https://www.w3.org/TR/vocab-org/#reporting_structure)

the same organisation might take possession for some products / in some contractual arrangements but takes ownership for other products / in other contractual arrangement

Well, of course. It acts in different Roles in these arrangements.

Does that organisation need 1 identifier or really need 3 ?

Just 1. I'm not introducing new organization IDs. All I'm asking is to allow the Role node to have an id, so they can be well-defined and shared between events.


Answering comments from #252 bullet 8:

"we can't say that every value of source/destination is a location or business location because ... 'possessing_party' or 'owning_party' is an organisation, not a location" And above: "in 2/3 of the options for type, source and destination do not point to a location or business location; they point to an organisation"

  • I am confused: I always assumed that BusinessLocationID is an Organization (PGLN) or a Place (SGLN), isn't that right?
  • How do you call the range of bizLocation and readPoint?
  • So every value of source/destination is a BusinessLocationID.

I already gave up on the idea of appending to urn:epc:id:sgln, but I want to explain my reasoning why I think URNs are not sacrosanct and the universe won't collapse if I mint my own URN based on a GS1 URN.

urn:epc:id:sgln:4012345.00001.0-possessing_party: "0-possessing_party" is a valid value for AI (254), so we can't use this syntax approach to add extra meaning to an existing SGLN EPC URN, firstly because we're trampling on an existing valid value,

  • That's only if someone attempts to validate or interpret it against the urn:epc:id:sgln spec. My view is that people should do that based on WHERE they find such URI, not what the URI looks LIKE.
  • Similarly, people should not taste something they find in a random place. They should only taste things they know where they came from thirdly because it violates the principle of non-significance of identification keys.
  • Quite the opposite: I propose to make a URI by appending to something, and you argue that something is sacrosanct and I dare not touch it.

I can't see an easy way to fix the current data model for source and destination without breaking things in the current XML binding and draft JSON binding. I can't think of a magic trick we can do in the JSON-LD context resource to disentangle this.

The way is easy and I showed it above (comment https://github.com/gs1/EPCIS/issues/230#issuecomment-821001303, search "the context").

I'm not aware of any way to express conditional mappings that would be needed to reflect the dependency on the value of type within source or destination but if you can, please suggest it.

Nested contexts, again see above.

VladimirAlexiev commented 3 years ago

We reworded 10-13 to use more consensus names.

Agreement:

mgh128 commented 3 years ago

@CraigRe - need to check all v1.2 examples for party that currently use SGLN, consider whether to use PGLN in EPCIS v2.0

VladimirAlexiev commented 3 years ago

@mgh128 We merged the two classes to epcis:SourceOrDestination. However, we still have two props epcis:source and epcis:destination, which makes no sense: if I want to reuse a epcis:SourceOrDestination in many events, I'm forced to specify both epcis:source and epcis:destination, being identical!!

Please explain your objection to item 11:

No - because in 2/3 of the options for type, source and destination do not point to a location or business location ; they point to an organisation, ideally identified by a PGLN.

I'm arguing to use a merged prop epcis:sourceOrDestination, not to change the range of epcis:source / epcis:destination.

Your proposal (prefixes omitted for brevity):

SourceOrDestination
  sourceOrDestinationType: cbv:SDT
  source: gs1:Place, gs1:Organization
  destination: gs1:Place, gs1:Organization  # two IDENTICAL props: source SAME as destination???

My proposal:

SourceOrDestination
  sourceOrDestinationType: cbv:SDT
  sourceOrDestination: gs1:Place, gs1:Organization # single prop

If you agree:

VladimirAlexiev commented 3 years ago

@mgh128 do you agree? I can't reopen the issue