Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2020 Robert Bosch GmbH |
| 3 | * Author: Constantin Ziesche (constantin.ziesche@bosch.com) |
| 4 | * |
| 5 | * This program and the accompanying materials are made available under the |
| 6 | * terms of the Eclipse Public License 2.0 which is available at |
| 7 | * http://www.eclipse.org/legal/epl-2.0 |
| 8 | * |
| 9 | * SPDX-License-Identifier: EPL-2.0 |
| 10 | *******************************************************************************/ |
| 11 | using BaSyx.API.Components; |
| 12 | using BaSyx.Models.Connectivity.Descriptors; |
| 13 | using BaSyx.Models.Core.Common; |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 14 | using BaSyx.Utils.Client.Http; |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 15 | using BaSyx.Utils.DependencyInjection; |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 16 | using BaSyx.Utils.ResultHandling; |
| 17 | using NLog; |
| 18 | using System; |
| 19 | using System.Collections.Generic; |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 20 | using System.Linq; |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 21 | using System.Net.Http; |
| 22 | using System.Threading; |
| 23 | using System.Threading.Tasks; |
| 24 | using System.Web; |
| 25 | |
| 26 | namespace BaSyx.Registry.Client.Http |
| 27 | { |
| 28 | public class RegistryHttpClient : SimpleHttpClient, IAssetAdministrationShellRegistry |
| 29 | { |
| 30 | private static readonly ILogger logger = LogManager.GetCurrentClassLogger(); |
| 31 | public RegistryClientSettings Settings { get; } |
| 32 | |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 33 | public const string REGISTRY_BASE_PATH = "api/v1/registry"; |
| 34 | public const string SUBMODEL_PATH = "submodels"; |
| 35 | public const string PATH_SEPERATOR = "/"; |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 36 | |
| 37 | private int RepeatRegistrationInterval = -1; |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 38 | private string baseUrl = null; |
| 39 | private int Timeout = -1; |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 40 | private CancellationTokenSource RepeatRegistrationCancellationToken = null; |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 41 | |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 42 | |
| 43 | public void LoadSettings(RegistryClientSettings settings) |
| 44 | { |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 45 | LoadProxy(settings.ProxyConfig); |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 46 | |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 47 | if (settings.RegistryConfig.RepeatRegistration.HasValue) |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 48 | RepeatRegistrationInterval = settings.RegistryConfig.RepeatRegistration.Value; |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 49 | |
| 50 | if (settings.ClientConfig.RequestConfig.RequestTimeout.HasValue) |
| 51 | Timeout = settings.ClientConfig.RequestConfig.RequestTimeout.Value; |
| 52 | else |
| 53 | Timeout = DEFAULT_REQUEST_TIMEOUT; |
| 54 | |
| 55 | baseUrl = settings.RegistryConfig.RegistryUrl.TrimEnd('/') + PATH_SEPERATOR + REGISTRY_BASE_PATH; |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 56 | } |
| 57 | |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 58 | public RegistryHttpClient() : this(null) |
| 59 | { } |
| 60 | |
| 61 | public RegistryHttpClient(RegistryClientSettings registryClientSettings) |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 62 | { |
| 63 | Settings = registryClientSettings ?? RegistryClientSettings.LoadSettings(); |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 64 | Settings = Settings ?? throw new NullReferenceException("Settings is null"); |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 65 | |
| 66 | LoadSettings(Settings); |
| 67 | JsonSerializerSettings = new JsonStandardSettings(); |
| 68 | } |
| 69 | |
| 70 | public Uri GetUri(params string[] pathElements) |
| 71 | { |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 72 | string path = baseUrl; |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 73 | |
| 74 | if (pathElements?.Length > 0) |
| 75 | foreach (var pathElement in pathElements) |
| 76 | { |
| 77 | string encodedPathElement = HttpUtility.UrlEncode(pathElement); |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 78 | path = path.TrimEnd('/') + PATH_SEPERATOR + encodedPathElement.TrimEnd('/'); |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 79 | } |
| 80 | return new Uri(path); |
| 81 | } |
| 82 | |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 83 | public void RepeatRegistration(IAssetAdministrationShellDescriptor aasDescriptor, CancellationTokenSource cancellationToken) |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 84 | { |
| 85 | RepeatRegistrationCancellationToken = cancellationToken; |
| 86 | Task.Factory.StartNew(async () => |
| 87 | { |
| 88 | while (!cancellationToken.IsCancellationRequested) |
| 89 | { |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 90 | IResult<IAssetAdministrationShellDescriptor> result = CreateOrUpdateAssetAdministrationShellRegistration(aasDescriptor.Identification.Id, aasDescriptor); |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 91 | logger.Info("Registration-Renewal - Success: " + result.Success + " | Messages: " + result.Messages.ToString()); |
| 92 | await Task.Delay(RepeatRegistrationInterval); |
| 93 | } |
| 94 | }, cancellationToken.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); |
| 95 | } |
| 96 | |
| 97 | public void CancelRepeatingRegistration() |
| 98 | { |
| 99 | RepeatRegistrationCancellationToken?.Cancel(); |
| 100 | } |
| 101 | |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 102 | public IResult<IAssetAdministrationShellDescriptor> CreateOrUpdateAssetAdministrationShellRegistration(string aasId, IAssetAdministrationShellDescriptor aasDescriptor) |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 103 | { |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 104 | if (string.IsNullOrEmpty(aasId)) |
| 105 | return new Result<IAssetAdministrationShellDescriptor>(new ArgumentNullException(nameof(aasId))); |
| 106 | if (aasDescriptor == null) |
| 107 | return new Result<IAssetAdministrationShellDescriptor>(new ArgumentNullException(nameof(aasDescriptor))); |
| 108 | |
| 109 | var request = base.CreateJsonContentRequest(GetUri(aasId), HttpMethod.Put, aasDescriptor); |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 110 | var response = base.SendRequest(request, Timeout); |
| 111 | return base.EvaluateResponse<IAssetAdministrationShellDescriptor>(response, response.Entity); |
| 112 | } |
| 113 | |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 114 | public IResult<IAssetAdministrationShellDescriptor> RetrieveAssetAdministrationShellRegistration(string aasId) |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 115 | { |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 116 | if (string.IsNullOrEmpty(aasId)) |
| 117 | return new Result<IAssetAdministrationShellDescriptor>(new ArgumentNullException(nameof(aasId))); |
| 118 | |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 119 | var request = base.CreateRequest(GetUri(aasId), HttpMethod.Get); |
| 120 | var response = base.SendRequest(request, Timeout); |
| 121 | return base.EvaluateResponse<IAssetAdministrationShellDescriptor>(response, response.Entity); |
| 122 | } |
| 123 | |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 124 | public IResult<IQueryableElementContainer<IAssetAdministrationShellDescriptor>> RetrieveAllAssetAdministrationShellRegistrations(Predicate<IAssetAdministrationShellDescriptor> predicate) |
| 125 | { |
| 126 | if (predicate == null) |
| 127 | return new Result<IQueryableElementContainer<IAssetAdministrationShellDescriptor>>(new ArgumentNullException(nameof(predicate))); |
| 128 | |
| 129 | var request = base.CreateRequest(GetUri(), HttpMethod.Get); |
| 130 | var response = base.SendRequest(request, Timeout); |
| 131 | var result = base.EvaluateResponse<IEnumerable<IAssetAdministrationShellDescriptor>>(response, response.Entity); |
| 132 | |
| 133 | if (!result.Success || result.Entity == null) |
| 134 | return new Result<IQueryableElementContainer<IAssetAdministrationShellDescriptor>>(result); |
| 135 | else |
| 136 | { |
| 137 | var foundItems = result.Entity.Where(w => predicate.Invoke(w)); |
Constantin Ziesche | e837f99 | 2020-08-19 12:04:32 +0200 | [diff] [blame] | 138 | return new Result<IQueryableElementContainer<IAssetAdministrationShellDescriptor>>(result.Success, foundItems?.AsQueryableElementContainer(), result.Messages); |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 139 | } |
| 140 | } |
| 141 | |
| 142 | public IResult<IQueryableElementContainer<IAssetAdministrationShellDescriptor>> RetrieveAllAssetAdministrationShellRegistrations() |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 143 | { |
| 144 | var request = base.CreateRequest(GetUri(), HttpMethod.Get); |
| 145 | var response = base.SendRequest(request, Timeout); |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 146 | var result = base.EvaluateResponse<IEnumerable<IAssetAdministrationShellDescriptor>>(response, response.Entity); |
Constantin Ziesche | e837f99 | 2020-08-19 12:04:32 +0200 | [diff] [blame] | 147 | return new Result<IQueryableElementContainer<IAssetAdministrationShellDescriptor>>(result.Success, result.Entity?.AsQueryableElementContainer(), result.Messages); |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 148 | } |
| 149 | |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 150 | public IResult DeleteAssetAdministrationShellRegistration(string aasId) |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 151 | { |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 152 | if (string.IsNullOrEmpty(aasId)) |
| 153 | return new Result(new ArgumentNullException(nameof(aasId))); |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 154 | |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 155 | if (RepeatRegistrationInterval > 0) |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 156 | RepeatRegistrationCancellationToken?.Cancel(); |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 157 | |
| 158 | var request = base.CreateRequest(GetUri(aasId), HttpMethod.Delete); |
| 159 | var response = base.SendRequest(request, Timeout); |
| 160 | return base.EvaluateResponse(response, response.Entity); |
| 161 | } |
| 162 | |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 163 | public IResult<ISubmodelDescriptor> CreateOrUpdateSubmodelRegistration(string aasId, string submodelId, ISubmodelDescriptor submodelDescriptor) |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 164 | { |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 165 | if (string.IsNullOrEmpty(aasId)) |
| 166 | return new Result<ISubmodelDescriptor>(new ArgumentNullException(nameof(aasId))); |
| 167 | if (string.IsNullOrEmpty(submodelId)) |
| 168 | return new Result<ISubmodelDescriptor>(new ArgumentNullException(nameof(submodelId))); |
| 169 | if (submodelDescriptor == null) |
| 170 | return new Result<ISubmodelDescriptor>(new ArgumentNullException(nameof(submodelDescriptor))); |
| 171 | |
| 172 | var request = base.CreateJsonContentRequest(GetUri(aasId, SUBMODEL_PATH, submodelId), HttpMethod.Put, submodelDescriptor); |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 173 | var response = base.SendRequest(request, Timeout); |
| 174 | return base.EvaluateResponse<ISubmodelDescriptor>(response, response.Entity); |
| 175 | } |
| 176 | |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 177 | public IResult<IQueryableElementContainer<ISubmodelDescriptor>> RetrieveAllSubmodelRegistrations(string aasId, Predicate<ISubmodelDescriptor> predicate) |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 178 | { |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 179 | if (string.IsNullOrEmpty(aasId)) |
| 180 | return new Result<IQueryableElementContainer<ISubmodelDescriptor>>(new ArgumentNullException(nameof(aasId))); |
| 181 | if (predicate == null) |
| 182 | return new Result<IQueryableElementContainer<ISubmodelDescriptor>>(new ArgumentNullException(nameof(predicate))); |
| 183 | |
| 184 | var request = base.CreateRequest(GetUri(aasId, SUBMODEL_PATH), HttpMethod.Get); |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 185 | var response = base.SendRequest(request, Timeout); |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 186 | var result = base.EvaluateResponse<IEnumerable<ISubmodelDescriptor>>(response, response.Entity); |
| 187 | |
| 188 | if (!result.Success || result.Entity == null) |
| 189 | return new Result<IQueryableElementContainer<ISubmodelDescriptor>>(result); |
| 190 | else |
| 191 | { |
| 192 | var foundItems = result.Entity.Where(w => predicate.Invoke(w)); |
Constantin Ziesche | e837f99 | 2020-08-19 12:04:32 +0200 | [diff] [blame] | 193 | return new Result<IQueryableElementContainer<ISubmodelDescriptor>>(result.Success, foundItems?.AsQueryableElementContainer(), result.Messages); |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 194 | } |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 195 | } |
| 196 | |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 197 | public IResult<IQueryableElementContainer<ISubmodelDescriptor>> RetrieveAllSubmodelRegistrations(string aasId) |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 198 | { |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 199 | if (string.IsNullOrEmpty(aasId)) |
| 200 | return new Result<IQueryableElementContainer<ISubmodelDescriptor>>(new ArgumentNullException(nameof(aasId))); |
| 201 | |
| 202 | var request = base.CreateRequest(GetUri(aasId, SUBMODEL_PATH), HttpMethod.Get); |
| 203 | var response = base.SendRequest(request, Timeout); |
| 204 | var result = base.EvaluateResponse<IEnumerable<ISubmodelDescriptor>>(response, response.Entity); |
| 205 | |
Constantin Ziesche | e837f99 | 2020-08-19 12:04:32 +0200 | [diff] [blame] | 206 | return new Result<IQueryableElementContainer<ISubmodelDescriptor>>(result.Success, result.Entity?.AsQueryableElementContainer(), result.Messages); |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 207 | } |
| 208 | |
| 209 | public IResult<ISubmodelDescriptor> RetrieveSubmodelRegistration(string aasId, string submodelId) |
| 210 | { |
| 211 | if (string.IsNullOrEmpty(aasId)) |
| 212 | return new Result<ISubmodelDescriptor>(new ArgumentNullException(nameof(aasId))); |
| 213 | if (string.IsNullOrEmpty(submodelId)) |
| 214 | return new Result<ISubmodelDescriptor>(new ArgumentNullException(nameof(submodelId))); |
| 215 | |
| 216 | var request = base.CreateRequest(GetUri(aasId, SUBMODEL_PATH, submodelId), HttpMethod.Get); |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 217 | var response = base.SendRequest(request, Timeout); |
| 218 | return base.EvaluateResponse<ISubmodelDescriptor>(response, response.Entity); |
| 219 | } |
| 220 | |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 221 | public IResult DeleteSubmodelRegistration(string aasId, string submodelId) |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 222 | { |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 223 | if (string.IsNullOrEmpty(aasId)) |
| 224 | return new Result(new ArgumentNullException(nameof(aasId))); |
| 225 | if (string.IsNullOrEmpty(submodelId)) |
| 226 | return new Result(new ArgumentNullException(nameof(submodelId))); |
| 227 | |
| 228 | var request = base.CreateRequest(GetUri(aasId, SUBMODEL_PATH, submodelId), HttpMethod.Delete); |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 229 | var response = base.SendRequest(request, Timeout); |
| 230 | return base.EvaluateResponse(response, response.Entity); |
Constantin Ziesche | 7b6d479 | 2020-08-18 17:15:11 +0200 | [diff] [blame] | 231 | } |
Constantin Ziesche | 857c7ab | 2020-02-25 11:24:51 +0100 | [diff] [blame] | 232 | } |
| 233 | } |