Commit b1710310 authored by Sylvain Renault's avatar Sylvain Renault
Browse files

Merge branch 'feature/unityWebSocketReg' into 'develop'

Some trst implementation for REST.

See merge request !1
parents f2663162 571913d7
Loading
Loading
Loading
Loading

openapi @ 073fd721

Original line number Diff line number Diff line
Subproject commit 073fd7213fd9e6ebc2f8a47d628a650de30c8bc4
+4 −4
Original line number Diff line number Diff line
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

# Container we use for final publish
FROM mcr.microsoft.com/dotnet/core/aspnet:5.0-buster-slim AS base
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

# Build container
FROM mcr.microsoft.com/dotnet/core/sdk:5.0-buster AS build
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build

# Copy the code into the container
WORKDIR /src
COPY ["src/ETSI.ARF.OpenAPI.WorldAnalysis/ETSI.ARF.OpenAPI.WorldAnalysis.csproj", "ETSI.ARF.OpenAPI.WorldAnalysis/"]
COPY ["ETSI.ARF.OpenAPI.WorldAnalysis.csproj", "ETSI.ARF.OpenAPI.WorldAnalysis/"]

# NuGet restore
RUN dotnet restore "ETSI.ARF.OpenAPI.WorldAnalysis/ETSI.ARF.OpenAPI.WorldAnalysis.csproj"
COPY ["src/ETSI.ARF.OpenAPI.WorldAnalysis/", "ETSI.ARF.OpenAPI.WorldAnalysis/"]
COPY [".", "ETSI.ARF.OpenAPI.WorldAnalysis/"]

# Build the API
WORKDIR "ETSI.ARF.OpenAPI.WorldAnalysis"
+29 −2
Original line number Diff line number Diff line
@@ -53,7 +53,22 @@ namespace ETSI.ARF.OpenAPI.WorldAnalysis.Controllers
        /// </summary>
        public override IActionResult GetCapabilities([FromHeader (Name = "token")]string token, [FromHeader (Name = "sessionID")]string sessionID)
        {
            return StatusCode(405, "Not supported yet!");
            if (!Startup.IsAccessGranted(token)) return StatusCode(511, new Error() { Message = "Invalid token!" });

            // todo: compare sessionID

            // Get all capabilities from all anchors/trackables
            // Info: Capabilities are collected after a module is connected via websockets

            // Create list
            List<Capability> capabilitiesList = new List<Capability>();
            capabilitiesList.AddRange(WorldAnalysisConnections.Singleton.GetCapabilities());

            // Create response object
            GetCapabilities200Response response = new GetCapabilities200Response();
            response.Capabilities = capabilitiesList;
            return new ObjectResult(response);
            //return StatusCode(405, "Not supported yet!");
        }

        /// <summary>
@@ -61,7 +76,19 @@ namespace ETSI.ARF.OpenAPI.WorldAnalysis.Controllers
        /// </summary>
        public override IActionResult GetSupport([FromRoute (Name = "trackableOrAnchorUUID")][Required]Guid trackableOrAnchorUUID, [FromHeader (Name = "token")]string token, [FromHeader (Name = "sessionID")]string sessionID)
        {
            return StatusCode(405, "Not supported yet!");
            if (!Startup.IsAccessGranted(token)) return StatusCode(511, new Error() { Message = "Invalid token!" });

            // todo: compare sessionID

            // Create list
            List<Capability> capabilitiesList = new List<Capability>();
            capabilitiesList.AddRange(WorldAnalysisConnections.Singleton.GetCapabilitiesFromUuid(trackableOrAnchorUUID));

            // Create response object
            GetSupport200Response response = new GetSupport200Response();
            response.Capabilities = capabilitiesList;
            return new ObjectResult(response); 
            //return StatusCode(405, "Not supported yet!");
        }
    }
}
+161 −15
Original line number Diff line number Diff line
@@ -53,7 +53,13 @@ namespace ETSI.ARF.OpenAPI.WorldAnalysis.Controllers
        /// </summary>
        public override IActionResult ConfigureFramerate([FromBody] PoseConfiguration poseConfiguration, [FromHeader(Name = "token")] string token, [FromHeader(Name = "sessionID")] string sessionID)
        {
            return StatusCode(405, "Not supported yet!");
            if (!Startup.IsAccessGranted(token)) return StatusCode(511, new Error() { Message = "Invalid token!" });

            // todo: compare sessionID

            // Notify the modules that the client need a new framerate
            bool result = WorldAnalysisConnections.Singleton.ConfigureFramerate(poseConfiguration);
            return result ? StatusCode(200, "Ok.") : StatusCode(405, "Not supported.");
        }

        /// <summary>
