blob: 13b1946eb38293fc1970ce7db87b47edb9b7a65e [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.Clients;
12using BaSyx.API.Components;
13using BaSyx.Models.Core.AssetAdministrationShell.Generics;
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010014using BaSyx.Utils.Client.Http;
15using BaSyx.Utils.ResultHandling;
16using System;
17using System.Collections.Generic;
18using System.Net.Http;
19using BaSyx.Utils.PathHandling;
20using BaSyx.Models.Core.Common;
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010021using BaSyx.Models.Connectivity.Descriptors;
Constantin Ziesche310d2aa2020-03-25 11:48:26 +010022using System.Linq;
23using BaSyx.Models.Connectivity;
24using NLog;
Constantin Zieschefa612082020-04-03 09:54:56 +020025using BaSyx.Models.Communication;
26using BaSyx.Utils.DependencyInjection;
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010027
28namespace BaSyx.AAS.Client.Http
29{
30 public class AssetAdministrationShellHttpClient : SimpleHttpClient, IAssetAdministrationShellClient, ISubmodelServiceProviderRegistry
31 {
Constantin Ziesche310d2aa2020-03-25 11:48:26 +010032 private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
33
Constantin Ziesche02817f12020-08-04 21:40:43 +020034 private const string SEPARATOR = "/";
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010035 private const string AAS = "aas";
36 private const string SUBMODELS = "submodels";
37 private const string SUBMODEL = "submodel";
Constantin Ziesche02817f12020-08-04 21:40:43 +020038 private const string SUBMODEL_ELEMENTS = "submodelElements";
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010039 private const string PROPERTIES = "properties";
40 private const string OPERATIONS = "operations";
41 private const string EVENTS = "events";
42 private const string VALUE = "value";
Constantin Ziesche02817f12020-08-04 21:40:43 +020043 private const string ASYNC = "async";
44 private const string INVOCATION_LIST = "invocationList";
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010045
46 private const string BINDING = "binding";
47 private const string BINDINGS = "bindings";
48
Constantin Ziesche310d2aa2020-03-25 11:48:26 +010049 private const int REQUEST_TIMEOUT = 30000;
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010050
51 public Uri Endpoint { get; }
52
Constantin Ziesche310d2aa2020-03-25 11:48:26 +010053 private AssetAdministrationShellHttpClient()
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010054 {
Constantin Ziesche08215502020-09-21 19:08:32 +020055 JsonSerializerSettings = new DependencyInjectionJsonSerializerSettings();
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010056 }
57
Constantin Ziesche310d2aa2020-03-25 11:48:26 +010058 public AssetAdministrationShellHttpClient(Uri endpoint) : this()
59 {
60 endpoint = endpoint ?? throw new ArgumentNullException(nameof(endpoint));
61 Endpoint = endpoint;
62 }
63
Constantin Ziesche03cc1562020-06-02 17:40:49 +020064 public AssetAdministrationShellHttpClient(IAssetAdministrationShellDescriptor aasDescriptor) : this()
Constantin Ziesche310d2aa2020-03-25 11:48:26 +010065 {
66 aasDescriptor = aasDescriptor ?? throw new ArgumentNullException(nameof(aasDescriptor));
67 HttpEndpoint httpEndpoint = aasDescriptor.Endpoints?.OfType<HttpEndpoint>()?.FirstOrDefault();
68 if (httpEndpoint == null || string.IsNullOrEmpty(httpEndpoint.Address))
69 throw new Exception("There is no http endpoint for instantiating a client");
70 else
Constantin Ziesche02817f12020-08-04 21:40:43 +020071 {
72 if (!httpEndpoint.Address.EndsWith(SEPARATOR + AAS) || !httpEndpoint.Address.EndsWith(SEPARATOR + AAS + SEPARATOR))
73 Endpoint = new Uri(httpEndpoint.Address + SEPARATOR + AAS);
74 else
75 Endpoint = new Uri(httpEndpoint.Address);
76 }
Constantin Ziesche310d2aa2020-03-25 11:48:26 +010077 }
78
79
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010080 public Uri GetUri(params string[] pathElements)
81 {
82 if (pathElements == null)
83 return Endpoint;
84 return Endpoint.Append(pathElements);
85 }
86
87 public IResult<IAssetAdministrationShellDescriptor> RetrieveAssetAdministrationShellDescriptor()
88 {
89 var request = base.CreateRequest(GetUri(), HttpMethod.Get);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +010090 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010091 return base.EvaluateResponse<IAssetAdministrationShellDescriptor>(response, response.Entity);
92 }
93
94 public IResult<IAssetAdministrationShell> RetrieveAssetAdministrationShell()
95 {
96 var request = base.CreateRequest(GetUri(), HttpMethod.Get);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +010097 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010098 return base.EvaluateResponse<IAssetAdministrationShell>(response, response.Entity);
99 }
100
101 public IResult<ISubmodel> CreateSubmodel(ISubmodel submodel)
102 {
Constantin Ziesche02817f12020-08-04 21:40:43 +0200103 var request = base.CreateJsonContentRequest(GetUri(SUBMODELS), HttpMethod.Put, submodel);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100104 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100105 return base.EvaluateResponse<ISubmodel>(response, response.Entity);
106 }
107
108 public IResult<IElementContainer<ISubmodel>> RetrieveSubmodels()
109 {
110 var request = base.CreateRequest(GetUri(SUBMODELS), HttpMethod.Get);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100111 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100112 return base.EvaluateResponse<ElementContainer<ISubmodel>>(response, response.Entity);
113 }
114
115 public IResult<ISubmodel> RetrieveSubmodel(string submodelId)
116 {
117 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId), HttpMethod.Get);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100118 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100119 return base.EvaluateResponse<ISubmodel>(response, response.Entity);
120 }
121
122 public IResult DeleteSubmodel(string submodelId)
123 {
124 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId), HttpMethod.Delete);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100125 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100126 return base.EvaluateResponse(response, response.Entity);
127 }
128
129 public IResult<IOperation> CreateOperation(string submodelId, IOperation operation)
130 {
Constantin Ziesche02817f12020-08-04 21:40:43 +0200131 var request = base.CreateJsonContentRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, OPERATIONS), HttpMethod.Put, operation);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100132 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100133 return base.EvaluateResponse<IOperation>(response, response.Entity);
134 }
135
Constantin Ziesche02817f12020-08-04 21:40:43 +0200136 public IResult<IElementContainer<ISubmodelElement>> RetrieveSubmodelElements(string submodelId)
137 {
138 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, SUBMODEL_ELEMENTS), HttpMethod.Get);
139 var response = base.SendRequest(request, REQUEST_TIMEOUT);
140 return base.EvaluateResponse<ElementContainer<ISubmodelElement>>(response, response.Entity);
141 }
142
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100143 public IResult<IElementContainer<IOperation>> RetrieveOperations(string submodelId)
144 {
145 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, OPERATIONS), HttpMethod.Get);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100146 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100147 return base.EvaluateResponse<ElementContainer<IOperation>>(response, response.Entity);
148 }
149
150 public IResult<IOperation> RetrieveOperation(string submodelId, string operationId)
151 {
152 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, OPERATIONS, operationId), HttpMethod.Get);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100153 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100154 return base.EvaluateResponse<IOperation>(response, response.Entity);
155 }
156
157 public IResult DeleteOperation(string submodelId, string operationId)
158 {
159 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, OPERATIONS, operationId), HttpMethod.Delete);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100160 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100161 return base.EvaluateResponse(response, response.Entity);
162 }
163
Constantin Zieschefa612082020-04-03 09:54:56 +0200164 public IResult<InvocationResponse> InvokeOperation(string submodelId, string operationId, InvocationRequest invocationRequest)
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100165 {
Constantin Zieschefa612082020-04-03 09:54:56 +0200166 var request = base.CreateJsonContentRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, OPERATIONS, operationId), HttpMethod.Post, invocationRequest);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100167 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Zieschefa612082020-04-03 09:54:56 +0200168 return base.EvaluateResponse<InvocationResponse>(response, response.Entity);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100169 }
170
171 public IResult<IProperty> CreateProperty(string submodelId, IProperty property)
172 {
Constantin Ziesche02817f12020-08-04 21:40:43 +0200173 var request = base.CreateJsonContentRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, PROPERTIES), HttpMethod.Put, property);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100174 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100175 return base.EvaluateResponse<IProperty>(response, response.Entity);
176 }
177
Constantin Ziesche02817f12020-08-04 21:40:43 +0200178 public IResult<ISubmodelElement> CreateSubmodelElement(string submodelId, ISubmodelElement submodelElement)
179 {
180 var request = base.CreateJsonContentRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, SUBMODEL_ELEMENTS), HttpMethod.Put, submodelElement);
181 var response = base.SendRequest(request, REQUEST_TIMEOUT);
182 return base.EvaluateResponse<ISubmodelElement>(response, response.Entity);
183 }
184
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100185 public IResult<IElementContainer<IProperty>> RetrieveProperties(string submodelId)
186 {
187 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, PROPERTIES), HttpMethod.Get);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100188 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100189 return base.EvaluateResponse<ElementContainer<IProperty>>(response, response.Entity);
190 }
191
192 public IResult<IProperty> RetrieveProperty(string submodelId, string propertyId)
193 {
194 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, PROPERTIES, propertyId), HttpMethod.Get);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100195 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100196 return base.EvaluateResponse<IProperty>(response, response.Entity);
197 }
198
Constantin Ziesche02817f12020-08-04 21:40:43 +0200199 public IResult<ISubmodelElement> RetrieveSubmodelElement(string submodelId, string submodelElementId)
200 {
201 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, SUBMODEL_ELEMENTS, submodelElementId), HttpMethod.Get);
202 var response = base.SendRequest(request, REQUEST_TIMEOUT);
203 return base.EvaluateResponse<ISubmodelElement>(response, response.Entity);
204 }
205
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100206 public IResult UpdatePropertyValue(string submodelId, string propertyId, IValue value)
207 {
208 var request = base.CreateJsonContentRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, PROPERTIES, propertyId, VALUE), HttpMethod.Put, value);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100209 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100210 return base.EvaluateResponse(response, response.Entity);
211 }
212
213 public IResult<IValue> RetrievePropertyValue(string submodelId, string propertyId)
214 {
215 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, PROPERTIES, propertyId, VALUE), HttpMethod.Get);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100216 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100217 return base.EvaluateResponse<IValue>(response, response.Entity);
218 }
219
Constantin Ziesche02817f12020-08-04 21:40:43 +0200220 public IResult DeleteSubmodelElement(string submodelId, string submodelElementId)
221 {
222 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, SUBMODEL_ELEMENTS, submodelElementId), HttpMethod.Delete);
223 var response = base.SendRequest(request, REQUEST_TIMEOUT);
224 return base.EvaluateResponse(response, response.Entity);
225 }
226
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100227 public IResult DeleteProperty(string submodelId, string propertyId)
228 {
229 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, PROPERTIES, propertyId), HttpMethod.Delete);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100230 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100231 return base.EvaluateResponse(response, response.Entity);
232 }
233
234 public IResult<IEvent> CreateEvent(string submodelId, IEvent eventable)
235 {
Constantin Ziesche02817f12020-08-04 21:40:43 +0200236 var request = base.CreateJsonContentRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, EVENTS), HttpMethod.Put, eventable);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100237 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100238 return base.EvaluateResponse<IEvent>(response, response.Entity);
239 }
240
241 public IResult<IElementContainer<IEvent>> RetrieveEvents(string submodelId)
242 {
243 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, EVENTS), HttpMethod.Get);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100244 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100245 return base.EvaluateResponse<ElementContainer<IEvent>>(response, response.Entity);
246 }
247
248 public IResult<IEvent> RetrieveEvent(string submodelId, string eventId)
249 {
250 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, EVENTS, eventId), HttpMethod.Get);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100251 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100252 return base.EvaluateResponse<IEvent>(response, response.Entity);
253 }
254
255 public IResult DeleteEvent(string submodelId, string eventId)
256 {
257 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, EVENTS, eventId), HttpMethod.Delete);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100258 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100259 return base.EvaluateResponse(response, response.Entity);
260 }
261
262 public IResult<ISubmodelDescriptor> RegisterSubmodelServiceProvider(string id, ISubmodelServiceProvider submodelServiceProvider)
263 {
264 var request = base.CreateJsonContentRequest(GetUri(SUBMODELS, id, BINDING), HttpMethod.Post, submodelServiceProvider.ServiceDescriptor);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100265 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100266 return base.EvaluateResponse<ISubmodelDescriptor>(response, response.Entity);
267 }
268
269 public IResult UnregisterSubmodelServiceProvider(string id)
270 {
271 var request = base.CreateRequest(GetUri(SUBMODELS, id, BINDING), HttpMethod.Delete);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100272 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100273 return base.EvaluateResponse(response, response.Entity);
274 }
275
276 public IResult<ISubmodelServiceProvider> GetSubmodelServiceProvider(string id)
277 {
278 var request = base.CreateRequest(GetUri(SUBMODELS, id, BINDING), HttpMethod.Get);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100279 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100280 return base.EvaluateResponse<ISubmodelServiceProvider>(response, response.Entity);
281 }
282
283 public IResult<IEnumerable<ISubmodelServiceProvider>> GetSubmodelServiceProviders()
284 {
285 var request = base.CreateRequest(GetUri(SUBMODELS, BINDINGS), HttpMethod.Get);
Constantin Ziesche310d2aa2020-03-25 11:48:26 +0100286 var response = base.SendRequest(request, REQUEST_TIMEOUT);
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100287 return base.EvaluateResponse<IEnumerable<ISubmodelServiceProvider>>(response, response.Entity);
288 }
Constantin Zieschefa612082020-04-03 09:54:56 +0200289 public IResult<CallbackResponse> InvokeOperationAsync(string submodelId, string operationId, InvocationRequest invocationRequest)
290 {
Constantin Ziesche02817f12020-08-04 21:40:43 +0200291 var request = base.CreateJsonContentRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, OPERATIONS, operationId, ASYNC), HttpMethod.Post, invocationRequest);
Constantin Zieschefa612082020-04-03 09:54:56 +0200292 var response = base.SendRequest(request, REQUEST_TIMEOUT);
293 return base.EvaluateResponse<CallbackResponse>(response, response.Entity);
294 }
295
296 public IResult<InvocationResponse> GetInvocationResult(string submodelId, string operationId, string requestId)
297 {
Constantin Ziesche02817f12020-08-04 21:40:43 +0200298 var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, SUBMODEL, OPERATIONS, operationId, INVOCATION_LIST, requestId), HttpMethod.Get);
Constantin Zieschefa612082020-04-03 09:54:56 +0200299 var response = base.SendRequest(request, REQUEST_TIMEOUT);
300 return base.EvaluateResponse<InvocationResponse>(response, response.Entity);
301 }
302
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100303 }
304}