private void EvaluateChannelMetadata(long messageId, ChannelMetadata channelMetadata) { var channelsToBeStopped = new List <ChannelMetadataRecord>(); var channelIndex = new List <int>(); for (int i = 0; i < channelMetadata.Channels.Count; i++) { var channel = channelMetadata.Channels[i]; var uri = new EtpUri(channel.ChannelUri); // Ensure that all parent UIDs are populated foreach (var objectId in uri.GetObjectIds()) { if (string.IsNullOrWhiteSpace(objectId.ObjectId)) { this.InvalidUri($"Channel {channel.ChannelName}({channel.ChannelId}) is missing the objectId of a parent.", messageId); channelsToBeStopped.Add(channel); channelIndex.Add(i); } } } // Notify producer to stop streaming the channels ChannelStreamingStop(channelsToBeStopped.Select(x => x.ChannelId).ToList()); // Remove the channels from the metadata channelIndex.Reverse(); channelIndex.ForEach(x => channelMetadata.Channels.RemoveAt(x)); }
/// <summary> /// Tries to replace the segment in the ETP URI of the same object type with the specified segment. /// </summary> /// <param name="uri">The URI to create a new URI from with the segment replaced.</param> /// <param name="segment">The segment to replace the current URI segment with.</param> /// <param name="success"><c>true</c> if successful; <c>false</c> otherwise.</param> /// <returns>The input URI with the segment replaced or the original URI if not successful.</returns> public static EtpUri TryReplaceObjectTypeSegment(this EtpUri uri, EtpUri.Segment segment, out bool success) { success = false; if (!uri.IsValid || string.IsNullOrEmpty(segment.ObjectType)) { return(uri); } var constructedUri = uri.GetUriFamily(); foreach (var s in uri.GetObjectIds()) { if (!string.IsNullOrEmpty(s.ObjectType) && segment.ObjectType.EqualsIgnoreCase(s.ObjectType)) { constructedUri = constructedUri.Append(segment.ObjectType, segment.ObjectId); success = true; } else { constructedUri = constructedUri.Append(s.ObjectType, s.ObjectId); } } if (success) { return(new EtpUri(constructedUri.ToString() + uri.Query)); } else { return(uri); } }
/// <summary> /// Tries to get the ETP URI prefix up to the specified object type. /// </summary> /// <param name="uri">The URI to create the prefix from.</param> /// <param name="objecType">The object type to end the prefix with.</param> /// <param name="success"><c>true</c> if successful; <c>false</c> otherwise.</param> /// <returns>The prefix of the input URI or the original URI without its query if not successful.</returns> public static EtpUri TryGetObjectTypePrefix(this EtpUri uri, string objecType, out bool success) { success = false; uri = new EtpUri(uri.GetLeftPart()); if (!uri.IsValid || string.IsNullOrEmpty(objecType)) { return(uri); } var constructedUri = uri.GetUriFamily(); foreach (var s in uri.GetObjectIds()) { if (!string.IsNullOrEmpty(s.ObjectType) && objecType.EqualsIgnoreCase(s.ObjectType)) { constructedUri = constructedUri.Append(s.ObjectType, s.ObjectId); success = true; break; } else { constructedUri = constructedUri.Append(s.ObjectType, s.ObjectId); } } if (success) { return(constructedUri); } else { return(uri); } }
/// <summary> /// If valid, returns the uri that matches the requested query hierarchy. /// </summary> /// <param name="uri">The uri.</param> /// <param name="query">The hierarchy query.</param> /// <returns></returns> public static EtpUri GetValidHierarchyUri(this EtpUri uri, EtpUri query) { var hierarchyUris = uri.GetRelatedHierarchyUris(); var queryObjectIds = query.GetObjectIds().ToList(); return(hierarchyUris.FirstOrDefault(x => { var uriObjectIds = x.GetObjectIds().ToList(); if (uriObjectIds.Count != queryObjectIds.Count) { return false; } for (var i = 0; i < uriObjectIds.Count; ++i) { if (!uriObjectIds[i].ObjectType.EqualsIgnoreCase(queryObjectIds[i].ObjectType) || !uriObjectIds[i].ObjectId.IsMatch(queryObjectIds[i].ObjectId)) { return false; } } return true; })); }
/// <summary> /// Gets the objects of the specified type. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="objectType">Type of the object.</param> /// <param name="uri">The URI.</param> /// <param name="optionsIn">The options in.</param> /// <returns></returns> protected virtual IEnumerable <T> GetObjects <T>(string objectType, EtpUri uri, params OptionsIn[] optionsIn) where T : IDataObject { var filters = new List <string>(); var values = new List <object>(); var count = 0; // Create dictionary with case-insensitive keys var objectIds = uri.GetObjectIds() .ToDictionary(x => x.ObjectType, x => x.ObjectId, StringComparer.InvariantCultureIgnoreCase); if (!string.IsNullOrWhiteSpace(uri.ObjectId)) { filters.Add("Uid = @" + (count++)); values.Add(uri.ObjectId); } if (objectIds.ContainsKey(ObjectTypes.Well) && !ObjectTypes.Well.EqualsIgnoreCase(objectType)) { filters.Add("UidWell = @" + (count++)); values.Add(objectIds[ObjectTypes.Well]); } if (objectIds.ContainsKey(ObjectTypes.Wellbore) && !ObjectTypes.Wellbore.EqualsIgnoreCase(objectType)) { filters.Add("UidWellbore = @" + count); values.Add(objectIds[ObjectTypes.Wellbore]); } var query = CreateWitsmlQuery(objectType); query = FormatWitsmlQuery(query, optionsIn); var result = query .Where(string.Join(" && ", filters), values.ToArray()) .GetEnumerator(); var dataObjects = new List <T>(); while (result.MoveNext()) { dataObjects.Add((T)result.Current); } return(dataObjects.OrderBy(x => x.Name)); }
private void SetFilterCriteria(string objectType, XDocument document, EtpUri uri) { var objectIds = uri.GetObjectIds() .ToDictionary(x => x.ObjectType, x => x.ObjectId, StringComparer.InvariantCultureIgnoreCase); if (!string.IsNullOrWhiteSpace(uri.ObjectId)) { _template.Set(document, "//@uid", uri.ObjectId); } if (objectIds.ContainsKey(ObjectTypes.Well) && !ObjectTypes.Well.EqualsIgnoreCase(objectType)) { _template.Set(document, "//@uidWell", objectIds[ObjectTypes.Well]); } if (objectIds.ContainsKey(ObjectTypes.Wellbore) && !ObjectTypes.Wellbore.EqualsIgnoreCase(objectType)) { _template.Set(document, "//@uidWellbore", objectIds[ObjectTypes.Wellbore]); } }
/// <summary> /// Tries to get the segment in the ETP URI corresponding to the specified object type. /// </summary> /// <param name="uri">The ETP URI to get the segment from.</param> /// <param name="objectType">The object type of the segment to get.</param> /// <param name="success"><c>true</c> if the object segment was found; <c>false</c> otherwise.</param> /// <returns>The found segment or default if not found.</returns> public static EtpUri.Segment TryGetObjectTypeSegment(this EtpUri uri, string objectType, out bool success) { success = false; if (!uri.IsValid || string.IsNullOrEmpty(objectType)) { return(default(EtpUri.Segment)); } foreach (var s in uri.GetObjectIds()) { if (!string.IsNullOrEmpty(s.ObjectType) && objectType.EqualsIgnoreCase(s.ObjectType)) { success = true; return(s); } } return(default(EtpUri.Segment)); }
/// <summary> /// Gets the uri /// </summary> /// <param name="uri"></param> /// <param name="other"></param> /// <returns></returns> public static EtpUri GetResolvedHierarchyUri(this EtpUri uri, EtpUri other) { var resolvedUri = new EtpUri(); if (other.IsRootUri) { return(uri); } if (!uri.IsRelatedTo(other)) { return(resolvedUri); } var uriHierarchy = uri.GetObjectIds().ToList(); var otherHierarchy = other.GetObjectIds().ToList(); resolvedUri = uri.GetUriFamily(); var otherHierarchyMap = otherHierarchy .ToLookup(x => x.ObjectType, x => x.ObjectId, StringComparer.InvariantCultureIgnoreCase) .ToDictionary(x => x.Key, x => x.First(), StringComparer.InvariantCultureIgnoreCase); uriHierarchy.ForEach(segment => { var objectType = segment.ObjectType; var objectId = segment.ObjectId; if (string.IsNullOrWhiteSpace(objectId)) { otherHierarchyMap.TryGetValue(objectType, out objectId); } resolvedUri.Append(objectType, objectId); }); return(resolvedUri); }
private bool IsValidUri(EtpUri uri) { if (!uri.IsValid) { return(false); } if (uri.IsRootUri || uri.IsBaseUri) { return(true); } var wellboreObjectTypes = new HashSet <string>(GetWellboreDataAdapters().Select(x => ObjectTypes.GetObjectType(x.DataObjectType)), StringComparer.InvariantCultureIgnoreCase); var wellObjectTypes = new HashSet <string>(GetWellDataAdapters().Select(x => ObjectTypes.GetObjectType(x.DataObjectType)).Except(wellboreObjectTypes), StringComparer.InvariantCultureIgnoreCase); var objectType = uri.ObjectType; var objectIds = uri.GetObjectIds().ToList(); var objectIdGroups = objectIds.GroupBy(x => x.ObjectType, StringComparer.InvariantCultureIgnoreCase); // check for repeating groups if (objectIdGroups.Any(x => x.Count() > 1)) { return(false); } if (wellObjectTypes.Contains(objectType)) { return(objectIds.Count >= 1 && ObjectTypes.Well.EqualsIgnoreCase(objectIds[0].ObjectType)); } if (wellboreObjectTypes.Contains(objectType)) { return(objectIds.Count >= 2 && ObjectTypes.Well.EqualsIgnoreCase(objectIds[0].ObjectType) && ObjectTypes.Wellbore.EqualsIgnoreCase(objectIds[1].ObjectType)); } return(objectIds.Count == 1 && ObjectTypes.Well.EqualsIgnoreCase(objectIds[0].ObjectType)); }
/// <summary> /// Gets the entity filter using the specified id field. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="uri">The URI.</param> /// <param name="idPropertyName">Name of the identifier property.</param> /// <returns>The entity filter with the specified id field</returns> public static FilterDefinition <T> GetEntityFilter <T>(EtpUri uri, string idPropertyName = "Uid") { var builder = Builders <T> .Filter; if (ObjectTypes.Uri.EqualsIgnoreCase(idPropertyName) || !uri.IsValid) { return(builder.EqIgnoreCase(idPropertyName, uri.Uri)); } // Uuid filter if (ObjectTypes.Uuid.Equals(idPropertyName)) { return(builder.EqIgnoreCase(idPropertyName, uri.ObjectId)); } // Create dictionary with case-insensitive keys var objectIds = uri.GetObjectIds() .ToDictionary(x => x.ObjectType, x => x.ObjectId, StringComparer.CurrentCultureIgnoreCase); // Uid filter var filters = new List <FilterDefinition <T> > { builder.EqIgnoreCase(idPropertyName, uri.ObjectId) }; if (!ObjectTypes.Well.EqualsIgnoreCase(uri.ObjectType) && objectIds.ContainsKey(ObjectTypes.Well)) { filters.Add(builder.EqIgnoreCase("UidWell", objectIds[ObjectTypes.Well])); } if (!ObjectTypes.Wellbore.EqualsIgnoreCase(uri.ObjectType) && objectIds.ContainsKey(ObjectTypes.Wellbore)) { filters.Add(builder.EqIgnoreCase("UidWellbore", objectIds[ObjectTypes.Wellbore])); } return(builder.And(filters.Where(f => f != null))); }
/// <summary> /// Gets whether an URI is relative to another URI. /// </summary> /// <param name="uri">The child URI (E.g. {eml://witsml20/Well(1234)/Wellbore(5678)/Trajectory(91011)}).</param> /// <param name="other">The parent URI (E.g. {eml://witsml20/Trajectory}).</param> /// <returns></returns> public static bool IsRelativeTo(this EtpUri uri, EtpUri other) { if (!uri.IsValid || !other.IsValid) { return(false); } if (other.IsRootUri) { return(true); } if (!uri.IsRelatedTo(other)) { return(false); } var uriHierarchy = uri.GetObjectIds().ToList(); var otherHierarchy = other.GetObjectIds().ToList(); var getObjectType = new Func <List <EtpUri.Segment>, int, EtpUri.Segment>((h, i) => { return(i >= 0 && i < h.Count ? h[i] : new EtpUri.Segment()); }); var isBaseUri = new Func <EtpUri.Segment, bool>((o) => { return(string.IsNullOrWhiteSpace(o.ObjectType) && string.IsNullOrWhiteSpace(o.ObjectId)); }); var uriIndex = uriHierarchy.Count - 1; var otherIndex = otherHierarchy.Count - 1; var uriTemp = getObjectType(uriHierarchy, uriIndex); var otherTemp = getObjectType(otherHierarchy, otherIndex); var valid = false; while (!string.IsNullOrWhiteSpace(uriTemp.ObjectType)) { if (uriTemp.ObjectType.EqualsIgnoreCase(otherTemp.ObjectType)) { valid = true; break; } uriTemp = getObjectType(uriHierarchy, --uriIndex); } if (isBaseUri(uriTemp) && isBaseUri(otherTemp)) { return(true); } if (!valid) { return(false); } while (!string.IsNullOrWhiteSpace(uriTemp.ObjectType) || !string.IsNullOrWhiteSpace(otherTemp.ObjectType)) { var objectTypeMatch = uriTemp.ObjectType.EqualsIgnoreCase(otherTemp.ObjectType); var objectIdMatch = objectTypeMatch && (uriTemp.ObjectId?.IsMatch(otherTemp.ObjectId) ?? string.IsNullOrWhiteSpace(otherTemp.ObjectId)); if (!objectIdMatch) { valid = false; break; } uriTemp = getObjectType(uriHierarchy, --uriIndex); otherTemp = getObjectType(otherHierarchy, --otherIndex); } return(valid || isBaseUri(uriTemp) && isBaseUri(otherTemp)); }
/// <summary> /// Gets the list of potential uris that represent the same object hierarchy. Assumes URI is well formed. /// </summary> /// <param name="uri"></param> /// <returns></returns> public static List <EtpUri> GetRelatedHierarchyUris(this EtpUri uri) { // By default WITSML 2.x objects return top-level URIs in their channel metadata // Ensure that it is first in the list to speed up any related processing that is // looking for those type of URIs... // WITSML 1.x object require the full hierarchy regardless. var uris = new List <EtpUri>() { uri.ToTopLevelUri() }; if (!uri.IsValid) { return(uris); } var uriHierarchy = uri.GetObjectIds().ToList(); if (!uriHierarchy.Any()) { return(uris); } var uriHierarchyMap = uriHierarchy .ToLookup(x => x.ObjectType, x => x.ObjectId, StringComparer.InvariantCultureIgnoreCase) .ToDictionary(x => x.Key, x => x.First(), StringComparer.InvariantCultureIgnoreCase); var isWitsml20 = EtpUris.Witsml200.IsRelatedTo(uri); if (!isWitsml20) { return(uris); } if (ObjectTypes.Well.EqualsIgnoreCase(uri.ObjectType)) { return(uris); } var rootUri = EtpUris.Witsml200; string wellObjectId; uriHierarchyMap.TryGetValue(ObjectTypes.Well, out wellObjectId); string wellboreObjectId; uriHierarchyMap.TryGetValue(ObjectTypes.Wellbore, out wellboreObjectId); string logObjectId; uriHierarchyMap.TryGetValue(ObjectTypes.Log, out logObjectId); string channelSetObjectId; uriHierarchyMap.TryGetValue(ObjectTypes.ChannelSet, out channelSetObjectId); if (ObjectTypes.Wellbore.EqualsIgnoreCase(uri.ObjectType)) { var hierarchyUri = rootUri .Append(ObjectTypes.Well, wellObjectId) .Append(ObjectTypes.Wellbore, uri.ObjectId); uris.Add(hierarchyUri); } else { EtpUri hierarchyUri; if (ObjectTypes.Channel.EqualsIgnoreCase(uri.ObjectType)) { hierarchyUri = rootUri .Append(ObjectTypes.ChannelSet, channelSetObjectId) .Append(ObjectTypes.Channel, uri.ObjectId); uris.Add(hierarchyUri); hierarchyUri = rootUri .Append(ObjectTypes.Log, logObjectId) .Append(ObjectTypes.ChannelSet, channelSetObjectId) .Append(ObjectTypes.Channel, uri.ObjectId); uris.Add(hierarchyUri); hierarchyUri = rootUri .Append(ObjectTypes.Wellbore, wellboreObjectId) .Append(ObjectTypes.Log, logObjectId) .Append(ObjectTypes.ChannelSet, channelSetObjectId) .Append(ObjectTypes.Channel, uri.ObjectId); uris.Add(hierarchyUri); hierarchyUri = rootUri .Append(ObjectTypes.Well, wellObjectId) .Append(ObjectTypes.Wellbore, wellboreObjectId) .Append(ObjectTypes.Log, logObjectId) .Append(ObjectTypes.ChannelSet, channelSetObjectId) .Append(ObjectTypes.Channel, uri.ObjectId); uris.Add(hierarchyUri); } else if (ObjectTypes.ChannelSet.EqualsIgnoreCase(uri.ObjectType)) { hierarchyUri = rootUri .Append(ObjectTypes.Log, logObjectId) .Append(ObjectTypes.ChannelSet, uri.ObjectId); uris.Add(hierarchyUri); hierarchyUri = rootUri .Append(ObjectTypes.Wellbore, wellboreObjectId) .Append(ObjectTypes.Log, logObjectId) .Append(ObjectTypes.ChannelSet, uri.ObjectId); uris.Add(hierarchyUri); hierarchyUri = rootUri .Append(ObjectTypes.Well, wellObjectId) .Append(ObjectTypes.Wellbore, wellboreObjectId) .Append(ObjectTypes.Log, logObjectId) .Append(ObjectTypes.ChannelSet, uri.ObjectId); uris.Add(hierarchyUri); } hierarchyUri = rootUri .Append(ObjectTypes.Wellbore, wellboreObjectId) .Append(uri.ObjectType, uri.ObjectId); uris.Add(hierarchyUri); hierarchyUri = rootUri .Append(ObjectTypes.Well, wellObjectId) .Append(ObjectTypes.Wellbore, wellboreObjectId) .Append(uri.ObjectType, uri.ObjectId); uris.Add(hierarchyUri); } return(uris); }