@@ -61,23 +67,82 @@ namespace ETSI.ARF.OpenAPI.WorldAnalysis.Controllers
        /// </summary>
        public override IActionResult GetPose([FromRoute(Name = "trackableOrAnchorUUID")][Required] Guid trackableOrAnchorUUID, [FromQuery(Name = "mode")][Required()] ModeWorldAnalysis mode, [FromHeader(Name = "token")] string token, [FromHeader(Name = "sessionID")] string sessionID)
        {
            return StatusCode(405, "Not supported yet!");
            if (!Startup.IsAccessGranted(token)) return StatusCode(511, new Error() { Message = "Invalid token!" });

            // todo: compare sessionID

            // Request from the modules a new pose of a single UUID
            Pose result;
            result = WorldAnalysisConnections.Singleton.GetPose(trackableOrAnchorUUID, mode);
            return new ObjectResult(result);
        }

        /// <summary>
        /// Request the last pose of a batch of Anchor or Trackable
        /// </summary>
        public override IActionResult GetPoses([FromQuery (Name = "uuid")][Required()]List<GetPosesUuidParameterInner> uuid, [FromHeader (Name = "token")]string token, [FromHeader (Name = "sessionID")]string sessionID)
        public override IActionResult GetPoses([FromQuery(Name = "uuid")][Required()] List<UuidAndMode> uuid, [FromHeader(Name = "token")] string token, [FromHeader(Name = "sessionID")] string sessionID)
        {
            return StatusCode(405, "Not supported yet!");
            if (!Startup.IsAccessGranted(token)) return StatusCode(511, new Error() { Message = "Invalid token!" });

            // todo: compare sessionID

            // Request from the modules new poses from all UUIDs
            GetPoses200Response result = new GetPoses200Response();
            foreach (var item in uuid)
            {
                result.Poses.Add(WorldAnalysisConnections.Singleton.GetPose(item.Uuid, item.Mode));
            }
            return new ObjectResult(result);
        }

#pragma warning disable CS1591 // Fehlendes XML-Kommentar fr ffentlich sichtbaren Typ oder Element

        //
        // Management of subscriptions
        //
        /// <summary>
        /// Dictionnary of susbscription informations for poses, for each item, stored using the UUID of the item (anchor/trackable)
        /// </summary>
        private Dictionary<Guid, SubscriptionInfo> m_subscriptionsPoses = new Dictionary<Guid, SubscriptionInfo>();

        public struct SubscriptionInfo
        {
            public Guid uuidSub;           // id of subscription (id is defined by the WA server)

            public SubscribeToPoseRequest subscription;
            public string webSocket;
            public Pose pose;
            public DateTime timeValidity;

            //public PoseCallback callback;
        }
#pragma warning restore CS1591 // Fehlendes XML-Kommentar fr ffentlich sichtbaren Typ oder Element

        /// <summary>
        /// Get information about a subscription
        /// </summary>
        public override IActionResult GetSubscription([FromRoute(Name = "subscriptionUUID")][Required] Guid subscriptionUUID, [FromHeader(Name = "token")] string token, [FromHeader(Name = "sessionID")] string sessionID)
        {
            return StatusCode(405, "Not supported yet!");
            if (!Startup.IsAccessGranted(token)) return StatusCode(511, new Error() { Message = "Invalid token!" });

            // todo: compare sessionID

            // todo: search for a subscription and send it back
            foreach (var item in m_subscriptionsPoses)
            {
                if (item.Key == subscriptionUUID)
                {
                    SubscriptionSingle response = new SubscriptionSingle();
                    response.Uuid = subscriptionUUID;
                    response.Target = item.Value.subscription.Target;
                    response.Mode = item.Value.pose.Mode;
                    response.Validity = item.Value.timeValidity.Millisecond;
                    response.WebhookUrl = item.Value.subscription.WebhookUrl;
                    response.WebsocketUrl = item.Value.webSocket;
                    return new ObjectResult(response);
                }
            }
            return StatusCode(404, "Not found.");
        }

        /// <summary>
