Skip to content

Commit

Permalink
Merge pull request #501 from PHOENIXCONTACT/feature/construct-endpoint
Browse files Browse the repository at this point in the history
Port: Extend construct method for constructor invocations on resources
  • Loading branch information
1nf0rmagician authored Dec 9, 2024
2 parents a790823 + beea8be commit c7a94f8
Showing 1 changed file with 36 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Moryx.Runtime.Modules;
using Moryx.Configuration;
using System.Runtime.Serialization;
using System.ComponentModel.DataAnnotations;

namespace Moryx.AbstractionLayer.Resources.Endpoints
{
Expand All @@ -32,8 +33,8 @@ public class ResourceModificationController : ControllerBase
private readonly IResourceTypeTree _resourceTypeTree;
private readonly ResourceSerialization _serialization;

public ResourceModificationController(IResourceManagement resourceManagement,
IResourceTypeTree resourceTypeTree,
public ResourceModificationController(IResourceManagement resourceManagement,
IResourceTypeTree resourceTypeTree,
IModuleManager moduleManager,
IServiceProvider serviceProvider)
{
Expand Down Expand Up @@ -121,7 +122,7 @@ public ActionResult<Entry> InvokeMethod(long id, string method, Entry parameters
return true;
});
}
catch(MissingMethodException)
catch (MissingMethodException)
{
return BadRequest("Method could not be invoked. Please check spelling and access modifier (has to be `public` or `internal`).");
}
Expand All @@ -142,30 +143,48 @@ public ActionResult<Entry> InvokeMethod(long id, string method, Entry parameters
public ActionResult<ResourceModel> ConstructWithParameters(string type, string method = null, [FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] Entry arguments = null)
{
var trustedType = WebUtility.HtmlEncode(type);

return method == null ? Construct(trustedType, null)
: Construct(trustedType, new MethodEntry { Name = method, Parameters = arguments });
if (method is null)
return Construct(trustedType);
else
return Construct(trustedType, new MethodEntry { Name = method, Parameters = arguments });
}

private ActionResult<ResourceModel> Construct(string type, MethodEntry method)
private ActionResult<ResourceModel> Construct(string type)
{
var resource = (Resource)Activator.CreateInstance(_resourceTypeTree[type].ResourceType);
if (resource is null)
Resource resource;
try
{
resource = (Resource)Activator.CreateInstance(_resourceTypeTree[type].ResourceType);
}
catch (Exception)
{
return NotFound(new MoryxExceptionResponse { Title = Strings.RESOURCE_NOT_FOUND });
}

ValueProviderExecutor.Execute(resource, new ValueProviderExecutorSettings()
.AddFilter(new DataMemberAttributeValueProviderFilter(false))
.AddDefaultValueProvider());

if (method != null)
EntryConvert.InvokeMethod(resource, method, _serialization);

var model = new ResourceToModelConverter(_resourceTypeTree, _serialization).GetDetails(resource);
model.Methods = Array.Empty<MethodEntry>(); // Reset methods because they can not be invoked on new objects

return model;
}

private ActionResult<ResourceModel> Construct(string type, MethodEntry method)
{
try
{
var id = _resourceManagement.Create(_resourceTypeTree[type].ResourceType, r => EntryConvert.InvokeMethod(r, method, _serialization));
return GetDetails(id);
}
catch (Exception e)
{
if (e is ArgumentException or SerializationException or ValidationException)
return BadRequest(e.Message);
throw;
}
}

[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status409Conflict)]
Expand All @@ -185,11 +204,11 @@ public ActionResult<ResourceModel> Save(ResourceModel model)
resourcesToSave.Skip(1).ForEach(id => _resourceManagement.Modify(id, r => true));
});

return Ok(GetDetails(id));
return GetDetails(id);
}
catch (Exception e)
{
if (e is ArgumentException or SerializationException)
if (e is ArgumentException or SerializationException or ValidationException)
return BadRequest(e.Message);
throw;
}
Expand Down Expand Up @@ -323,7 +342,7 @@ private void UpdateReferences(Resource instance, HashSet<long> resourcesToSave,
[Authorize(Policy = ResourcePermissions.CanEdit)]
public ActionResult<ResourceModel> Update(long id, ResourceModel model)
{
if (_resourceManagement.GetAllResources<IResource>(r=>r.Id == id) is null)
if (_resourceManagement.GetAllResources<IResource>(r => r.Id == id) is null)
return NotFound(new MoryxExceptionResponse { Title = string.Format(Strings.ResourceNotFoundException_ById_Message, id) });

try
Expand All @@ -339,7 +358,7 @@ public ActionResult<ResourceModel> Update(long id, ResourceModel model)
}
catch (Exception e)
{
if (e is ArgumentException or SerializationException)
if (e is ArgumentException or SerializationException or ValidationException)
return BadRequest(e.Message);
throw;
}
Expand Down

0 comments on commit c7a94f8

Please sign in to comment.