blob: 14ac13046c7025b1b8d7729e6e2b3d140bc74f2d [file] [log] [blame]
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using BaSys40.Models.Core.AssetAdministrationShell.Generics;
using BaSys40.Utils.ResultHandling;
using BaSys40.API.ServiceProvider;
using static BaSys40.Utils.ResultHandling.Utils;
using BaSys40.Utils.Client;
using System;
using BaSys40.API.AssetAdministrationShell;
using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
using BaSys40.Models.Connectivity;
namespace BaSys40.Component.REST.Controllers
{
/// <summary>
/// All Asset Administration Shell Services provided by the component
/// </summary>
public class SubmodelServices : Controller, ISubmodelServiceProvider
{
private readonly ISubmodelServiceProvider submodelServiceProvider;
public ISubmodel Submodel => submodelServiceProvider.GetBinding();
public IServiceDescriptor ServiceDescriptor { get; }
public SubmodelServices(ISubmodelServiceProvider submodelServiceProvider)
{
this.submodelServiceProvider = submodelServiceProvider;
ServiceDescriptor = submodelServiceProvider.ServiceDescriptor;
}
public void BindTo(ISubmodel element)
{
submodelServiceProvider.BindTo(element);
}
public ISubmodel GetBinding()
{
return submodelServiceProvider.GetBinding();
}
#region REST-Interface Submodel
/// <summary>
/// Retrieves the Submodel
/// </summary>
/// <returns></returns>
/// <response code="200">Success</response>
/// <response code="502">Bad Gateway - Submodel not available</response>
[HttpGet("submodel", Name = "GetSubmodel")]
[ProducesResponseType(typeof(IResult<ISubmodel>), 200)]
public IActionResult GetSubmodel()
{
var result = submodelServiceProvider.GetBinding();
if (result != null)
return new OkObjectResult(new Result<ISubmodel>(true, result));
return StatusCode(502);
}
/// <summary>
/// Retrieves all DataElements from the current Submodel
/// </summary>
/// <returns></returns>
/// <response code="200">Returns a list of found DataElements</response>
/// <response code="404">Submodel not found / No DataElements found</response>
/// <response code="502">Bad Gateway</response>
[HttpGet("submodel/dataElements", Name = "GetDataElements")]
[ProducesResponseType(typeof(IResult<ElementContainer<IDataElement>>), 200)]
public IActionResult GetDataElements(string submodelId)
{
var result = RetrieveDataElements();
return EvaluateResult(result, CrudOperation.Retrieve);
}
/// <summary>
/// Retrieves all Operations from the current Submodel
/// </summary>
/// <returns></returns>
/// <response code="200">Success</response>
/// <response code="404">Submodel not found / No Operations found</response>
/// <response code="502">Bad Gateway</response>
[HttpGet("submodel/operations", Name = "GetOperations")]
[ProducesResponseType(typeof(IResult<ElementContainer<IOperation>>), 200)]
public IActionResult GetOperations(string submodelId)
{
var result = RetrieveOperations();
return EvaluateResult(result, CrudOperation.Retrieve);
}
/// <summary>
/// Retrieves all Events from the current Submodel
/// </summary>
/// <returns></returns>
/// <response code="200">Success</response>
/// <response code="404">Submodel not found / No Events found</response>
/// <response code="502">Bad Gateway</response>
[HttpGet("submodel/events", Name = "GetEvents")]
[ProducesResponseType(typeof(IResult<ElementContainer<IEvent>>), 200)]
public IActionResult GetEvents(string submodelId)
{
var result = RetrieveEvents();
return EvaluateResult(result, CrudOperation.Retrieve);
}
#region DataElement - REST-Calls
/// <summary>
/// Adds a new DataElement to the Asset Administration Shell's Submodel
/// </summary>
/// <param name="submodelId">The Submodel's short id</param>
/// <param name="dataElement">The DataElement's description object</param>
/// <returns></returns>
/// <response code="201">DataElement created successfully</response>
/// <response code="400">Bad Request</response>
/// <response code="404">Submodel not found</response>
/// <response code="502">Bad Gateway</response>
[HttpPost("submodel/dataElements", Name = "PostDataElement")]
[ProducesResponseType(typeof(IResult<IDataElement>), 201)]
public IActionResult PostDataElement(string submodelId, [FromBody] IDataElement dataElement)
{
var result = CreateDataElement(dataElement);
return EvaluateResult(result, CrudOperation.Create);
}
/// <summary>
/// Retrieves a specific DataElement from the Asset Administrations's Submodel
/// </summary>
/// <param name="submodelId">The Submodel's short id</param>
/// <param name="dataElementId">The DataElement's short id</param>
/// <returns></returns>
/// <response code="200">Returns the requested DataElement</response>
/// <response code="404">Submodel/DataElement not found</response>
/// <response code="502">Bad Gateway</response>
[HttpGet("submodel/dataElements/{dataElementId}", Name = "GetDataElement")]
[ProducesResponseType(typeof(IResult<IDataElement>), 200)]
public IActionResult GetDataElement(string submodelId, string dataElementId)
{
var result = RetrieveDataElement(dataElementId);
return EvaluateResult(result, CrudOperation.Retrieve);
}
/// <summary>
/// Retrieves the value of a specific DataElement from the Asset Administrations Shell's Submodel
/// </summary>
/// <param name="submodelId">The Submodel's short id</param>
/// <param name="dataElementId">The DataElement's short id</param>
/// <returns></returns>
/// <response code="200">Returns the requested DataElement's value</response>
/// <response code="404">Submodel/DataElement not found</response>
/// <response code="502">Bad Gateway</response>
[HttpGet("submodel/dataElements/{dataElementId}/value", Name = "GetDataElementValue")]
[ProducesResponseType(typeof(IResult<IValue>), 200)]
public IActionResult GetDataElementValue(string submodelId, string dataElementId)
{
var result = RetrieveDataElementValue(dataElementId);
return EvaluateResult(result, CrudOperation.Retrieve);
}
/// <summary>
/// Updates the Asset Administration Shell's Submodel's DataElement
/// </summary>
/// <param name="submodelId">The Submodel's short id</param>
/// <param name="dataElementId">The DataElement's short id</param>
/// <param name="value">The new value</param>
/// <returns></returns>
/// <response code="204">DataElement's value changed successfully</response>
/// <response code="404">Submodel/DataElement not found</response>
/// <response code="502">Bad Gateway</response>
[HttpPut("submodel/dataElements/{dataElementId}/value", Name = "PutDataElementValue")]
[ProducesResponseType(typeof(IResult), 204)]
public IActionResult PutDataElementValue(string submodelId, string dataElementId, [FromBody] IValue value)
{
var result = UpdateDataElementValue(dataElementId, value);
return EvaluateResult(result, CrudOperation.Update);
}
/// <summary>
/// Deletes a specific DataElement from the Asset Administration Shell's Submodel
/// </summary>
/// <param name="submodelId">The Submodel's short id</param>
/// <param name="dataElementId">The DataElement's short id</param>
/// <returns></returns>
/// <response code="204">DataElement deleted successfully</response>
/// <response code="400">Bad Request</response>
/// <response code="404">Submodel not found</response>
/// <response code="502">Bad Gateway</response>
[HttpDelete("submodel/dataElements/{dataElementId}", Name = "DelDataElement")]
[ProducesResponseType(typeof(IResult), 204)]
public IActionResult DelDataElement(string submodelId, string dataElementId)
{
var result = DeleteDataElement(dataElementId);
return EvaluateResult(result, CrudOperation.Delete);
}
#endregion
#region Operation - REST-Calls
/// <summary>
/// Adds a new operation to the Asset Administraiton Shell's Submodel
/// </summary>
/// <param name="submodelId">The Submodel's short id</param>
/// <param name="operation">The operation description object</param>
/// <returns></returns>
/// <response code="201">Operation created successfully</response>
/// <response code="400">Bad Request</response>
/// <response code="404">Submodel not found</response>
/// <response code="502">Bad Gateway</response>
[HttpPost("submodel/operations", Name = "PostOperation")]
[ProducesResponseType(typeof(IResult<IOperation>), 201)]
public IActionResult PostOperation(string submodelId, [FromBody] IOperation operation)
{
var result = CreateOperation(operation);
return EvaluateResult(result, CrudOperation.Create);
}
/// <summary>
/// Retrieves a specific Operation from the Asset Administration Shell's Submodel
/// </summary>
/// <param name="submodelId">The Submodel's short id</param>
/// <param name="operationId">The Operation's short id</param>
/// <returns></returns>
/// <response code="200">Success</response>
/// <response code="404">Submodel/Operation not found</response>
/// <response code="502">Bad Gateway</response>
[HttpGet("submodel/operations/{operationId}", Name = "GetOperation")]
[ProducesResponseType(typeof(IResult<IOperation>), 200)]
public IActionResult GetOperation(string submodelId, string operationId)
{
var result = RetrieveOperation(operationId);
return EvaluateResult(result, CrudOperation.Retrieve);
}
/// <summary>
/// Deletes a specific Operation from the Asset Administration Shell's Submodel
/// </summary>
/// <param name="submodelId">The Submodel's short id</param>
/// <param name="operationId">The Operation's short id</param>
/// <returns></returns>
/// <response code="204">Operation deleted successfully</response>
/// <response code="400">Bad Request</response>
/// <response code="404">Submodel not found</response>
/// <response code="502">Bad Gateway</response>
[HttpDelete("submodel/operations/{operationId}", Name = "DelOperation")]
[ProducesResponseType(typeof(IResult), 204)]
public IActionResult DelOperation(string submodelId, string operationId)
{
var result = DeleteOperation(operationId);
return EvaluateResult(result, CrudOperation.Delete);
}
/// <summary>
/// Invokes a specific operation from the Asset Administration Shell' Submodel with a list of input parameters
/// </summary>
/// <param name="submodelId">The Submodel's short id</param>
/// <param name="operationId">The operation's short id</param>
/// <param name="timeout">Timeout for the operation to finish</param>
/// <param name="inputArguments">List of input arguments</param>
/// <returns></returns>
/// <response code="200">Operation invoked successfully</response>
/// <response code="400">Bad Request</response>
/// <response code="404">Submodel not found</response>
/// <response code="502">Bad Gateway</response>
[HttpPost("submodel/operations/{operationId}", Name = "InvokeOperationRest")]
[ProducesResponseType(typeof(IResult<List<IArgument>>), 200)]
public IActionResult InvokeOperationRest(string submodelId, string operationId, [FromQuery] int timeout, [FromBody] List<IArgument> inputArguments)
{
List<IArgument> outputArguments = new List<IArgument>();
IResult result = InvokeOperation(operationId, inputArguments, outputArguments, timeout);
if (result != null)
{
var objResult = new ObjectResult(new Result<List<IArgument>>(result.Success, outputArguments, result.Messages));
if (result.Success)
objResult.StatusCode = 200;
else if (Utils.ResultHandling.Utils.TryParseStatusCode(result, out int httpStatusCode))
objResult.StatusCode = httpStatusCode;
else
objResult.StatusCode = 502;
return objResult;
}
return StatusCode(502);
}
#endregion
#region Event - REST-Calls
/// <summary>
/// Adds a new event to the Asset Administration Shell's Submodel
/// </summary>
/// <param name="submodelId">The Submodel's short id</param>
/// <param name="eventable">The Event description object</param>
/// <returns></returns>
/// <response code="201">Event created successfully</response>
/// <response code="400">Bad Request</response>
/// <response code="404">Submodel not found</response>
/// <response code="502">Bad Gateway</response>
[HttpPost("submodel/events", Name = "PostEvent")]
[ProducesResponseType(typeof(IResult<IEvent>), 201)]
public IActionResult PostEvent(string submodelId, [FromBody] IEvent eventable)
{
var result = CreateEvent(eventable);
return EvaluateResult(result, CrudOperation.Create);
}
/// <summary>
/// Retrieves a specific event from the Asset Administration Shell's Submodel
/// </summary>
/// <param name="submodelId">The Submodel's short id</param>
/// <param name="eventId">The Event's short id</param>
/// <returns></returns>
/// <response code="200">Success</response>
/// <response code="404">Submodel/Event not found</response>
/// <response code="502">Bad Gateway</response>
[HttpGet("submodel/events/{eventId}", Name = "GetEvent")]
[ProducesResponseType(typeof(IResult<IEvent>), 200)]
public IActionResult GetEvent(string submodelId, string eventId)
{
var result = RetrieveEvent(eventId);
return EvaluateResult(result, CrudOperation.Retrieve);
}
/// <summary>
/// Deletes a specific event from the Asset Administration Shell's Submodel
/// </summary>
/// <param name="submodelId">The Submodel's short id</param>
/// <param name="eventId">The Event's short id</param>
/// <returns></returns>
/// <response code="204">Event deleted successfully</response>
/// <response code="400">Bad Request</response>
/// <response code="404">Submodel not found</response>
/// <response code="502">Bad Gateway</response>
[HttpDelete("submodel/events/{eventId}", Name = "DelEvent")]
[ProducesResponseType(typeof(IResult), 204)]
public IActionResult DelEvent(string submodelId, string eventId)
{
var result = DeleteEvent(eventId);
return EvaluateResult(result, CrudOperation.Delete);
}
#endregion
#endregion
#region Interface Implementation SubmodelServiceProvider
public IResult<IOperation> CreateOperation(IOperation operation)
{
return submodelServiceProvider.CreateOperation(operation);
}
public IResult<ElementContainer<IOperation>> RetrieveOperations()
{
return submodelServiceProvider.RetrieveOperations();
}
public IResult<IOperation> RetrieveOperation(string operationId)
{
return submodelServiceProvider.RetrieveOperation(operationId);
}
public IResult DeleteOperation(string operationId)
{
return submodelServiceProvider.DeleteOperation(operationId);
}
public IResult InvokeOperation(string operationId, List<IArgument> inputArguments, List<IArgument> outputArguments, int timeout)
{
return submodelServiceProvider.InvokeOperation(operationId, inputArguments, outputArguments, timeout);
}
public IResult<IDataElement> CreateDataElement(IDataElement dataElement)
{
return submodelServiceProvider.CreateDataElement(dataElement);
}
public IResult<ElementContainer<IDataElement>> RetrieveDataElements()
{
return submodelServiceProvider.RetrieveDataElements();
}
public IResult<IDataElement> RetrieveDataElement(string dataElementId)
{
return submodelServiceProvider.RetrieveDataElement(dataElementId);
}
public IResult UpdateDataElementValue(string dataElementId, IValue value)
{
return submodelServiceProvider.UpdateDataElementValue(dataElementId, value);
}
public IResult DeleteDataElement(string dataElementId)
{
return submodelServiceProvider.DeleteDataElement(dataElementId);
}
public IResult<IEvent> CreateEvent(IEvent eventable)
{
return submodelServiceProvider.CreateEvent(eventable);
}
public IResult<ElementContainer<IEvent>> RetrieveEvents()
{
return submodelServiceProvider.RetrieveEvents();
}
public IResult<IEvent> RetrieveEvent(string eventId)
{
return submodelServiceProvider.RetrieveEvent(eventId);
}
public IResult ThrowEvent(IPublishableEvent publishableEvent, string topic, Action<IMessagePublishedEventArgs> MessagePublished, byte qosLevel)
{
return submodelServiceProvider.ThrowEvent(publishableEvent, topic, MessagePublished, qosLevel);
}
public IResult DeleteEvent(string eventId)
{
return submodelServiceProvider.DeleteEvent(eventId);
}
public Delegate RetrieveMethodDelegate(string operationId)
{
return submodelServiceProvider.RetrieveMethodDelegate(operationId);
}
public void RegisterMethodCalledHandler(string operationId, Delegate handler)
{
submodelServiceProvider.RegisterMethodCalledHandler(operationId, handler);
}
public void ConfigureEventHandler(IMessageClient messageClient)
{
submodelServiceProvider.ConfigureEventHandler(messageClient);
}
public IResult<IValue> RetrieveDataElementValue(string dataElementId)
{
return submodelServiceProvider.RetrieveDataElementValue(dataElementId);
}
public DataElementHandler RetrieveDataElementHandler(string dataElementId)
{
return submodelServiceProvider.RetrieveDataElementHandler(dataElementId);
}
public void RegisterDataElementHandler(string dataElementId, DataElementHandler handler)
{
submodelServiceProvider.RegisterDataElementHandler(dataElementId, handler);
}
public void SubscribeUpdates(string dataElementId, Action<IValue> updateFunction)
{
submodelServiceProvider.SubscribeUpdates(dataElementId, updateFunction);
}
public void PublishUpdate(string dataElementId, IValue value)
{
submodelServiceProvider.PublishUpdate(dataElementId, value);
}
#endregion
#region Helper Methods
#endregion
}
}