Notes for Sprint-2011.11-Block.2 Roger - Misc questions - Should we define the DataONEException type in the D1 schema? We have the schema in the Exceptions page in the API docs so maybe there is a reason it is being kept out of the schema? Any estimates on how expensive it is to generate exceptions based on pyxb / jaxb? Perhaps keeping them separate provides a level of independence which may be desirable? We went that way to begin with because it was easy and quick. It seems to have served us well because we wish to manipulate the serialization of objects more flexible than JibX affords. - We have an inconsistency in how we name lists. We use both "List" as in NodeList and appending an "s" as in "Services". Should we settle on one? My preference is appending an "s". I think the root elemens have "List" attached to them while inner elements may be plural. I think the term list is really meant to apply to things that are only Lists while other elements that are a mix of simple and complex elements end up more like Hashes. - We seem to have some inconsistencies in when we use attributes and when we use subelements. For instance, in the NodeList, we have: mn_crud .. Is there any reason version is an attribute and name is an element? no, that was messed up. we need a uniform convention, but attributes are nice when you have a TOKEN that can be assigned to it or an enumeration. Strings should go to elements. I looked into when to use attributes and when to use subelements, and found this: http://www.ibm.com/developerworks/xml/library/x-tipsub.html Robert has a task: "add the HTTP_METHOD as attribute on the method element in nodeList". I'm wondering if we should do that. The reasoning is that we're getting into describing how to use the methods, and I don't think we should try to do that in the schema. Developers will have to refer to the API docs on how to use the methods. Methods are already distinguished by their names, so we won't have two methods with the same name but different verbs. - Removed documentation from schema: Name and version of a DataONE software stack component are equivalent to the statusresponselist.xsd name and version. (-rpw notes from meeting 9/25/2010, but Component Name and Version is different than Service API name and version!) A process should check MN_health.getStatus() periodically and update the version, availability and dateChecked for each API. May need to update method definitions at same time Though should some of this be left in? - Instead of having a list of service names with versions, should we have a parent service name with (potentially) multiple children each of which is a service version? That would restrict the usage of multiple services to a single service with multiple versions (as opposed to now where there would be multiple service names as well). Thinking about this- the node information can be rearranged a bit to something like: Network (1..n, replaces "environment", represents a functional group of CNs and MNs) networkid (1, identifier for the network) description (1, Further details describing the network) adminGroup (1, A group of users that has admin access control of the network) notifyGroup (1, A group of users that should be notified of changes to the network) Node (1..n, A node describes a Member or Coordinating Node) nodeid (1, unique identifier for the node) name (1, Human readable name for the node) description (1, Description of the node, approximately 1 paragraph) location (1, physical location of the node - longitude, latitude in decimal degrees, WGS84) adminGroup (1, group of users who have administrative access to the node) notifyGroup (1, group of users that should be notified of changes or alerts related to the node) created (1, time that the node was first registered) modified (1, time when the registry information was last upated) objectFormatsSupported (list of object formats known to support) (-- needs wildcard support) Service (1..n, MN) version (1, schema version supported, MN) baseURL (1, MN) name (1, human readable name for service, e.g. "DataONE-0.6.1", MN) activeNetwork (1, id of network this interface is active for, MN) lastSynchronization (1, time stamp for when sycnrhonization was last performed, CN) isAlive (1, result of a ping() against the service baseURL, CN) lastChecked (1, last time service was examined, i.e. evaluatation of the methods, CN) synchronize (1, True if content available from this service should be synchronized with activeNetwork, MN) replicate (1, True if content should be replicated to other nodes on activeNetwork, MN) replicationTarget (1, True if this service is a replication target, MN, CN) method (1..n, MN) name (1, MN) isactive (1, set by CN) General requirement to support versioning on groups of methods, such as the APIs currently described. Node tiers --------------- Tier 1: Public read, no Authn/Authz - logging operations may need to refer to individuals identified by authentication - but does offer lowest entry to infrastructure - can only request that other nodes report on same level of detail that this node supports - must support replication policy information in system metadata (if content is to be replicated) - methods: get, listObjects, getSystemMetadata, describe, getChecksum, ping, getCapabilities, [ log ?] Tier 2: Read/Resolve with Authn/Authz Tier 3: Write (create, update, delete), possibly limited support for data types Tier 4: Limited Replication target (specified data types) Tier 5: Replication target, any data types Logging requires broader discussion due to privacy concerns. The "aggregateLogs" functionality should be indicated at the Node level as it applies to all operations. Core: Functionality common to all nodes, including optional methods Old API: MN_health, MN_crud New API: MN_core Methods: ping, getCapabilities, getStatus, [getObjectStatistics], [getOperationStatistics], [getLogRecords] Tier 1: Public read, no Authn/Authz Old APIs: MN_crud, MN_replication, MN_health New APIs: MN_core, MN_read Methods: MN_core: ping, getCapabilities, getStatus, [getObjectStatistics], [getOperationStatistics], [getLogRecords] MN_read: get, getSystemMetadata, listObjects, describe, getChecksum, synchronizationFailed Tier 2: Read/Resolve with Authn/Authz Old API: MN_authorization, MN_authentication New API: MN_auth Methods: MN_read + login(*), logout(*), isAuthorized(*), setAccess(*) Tier 3: Write (create, update, delete), possibly limited support for data types Old API: MN_crud New API: MN_storage Methods: MN_auth + create, update, delete, - Need to expose a list of supported ObjectFormats supported by a MN (support for writing) - Support wild cards - Also limiting attributes? e.g. size constraints by type? - part of the authorization spec? Tier 4: Limited Replication target (specified data types) Old API: MN_replication New API: MN_replication Methods: MN_storage + replicate Tier 5: Replication target, any data types Old API: New API: Methods: MN_replication (no additional methods) ~~ - How about the include a location for an automatically generated identifier in the DataONEException so that the exception can be matched up with corresponding entries in the log? Seems unnecessary. Use time stamps. - There is a bug in the repository browser. http://repository.dataone.org When clicking "view history", it shows the index.php file instead of running it. Yep. Use the redmine browser instead. ~~ @@@@@@@@@@@@@@ Migration strategy discussion We need to find out how to best support migration to newer versions of the DataONE APIs as they are introduced. At any given time, there will be MNs and clients supporting different versions of the DataONE APIs. When DataONE releases a new API, adoption will happen gradually (maybe like the technology adoption bell curve). The spec should make it as easy as possible to gradually implement support for new APIs in MNs and clients while the versions of calls remain unambiguous. The spec should also place as few restrictions as possible on how support for APIs must be implemented. For instance, one MN may want to support several versions of one call with the same call while another MN may want to use multiple calls and both should be allowed. ~~ Q: Multiple versions of methods is currently supported by allowing multiple APIs, each with a set of methods in the NodeList. Is this the best way? After mulling over it a bit more, it seems that just using a different baseURL for different service versions is the simplest way to go. ~~ Q: What kind of granularity in version differences do we want to support and how do we support it? For instance, should an update of a method require a new version of the API the method is in. Yes, if the method signature changes. ~~ Q: How do we handle cross dependencies between APIs? Version the service, not the individual APIs ~~ Q: Which enumerations should be in the schema? Should API and Method names be enumerated. If so, should they be generated directly from the MethodCrossReference.xls spreadsheet. As few as possible. They could be generated from the spreadsheet, but there's so few it doesn't seem woth the hassle really. ~~ Q: Is it appropriate to have API and Method versions be enumerations? Advantage: We can verify that the stated version of an API or Method is one that exists. Disadvantage: It adds an enumeration to the schema. See "Enumerations in the DataONE schema" below. Nope. IMO we should version the service. ~~ Enumerations in the DataONE schema: The issue with enumerations in the schema is that when an enumeration is expanded, the following chain of updates is triggered: The schema namespace -> autogenerated serialization code (PyXB and JAXB) -> DataONE libraries -> CNs, MNs and Clients. If this forces MNs and Clients to update any of their code, it is desirable to have the schema be as stable as possible, which means including as few enumerations as possible. But I think that the most important part of the migration strategy will be to support multiple schemas, so that updating the schema does not require any code that is already implemented and running to change. That way, only new code will be using new schemas and will get access to the additional functionality in the new schema. In that scenario, updating the schema does not carry a "penalty" in dependencies that must be updated and so we are free to set up as many enumerations as we like in the schema. That is what we do. A schema version is released, then the cascade of libraries and tools is similarly released. A change in the schema or any dependencies cascades a new release of the libs etc. ~~ - http://stackoverflow.com/questions/3319707/xml-schema-compatibility-strategy ~~ CN Object Format Service ---------------------------------------- CN service will implement: listObjectFormats() GET /formats getFormat() GET /formats/{fmtid} updateFormatList() POST /formats getSerializedFormatIdentifier() if (id exists) { // Generate a new id // update(formatList, id, oldId) // setAccess(adminGroup) } else { // Generate a new id // create(formatList, id) // setAccess(adminGroup) } createFormat(AuthToken, ObjectFormat) PUT /formats/{fmtid} getSerializedFormatIdentifier() if (id exists) { // *get formatlist from metacat // *add new format to formatlist // Generate a new id // serialize formatlist with new id // update(formatList, id, oldId) // setAccess(adminGroup) // record newid in CN config properties } else { // Generate a new id // create formatlist object // add new format to formatlist // serialize formatlist // create(formatList, id) // setAccess(adminGroup) // record newid in CN config properties } LDAP Group: cn=dataone-cn-admins,o=DataONE,dc=ecoinformatics,dc=org MemberNode Object Format Service: ------------------------------------------------------- new ObjectFormatService() ObjectFormatList fmtlist = CN.listFormats() (from d1_lib_client) if (fail) read from local cache throughout MN code needing to compare object formats: ObjectFormat ObjectFormatService.getFormat() getNodeType() // are we on a MN or CN? try fmtlist.getFormat() catch fail if nodeType == MN { call CN.listFormats *cache copy of fmtlist (see lines 249-253 above) try fmtlist.getFormat() } catch fail -- throw failure