@@ -85,7 +150,68 @@ namespace ETSI.ARF.OpenAPI.WorldAnalysis.Controllers
        /// </summary>
        public override IActionResult SubscribeToPose([FromBody] SubscribeToPoseRequest subscribeToPoseRequest, [FromHeader(Name = "token")] string token, [FromHeader(Name = "sessionID")] string sessionID)
        {
            return StatusCode(405, "Not supported yet!");
            // Simulation ON for STF669 pose calcualtion
            string _token = token;
            Guid parentUUID = Guid.Empty;
            if (token.Contains(","))
            {
                _token = token.Split(',')[0];
                parentUUID = new Guid(token.Split(',')[1]);
            }

            if (!Startup.IsAccessGranted(_token)) return StatusCode(511, new Error() { Message = "Invalid token!" });

            // todo: compare sessionID

            if (subscribeToPoseRequest.Targets != null && subscribeToPoseRequest.Targets.Count > 0)
            {
                return StatusCode(404, "Multiple subscriptions are not implemented (targets).");
            }
            else if (subscribeToPoseRequest.Modes != null && subscribeToPoseRequest.Modes.Count > 0)
            {
                return StatusCode(404, "Multiple subscriptions are not implemented (modes).");
            }

            int validity = subscribeToPoseRequest.Validity; // todo: is to handle here or by the client?

            SubscribeToPose200Response response = new SubscribeToPose200Response();
            response.Validity = validity;
            response.Uuid = Guid.NewGuid();
            response.Target = subscribeToPoseRequest.Target;
            response.Mode = subscribeToPoseRequest.Mode;
            response.WebhookUrl = subscribeToPoseRequest.WebhookUrl;
            response.WebsocketUrl = "";

            // Send the websocket connection URL
            if (string.IsNullOrEmpty(response.WebhookUrl))
            {
                // Notice: starting websocket server is done autom. by the client, when calling "URL:xxx/ws"
                // Registering the client is done in the analysis module, so the websocket can send to it pose updates
                response.WebsocketUrl = "wss://" + Request.Host.ToString() + "/ws";
            }

            // We add the subscription
            SubscriptionInfo info = new SubscriptionInfo();
            info.uuidSub = response.Uuid;
            info.webSocket = response.WebsocketUrl;
            info.timeValidity = DateTime.Now.AddMilliseconds(validity / 1000.0f);

            info.pose = new Pose();
            info.pose.Mode = response.Mode;

            info.subscription = new SubscribeToPoseRequest();
            info.subscription.Target = response.Target;
            info.subscription.Mode = response.Mode;
            info.subscription.Validity = response.Validity;
            info.subscription.WebhookUrl = response.WebhookUrl;

            m_subscriptionsPoses.Add(info.uuidSub, info);
            
            // todo: inform the module(s) that the client will track an anchor/trackable and need the pose
            // todo: has the module to call GetRelocalizationInformation() then?!?
            WorldAnalysisConnections.Singleton.SubscribeToPose(info, parentUUID);

            return new ObjectResult(response);
        }

        /// <summary>
@@ -93,7 +219,21 @@ namespace ETSI.ARF.OpenAPI.WorldAnalysis.Controllers
        /// </summary>
        public override IActionResult UnsubscribeFromPose([FromRoute(Name = "subscriptionUUID")][Required] Guid subscriptionUUID, [FromHeader(Name = "token")] string token, [FromHeader(Name = "sessionID")] string sessionID)
        {
            return StatusCode(405, "Not supported yet!");
            if (!Startup.IsAccessGranted(token)) return StatusCode(511, new Error() { Message = "Invalid token!" });

            // todo: compare sessionID

            // Remove the subscription from the list?
            if (m_subscriptionsPoses.ContainsKey(subscriptionUUID)) m_subscriptionsPoses.Remove(subscriptionUUID);
            else
            {
                //return StatusCode(404, new Error() { Message = "Unsubscribe UUID not found!" });
            }

            // Inform the module(s) that the subscription ended
            WorldAnalysisConnections.Singleton.UnsubscribeFromPose(subscriptionUUID);

            return StatusCode(200, new Success() { Message = "Unsubscription successfull." });
        }

        /// <summary>
@@ -101,6 +241,12 @@ namespace ETSI.ARF.OpenAPI.WorldAnalysis.Controllers
        /// </summary>
        public override IActionResult UpdateSubscription([FromRoute(Name = "subscriptionUUID")][Required] Guid subscriptionUUID, [FromBody] UpdateSubscriptionRequest updateSubscriptionRequest, [FromHeader(Name = "token")] string token, [FromHeader(Name = "sessionID")] string sessionID)
        {
            if (!Startup.IsAccessGranted(token)) return StatusCode(511, new Error() { Message = "Invalid token!" });

            // todo: compare sessionID

            // todo: inform the module(s) that the subscription changed

            return StatusCode(405, "Not supported yet!");
        }
    }
+285 −32

File changed.

Preview size limit exceeded, changes collapsed.

Loading