blob: 0db377ced1561389c01e61f167212fadbe7cd774 [file] [log] [blame]
Constantin Ziesche857c7ab2020-02-25 11:24:51 +01001/*******************************************************************************
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*******************************************************************************/
11using BaSyx.API.Components;
12using BaSyx.Models.Connectivity.Descriptors;
13using BaSyx.Models.Core.Common;
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010014using BaSyx.Utils.Client.Http;
Constantin Zieschefa612082020-04-03 09:54:56 +020015using BaSyx.Utils.DependencyInjection;
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010016using BaSyx.Utils.ResultHandling;
17using NLog;
18using System;
19using System.Collections.Generic;
Constantin Ziesche7b6d4792020-08-18 17:15:11 +020020using System.Linq;
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010021using System.Net.Http;
22using System.Threading;
23using System.Threading.Tasks;
24using System.Web;
25
26namespace 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 Ziesche7b6d4792020-08-18 17:15:11 +020033 public const string REGISTRY_BASE_PATH = "api/v1/registry";
34 public const string SUBMODEL_PATH = "submodels";
35 public const string PATH_SEPERATOR = "/";
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010036
37 private int RepeatRegistrationInterval = -1;
Constantin Ziesche7b6d4792020-08-18 17:15:11 +020038 private string baseUrl = null;
39 private int Timeout = -1;
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010040 private CancellationTokenSource RepeatRegistrationCancellationToken = null;
Constantin Ziesche7b6d4792020-08-18 17:15:11 +020041
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010042
43 public void LoadSettings(RegistryClientSettings settings)
44 {
Constantin Ziesche7b6d4792020-08-18 17:15:11 +020045 LoadProxy(settings.ProxyConfig);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010046
Constantin Ziesche7b6d4792020-08-18 17:15:11 +020047 if (settings.RegistryConfig.RepeatRegistration.HasValue)
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010048 RepeatRegistrationInterval = settings.RegistryConfig.RepeatRegistration.Value;
Constantin Ziesche7b6d4792020-08-18 17:15:11 +020049
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 Ziesche857c7ab2020-02-25 11:24:51 +010056 }
57
Constantin Ziesche7b6d4792020-08-18 17:15:11 +020058 public RegistryHttpClient() : this(null)
59 { }
60
61 public RegistryHttpClient(RegistryClientSettings registryClientSettings)
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010062 {
63 Settings = registryClientSettings ?? RegistryClientSettings.LoadSettings();
Constantin Ziesche7b6d4792020-08-18 17:15:11 +020064 Settings = Settings ?? throw new NullReferenceException("Settings is null");
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010065
66 LoadSettings(Settings);
67 JsonSerializerSettings = new JsonStandardSettings();
68 }
69
70 public Uri GetUri(params string[] pathElements)
71 {
Constantin Ziesche7b6d4792020-08-18 17:15:11 +020072 string path = baseUrl;
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010073
74 if (pathElements?.Length > 0)
75 foreach (var pathElement in pathElements)
76 {
77 string encodedPathElement = HttpUtility.UrlEncode(pathElement);
Constantin Ziesche7b6d4792020-08-18 17:15:11 +020078 path = path.TrimEnd('/') + PATH_SEPERATOR + encodedPathElement.TrimEnd('/');
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010079 }
80 return new Uri(path);
81 }
82
Constantin Ziesche7b6d4792020-08-18 17:15:11 +020083 public void RepeatRegistration(IAssetAdministrationShellDescriptor aasDescriptor, CancellationTokenSource cancellationToken)
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010084 {
85 RepeatRegistrationCancellationToken = cancellationToken;
86 Task.Factory.StartNew(async () =>
87 {
88 while (!cancellationToken.IsCancellationRequested)
89 {
Constantin Ziesche7b6d4792020-08-18 17:15:11 +020090 IResult<IAssetAdministrationShellDescriptor> result = CreateOrUpdateAssetAdministrationShellRegistration(aasDescriptor.Identification.Id, aasDescriptor);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010091 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 Ziesche7b6d4792020-08-18 17:15:11 +0200102 public IResult<IAssetAdministrationShellDescriptor> CreateOrUpdateAssetAdministrationShellRegistration(string aasId, IAssetAdministrationShellDescriptor aasDescriptor)
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100103 {
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200104 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 Ziesche857c7ab2020-02-25 11:24:51 +0100110 var response = base.SendRequest(request, Timeout);
111 return base.EvaluateResponse<IAssetAdministrationShellDescriptor>(response, response.Entity);
112 }
113
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200114 public IResult<IAssetAdministrationShellDescriptor> RetrieveAssetAdministrationShellRegistration(string aasId)
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100115 {
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200116 if (string.IsNullOrEmpty(aasId))
117 return new Result<IAssetAdministrationShellDescriptor>(new ArgumentNullException(nameof(aasId)));
118
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100119 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 Ziesche7b6d4792020-08-18 17:15:11 +0200124 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 Zieschee837f992020-08-19 12:04:32 +0200138 return new Result<IQueryableElementContainer<IAssetAdministrationShellDescriptor>>(result.Success, foundItems?.AsQueryableElementContainer(), result.Messages);
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200139 }
140 }
141
142 public IResult<IQueryableElementContainer<IAssetAdministrationShellDescriptor>> RetrieveAllAssetAdministrationShellRegistrations()
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100143 {
144 var request = base.CreateRequest(GetUri(), HttpMethod.Get);
145 var response = base.SendRequest(request, Timeout);
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200146 var result = base.EvaluateResponse<IEnumerable<IAssetAdministrationShellDescriptor>>(response, response.Entity);
Constantin Zieschee837f992020-08-19 12:04:32 +0200147 return new Result<IQueryableElementContainer<IAssetAdministrationShellDescriptor>>(result.Success, result.Entity?.AsQueryableElementContainer(), result.Messages);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100148 }
149
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200150 public IResult DeleteAssetAdministrationShellRegistration(string aasId)
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100151 {
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200152 if (string.IsNullOrEmpty(aasId))
153 return new Result(new ArgumentNullException(nameof(aasId)));
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100154
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200155 if (RepeatRegistrationInterval > 0)
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100156 RepeatRegistrationCancellationToken?.Cancel();
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100157
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 Ziesche7b6d4792020-08-18 17:15:11 +0200163 public IResult<ISubmodelDescriptor> CreateOrUpdateSubmodelRegistration(string aasId, string submodelId, ISubmodelDescriptor submodelDescriptor)
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100164 {
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200165 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 Ziesche857c7ab2020-02-25 11:24:51 +0100173 var response = base.SendRequest(request, Timeout);
174 return base.EvaluateResponse<ISubmodelDescriptor>(response, response.Entity);
175 }
176
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200177 public IResult<IQueryableElementContainer<ISubmodelDescriptor>> RetrieveAllSubmodelRegistrations(string aasId, Predicate<ISubmodelDescriptor> predicate)
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100178 {
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200179 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 Ziesche857c7ab2020-02-25 11:24:51 +0100185 var response = base.SendRequest(request, Timeout);
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200186 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 Zieschee837f992020-08-19 12:04:32 +0200193 return new Result<IQueryableElementContainer<ISubmodelDescriptor>>(result.Success, foundItems?.AsQueryableElementContainer(), result.Messages);
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200194 }
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100195 }
196
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200197 public IResult<IQueryableElementContainer<ISubmodelDescriptor>> RetrieveAllSubmodelRegistrations(string aasId)
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100198 {
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200199 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 Zieschee837f992020-08-19 12:04:32 +0200206 return new Result<IQueryableElementContainer<ISubmodelDescriptor>>(result.Success, result.Entity?.AsQueryableElementContainer(), result.Messages);
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200207 }
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 Ziesche857c7ab2020-02-25 11:24:51 +0100217 var response = base.SendRequest(request, Timeout);
218 return base.EvaluateResponse<ISubmodelDescriptor>(response, response.Entity);
219 }
220
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200221 public IResult DeleteSubmodelRegistration(string aasId, string submodelId)
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100222 {
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200223 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 Ziesche857c7ab2020-02-25 11:24:51 +0100229 var response = base.SendRequest(request, Timeout);
230 return base.EvaluateResponse(response, response.Entity);
Constantin Ziesche7b6d4792020-08-18 17:15:11 +0200231 }
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100232 }
233}