예제 #1
0
        public async Task <ActionResult> Get(
            [FromRoute] string org,
            [FromRoute] string app,
            [FromRoute] int instanceOwnerPartyId,
            [FromRoute] Guid instanceGuid)
        {
            EnforcementResult enforcementResult = await AuthorizeAction(org, app, instanceOwnerPartyId, instanceGuid, "read");

            if (!enforcementResult.Authorized)
            {
                return(Forbidden(enforcementResult));
            }

            try
            {
                Instance instance = await _instanceService.GetInstance(app, org, instanceOwnerPartyId, instanceGuid);

                SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request);

                string userOrgClaim = User.GetOrg();

                if (userOrgClaim == null || !org.Equals(userOrgClaim, StringComparison.InvariantCultureIgnoreCase))
                {
                    await _instanceService.UpdateReadStatus(instanceOwnerPartyId, instanceGuid, "read");
                }

                return(Ok(instance));
            }
            catch (Exception exception)
            {
                return(ExceptionResponse(exception, $"Get instance {instanceOwnerPartyId}/{instanceGuid} failed"));
            }
        }
        public async Task <ActionResult> Get(
            [FromRoute] string org,
            [FromRoute] string app,
            [FromRoute] int instanceOwnerPartyId,
            [FromRoute] Guid instanceGuid)
        {
            EnforcementResult enforcementResult = await AuthorizeAction(org, app, instanceOwnerPartyId, "read");

            if (!enforcementResult.Authorized)
            {
                if (enforcementResult.FailedObligations != null && enforcementResult.FailedObligations.Count > 0)
                {
                    return(StatusCode((int)HttpStatusCode.Forbidden, enforcementResult.FailedObligations));
                }

                return(StatusCode((int)HttpStatusCode.Forbidden));
            }

            try
            {
                Instance instance = await _instanceService.GetInstance(app, org, instanceOwnerPartyId, instanceGuid);

                SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request);

                return(Ok(instance));
            }
            catch (PlatformHttpException e)
            {
                return(HandlePlatformHttpException(e, $"Get instance {instanceOwnerPartyId}/{instanceGuid} failed"));
            }
            catch (Exception exception)
            {
                return(ExceptionResponse(exception, $"Get instance {instanceOwnerPartyId}/{instanceGuid} failed"));
            }
        }
예제 #3
0
        public async Task <ActionResult> Put(
            [FromRoute] string org,
            [FromRoute] string app,
            [FromRoute] int instanceOwnerPartyId,
            [FromRoute] Guid instanceGuid,
            [FromBody] Instance instance)
        {
            if (instance == null ||
                !org.Equals(instance.Org) ||
                !instance.AppId.EndsWith(app) ||
                !instanceOwnerPartyId.Equals(int.Parse(instance.InstanceOwner.PartyId)) ||
                !instance.Id.EndsWith(instanceGuid.ToString()))
            {
                return(BadRequest($"Inconsistent values between path params and instance attributes"));
            }

            try
            {
                Instance updatedInstance = await _instanceService.UpdateInstance(instance);

                if (updatedInstance == null)
                {
                    return(NotFound());
                }

                SelfLinkHelper.SetInstanceAppSelfLinks(updatedInstance, Request);

                return(Ok(updatedInstance));
            }
            catch (Exception exception)
            {
                return(ExceptionResponse(exception, $"Update of instance {instanceOwnerPartyId}/{instanceGuid} failed."));
            }
        }
예제 #4
0
        public async Task <ActionResult <Instance> > UpdateSubstatus(
            [FromRoute] string org,
            [FromRoute] string app,
            [FromRoute] int instanceOwnerPartyId,
            [FromRoute] Guid instanceGuid,
            [FromBody] Substatus substatus)
        {
            if (substatus == null || string.IsNullOrEmpty(substatus.Label))
            {
                return(BadRequest($"Invalid sub status: {JsonConvert.SerializeObject(substatus)}. Substatus must be defined and include a label."));
            }

            Instance instance = await _instanceService.GetInstance(app, org, instanceOwnerPartyId, instanceGuid);

            string orgClaim = User.GetOrg();

            if (!instance.Org.Equals(orgClaim))
            {
                return(Forbid());
            }

            try
            {
                Instance updatedInstance = await _instanceService.UpdateSubstatus(instanceOwnerPartyId, instanceGuid, substatus);

                SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request);

                return(Ok(updatedInstance));
            }
            catch (Exception exception)
            {
                return(ExceptionResponse(exception, $"Updating substatus for instance {instanceOwnerPartyId}/{instanceGuid} failed."));
            }
        }
예제 #5
0
        private async Task <ActionResult> PutBinaryData(string org, string app, int instanceOwnerPartyId, Guid instanceGuid, Guid dataGuid)
        {
            DataElement dataElement = await _dataService.UpdateBinaryData(org, app, instanceOwnerPartyId, instanceGuid, dataGuid, Request);

            SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, dataElement, Request);

            return(Created(dataElement.SelfLinks.Apps, dataElement));
        }
예제 #6
0
        private async Task<ActionResult> PutFormData(string org, string app, Instance instance, Guid dataGuid, string dataType)
        {
            string classRef = _appResourcesService.GetClassRefForLogicDataType(dataType);
            Guid instanceGuid = Guid.Parse(instance.Id.Split("/")[1]);
            
            ModelDeserializer deserializer = new ModelDeserializer(_logger, _altinnApp.GetAppModelType(classRef));
            object serviceModel = await deserializer.DeserializeAsync(Request.Body, Request.ContentType);

            if (!string.IsNullOrEmpty(deserializer.Error))
            {
                return BadRequest(deserializer.Error);
            }

            if (serviceModel == null)
            {
                return BadRequest("No data found in content");
            }

            string serviceModelJsonString = JsonSerializer.Serialize(serviceModel);

            // Trigger application business logic
            bool changedByCalculation = await _altinnApp.RunCalculation(serviceModel);

            int instanceOwnerPartyId = int.Parse(instance.InstanceOwner.PartyId);

            // Save Formdata to database
            DataElement updatedDataElement = await _dataService.UpdateData(
                serviceModel,
                instanceGuid,
                _altinnApp.GetAppModelType(classRef),
                org,
                app,
                instanceOwnerPartyId,
                dataGuid);

            SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, updatedDataElement, Request);

            string dataUrl = updatedDataElement.SelfLinks.Apps;

            if (changedByCalculation)
            {
                string updatedServiceModelString = JsonSerializer.Serialize(serviceModel);
                CalculationResult calculationResult = new CalculationResult(updatedDataElement);
                try
                {
                    Dictionary<string, object> changedFields = JsonHelper.FindChangedFields(serviceModelJsonString, updatedServiceModelString);
                    calculationResult.ChangedFields = changedFields;
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "Unable to determine changed fields");
                }
                
                return StatusCode((int)HttpStatusCode.SeeOther, calculationResult);
            }

            return Created(dataUrl, updatedDataElement);
        }
예제 #7
0
        private async Task <ActionResult> CreateAppModelData(
            string org,
            string app,
            Instance instance,
            string dataType)
        {
            Guid instanceGuid = Guid.Parse(instance.Id.Split("/")[1]);

            object appModel;

            string classRef = _appResourcesService.GetClassRefForLogicDataType(dataType);

            if (Request.ContentType == null)
            {
                appModel = _altinnApp.CreateNewAppModel(classRef);
            }
            else
            {
                ModelDeserializer deserializer = new ModelDeserializer(_logger, _altinnApp.GetAppModelType(classRef));
                appModel = await deserializer.DeserializeAsync(Request.Body, Request.ContentType);

                if (!string.IsNullOrEmpty(deserializer.Error))
                {
                    return(BadRequest(deserializer.Error));
                }
            }

            // runs prefill from repo configuration if config exists
            await _prefillService.PrefillDataModel(instance.InstanceOwner.PartyId, dataType, appModel);

            // send events to trigger application business logic
            await _altinnApp.RunDataCreation(instance, appModel);

            Dictionary <string, string> updatedValues =
                DataHelper.GetUpdatedDataValues(
                    _appResourcesService.GetApplication().PresentationFields,
                    instance.PresentationTexts,
                    dataType,
                    appModel);

            if (updatedValues.Count > 0)
            {
                await _instanceService.UpdatePresentationTexts(
                    int.Parse(instance.InstanceOwner.PartyId),
                    Guid.Parse(instance.Id.Split("/")[1]),
                    new PresentationTexts { Texts = updatedValues });
            }

            int instanceOwnerPartyId = int.Parse(instance.InstanceOwner.PartyId);

            DataElement dataElement = await _dataService.InsertFormData(appModel, instanceGuid, _altinnApp.GetAppModelType(classRef), org, app, instanceOwnerPartyId, dataType);

            SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, dataElement, Request);

            return(Created(dataElement.SelfLinks.Apps, dataElement));
        }
예제 #8
0
        private async Task <ActionResult> PutBinaryData(string org, string app, int instanceOwnerPartyId, Guid instanceGuid, Guid dataGuid)
        {
            DataElement dataElement = await _dataService.UpdateBinaryData(org, app, instanceOwnerPartyId, instanceGuid, dataGuid, Request);

            if (dataElement.Locked)
            {
                return(Conflict($"Data element {dataGuid} is locked and cannot be updated"));
            }

            SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, dataElement, Request);

            return(Created(dataElement.SelfLinks.Apps, dataElement));
        }
예제 #9
0
        private async Task <ActionResult> CreateBinaryData(string org, string app, Instance instanceBefore, string dataType)
        {
            int  instanceOwnerPartyId = int.Parse(instanceBefore.Id.Split("/")[0]);
            Guid instanceGuid         = Guid.Parse(instanceBefore.Id.Split("/")[1]);

            DataElement dataElement = await _dataService.InsertBinaryData(org, app, instanceOwnerPartyId, instanceGuid, dataType, Request);

            if (Guid.Parse(dataElement.Id) == Guid.Empty)
            {
                return(StatusCode(500, $"Cannot store form attachment on instance {instanceOwnerPartyId}/{instanceGuid}"));
            }

            SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, dataElement, Request);
            return(Created(dataElement.SelfLinks.Apps, dataElement));
        }
예제 #10
0
        public async Task <ActionResult <Instance> > AddCompleteConfirmation(
            [FromRoute] int instanceOwnerPartyId,
            [FromRoute] Guid instanceGuid)
        {
            try
            {
                Instance instance = await _instanceService.AddCompleteConfirmation(instanceOwnerPartyId, instanceGuid);

                SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request);

                return(Ok(instance));
            }
            catch (Exception exception)
            {
                return(ExceptionResponse(exception, $"Adding complete confirmation to instance {instanceOwnerPartyId}/{instanceGuid} failed"));
            }
        }
예제 #11
0
        private async Task <ActionResult> PutFormData(string org, string app, Instance instance, Guid dataGuid, string dataType)
        {
            string classRef     = _appResourcesService.GetClassRefForLogicDataType(dataType);
            Guid   instanceGuid = Guid.Parse(instance.Id.Split("/")[1]);


            ModelDeserializer deserializer = new ModelDeserializer(_logger, _altinnApp.GetAppModelType(classRef));
            object            serviceModel = await deserializer.DeserializeAsync(Request.Body, Request.ContentType);

            if (!string.IsNullOrEmpty(deserializer.Error))
            {
                return(BadRequest(deserializer.Error));
            }

            if (serviceModel == null)
            {
                return(BadRequest("No data found in content"));
            }

            // Trigger application business logic
            bool changedByCalculation = await _altinnApp.RunCalculation(serviceModel);

            int instanceOwnerPartyId = int.Parse(instance.InstanceOwner.PartyId);

            // Save Formdata to database
            DataElement updatedDataElement = await _dataService.UpdateData(
                serviceModel,
                instanceGuid,
                _altinnApp.GetAppModelType(classRef),
                org,
                app,
                instanceOwnerPartyId,
                dataGuid);

            SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, updatedDataElement, Request);

            string dataUrl = updatedDataElement.SelfLinks.Apps;

            if (changedByCalculation)
            {
                return(StatusCode((int)HttpStatusCode.SeeOther, updatedDataElement));
            }

            return(Created(dataUrl, updatedDataElement));
        }
예제 #12
0
        public async Task <ActionResult <Instance> > DeleteInstance(
            [FromRoute] int instanceOwnerPartyId,
            [FromRoute] Guid instanceGuid,
            [FromQuery] bool hard)
        {
            try
            {
                Instance deletedInstance = await _instanceService.DeleteInstance(instanceOwnerPartyId, instanceGuid, hard);

                SelfLinkHelper.SetInstanceAppSelfLinks(deletedInstance, Request);

                return(Ok(deletedInstance));
            }
            catch (Exception exception)
            {
                return(ExceptionResponse(exception, $"Deleting instance {instanceOwnerPartyId}/{instanceGuid} failed."));
            }
        }
예제 #13
0
        private async Task <ActionResult> PutFormData(string org, string app, Instance instance, Guid dataGuid, string dataType)
        {
            string classRef     = _appResourcesService.GetClassRefForLogicDataType(dataType);
            Guid   instanceGuid = Guid.Parse(instance.Id.Split("/")[1]);

            object serviceModel = ParseContentAndDeserializeServiceModel(_altinnApp.GetAppModelType(classRef), out ActionResult contentError);

            if (contentError != null)
            {
                return(contentError);
            }

            if (serviceModel == null)
            {
                return(BadRequest("No data found in content"));
            }

            // send events to trigger application business logic
            await _altinnApp.RunAppEvent(AppEventType.DataRetrieval, serviceModel);

            await _altinnApp.RunAppEvent(AppEventType.Calculation, serviceModel);


            int instanceOwnerPartyId = int.Parse(instance.InstanceOwner.PartyId);

            // Save Formdata to database
            DataElement updatedDataElement = await _dataService.UpdateData(
                serviceModel,
                instanceGuid,
                _altinnApp.GetAppModelType(classRef),
                org,
                app,
                instanceOwnerPartyId,
                dataGuid);

            SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, updatedDataElement, Request);

            string dataUrl = updatedDataElement.SelfLinks.Apps;

            return(Created(dataUrl, updatedDataElement));
        }
예제 #14
0
        private async Task <ActionResult> CreateAppModelData(
            string org,
            string app,
            Instance instance,
            string dataType)
        {
            Guid instanceGuid = Guid.Parse(instance.Id.Split("/")[1]);

            object appModel;


            string classRef = _appResourcesService.GetClassRefForLogicDataType(dataType);

            if (Request.ContentType == null)
            {
                appModel = _altinnApp.CreateNewAppModel(classRef);
            }
            else
            {
                appModel = ParseContentAndDeserializeServiceModel(_altinnApp.GetAppModelType(classRef), out ActionResult contentError);
                if (contentError != null)
                {
                    return(contentError);
                }
            }

            // send events to trigger application business logic
            await _altinnApp.RunAppEvent(AppEventType.AppModelCreation, appModel);

            int instanceOwnerPartyId = int.Parse(instance.InstanceOwner.PartyId);

            DataElement dataElement = await _dataService.InsertFormData(appModel, instanceGuid, _altinnApp.GetAppModelType(classRef), org, app, instanceOwnerPartyId, dataType);

            SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, dataElement, Request);

            return(Created(dataElement.SelfLinks.Apps, dataElement));
        }
예제 #15
0
        public async Task <ActionResult> Get(
            [FromRoute] string org,
            [FromRoute] string app,
            [FromRoute] int instanceOwnerPartyId,
            [FromRoute] Guid instanceGuid)
        {
            try
            {
                Instance instance = await _instanceService.GetInstance(app, org, instanceOwnerPartyId, instanceGuid);

                if (instance == null)
                {
                    return(NotFound());
                }

                SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request);

                return(Ok(instance));
            }
            catch (Exception exception)
            {
                return(ExceptionResponse(exception, $"Get instance {instanceOwnerPartyId}/{instanceGuid} failed"));
            }
        }
예제 #16
0
        public async Task <ActionResult> Get(
            [FromRoute] string org,
            [FromRoute] string app,
            [FromRoute] int instanceOwnerPartyId,
            [FromRoute] Guid instanceGuid)
        {
            try
            {
                Instance instance = await _instanceService.GetInstance(app, org, instanceOwnerPartyId, instanceGuid);

                if (instance == null)
                {
                    return(NotFound());
                }

                SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request);

                return(Ok(instance));
            }
            catch (Exception ex)
            {
                return(StatusCode(500, $"{ex.Message}"));
            }
        }
        public async Task <ActionResult <Instance> > Post(
            [FromRoute] string org,
            [FromRoute] string app,
            [FromQuery] int?instanceOwnerPartyId)
        {
            if (string.IsNullOrEmpty(org))
            {
                return(BadRequest("The path parameter 'org' cannot be empty"));
            }

            if (string.IsNullOrEmpty(app))
            {
                return(BadRequest("The path parameter 'app' cannot be empty"));
            }

            Application application = _appResourcesService.GetApplication();

            if (application == null)
            {
                return(NotFound($"AppId {org}/{app} was not found"));
            }

            MultipartRequestReader parsedRequest = new MultipartRequestReader(Request);
            await parsedRequest.Read();

            if (parsedRequest.Errors.Any())
            {
                return(BadRequest($"Error when reading content: {JsonConvert.SerializeObject(parsedRequest.Errors)}"));
            }

            Instance instanceTemplate = await ExtractInstanceTemplate(parsedRequest);

            if (!instanceOwnerPartyId.HasValue && instanceTemplate == null)
            {
                return(BadRequest("Cannot create an instance without an instanceOwner.partyId. Either provide instanceOwner party Id as a query parameter or an instanceTemplate object in the body."));
            }

            if (instanceOwnerPartyId.HasValue && instanceTemplate?.InstanceOwner?.PartyId != null)
            {
                return(BadRequest("You cannot provide an instanceOwnerPartyId as a query param as well as an instance template in the body. Choose one or the other."));
            }

            RequestPartValidator requestValidator = new RequestPartValidator(application);

            string multipartError = requestValidator.ValidateParts(parsedRequest.Parts);

            if (!string.IsNullOrEmpty(multipartError))
            {
                return(BadRequest($"Error when comparing content to application metadata: {multipartError}"));
            }

            if (instanceTemplate != null)
            {
                InstanceOwner lookup = instanceTemplate.InstanceOwner;

                if (lookup == null || lookup.PersonNumber == null && lookup.OrganisationNumber == null && lookup.PartyId == null)
                {
                    return(BadRequest("Error: instanceOwnerPartyId query parameter is empty and InstanceOwner is missing from instance template. You must populate instanceOwnerPartyId or InstanceOwner"));
                }
            }
            else
            {
                // create minimum instance template
                instanceTemplate = new Instance
                {
                    InstanceOwner = new InstanceOwner {
                        PartyId = instanceOwnerPartyId.Value.ToString()
                    }
                };
            }

            Party party;

            try
            {
                party = await LookupParty(instanceTemplate);
            }
            catch (Exception partyLookupException)
            {
                return(NotFound($"Cannot lookup party: {partyLookupException.Message}"));
            }

            EnforcementResult enforcementResult = await AuthorizeAction(org, app, party.PartyId, "instantiate");

            if (!enforcementResult.Authorized)
            {
                if (enforcementResult.FailedObligations != null && enforcementResult.FailedObligations.Count > 0)
                {
                    return(StatusCode((int)HttpStatusCode.Forbidden, enforcementResult.FailedObligations));
                }

                return(StatusCode((int)HttpStatusCode.Forbidden));
            }

            if (!InstantiationHelper.IsPartyAllowedToInstantiate(party, application.PartyTypesAllowed))
            {
                return(StatusCode((int)HttpStatusCode.Forbidden, $"Party {party.PartyId} is not allowed to instantiate this application {org}/{app}"));
            }

            // Run custom app logic to validate instantiation
            InstantiationValidationResult validationResult = await _altinnApp.RunInstantiationValidation(instanceTemplate);

            if (validationResult != null && !validationResult.Valid)
            {
                return(StatusCode((int)HttpStatusCode.Forbidden, validationResult));
            }

            Instance           instance;
            ProcessStateChange processResult;

            try
            {
                // start process and goto next task
                instanceTemplate.Process = null;
                string startEvent = await _altinnApp.OnInstantiateGetStartEvent();

                processResult = _processService.ProcessStartAndGotoNextTask(instanceTemplate, startEvent, User);

                // create the instance
                instance = await _instanceService.CreateInstance(org, app, instanceTemplate);
            }
            catch (Exception exception)
            {
                return(ExceptionResponse(exception, $"Instantiation of appId {org}/{app} failed for party {instanceTemplate.InstanceOwner?.PartyId}"));
            }

            try
            {
                await StorePrefillParts(instance, application, parsedRequest.Parts);

                // get the updated instance
                instance = await _instanceService.GetInstance(app, org, int.Parse(instance.InstanceOwner.PartyId), Guid.Parse(instance.Id.Split("/")[1]));

                // notify app and store events
                await ProcessController.NotifyAppAboutEvents(_altinnApp, instance, processResult.Events);

                await _processService.DispatchProcessEventsToStorage(instance, processResult.Events);
            }
            catch (Exception exception)
            {
                return(ExceptionResponse(exception, $"Instantiation of data elements failed for instance {instance.Id} for party {instanceTemplate.InstanceOwner?.PartyId}"));
            }

            SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request);
            string url = instance.SelfLinks.Apps;

            return(Created(url, instance));
        }
예제 #18
0
        public async Task <ActionResult <Instance> > Post(
            [FromRoute] string org,
            [FromRoute] string app,
            [FromQuery] int?instanceOwnerPartyId)
        {
            if (string.IsNullOrEmpty(org))
            {
                return(BadRequest("The path parameter 'org' cannot be empty"));
            }

            if (string.IsNullOrEmpty(app))
            {
                return(BadRequest("The path parameter 'app' cannot be empty"));
            }

            Application application = _appResourcesService.GetApplication();

            if (application == null)
            {
                return(NotFound($"AppId {org}/{app} was not found"));
            }

            MultipartRequestReader parsedRequest = new MultipartRequestReader(Request);
            await parsedRequest.Read();

            if (parsedRequest.Errors.Any())
            {
                return(BadRequest($"Error when reading content: {JsonConvert.SerializeObject(parsedRequest.Errors)}"));
            }

            Instance instanceTemplate = ExtractInstanceTemplate(parsedRequest);

            if (!instanceOwnerPartyId.HasValue && instanceTemplate == null)
            {
                return(BadRequest("Cannot create an instance without an instanceOwner.partyId. Either provide instanceOwner party Id as a query parameter or an instanceTemplate object in the body."));
            }

            if (instanceOwnerPartyId.HasValue && instanceTemplate?.InstanceOwner?.PartyId != null)
            {
                return(BadRequest("You cannot provide an instanceOwnerPartyId as a query param as well as an instance template in the body. Choose one or the other."));
            }

            RequestPartValidator requestValidator = new RequestPartValidator(application);

            string multipartError = requestValidator.ValidateParts(parsedRequest.Parts);

            if (!string.IsNullOrEmpty(multipartError))
            {
                return(BadRequest($"Error when comparing content to application metadata: {multipartError}"));
            }

            // extract or create instance template
            if (instanceTemplate != null)
            {
                InstanceOwner lookup = instanceTemplate.InstanceOwner;

                if (string.IsNullOrEmpty(instanceTemplate.InstanceOwner.PartyId) && (lookup == null || (lookup.PersonNumber == null && lookup.OrganisationNumber == null)))
                {
                    return(BadRequest($"Error: instanceOwnerPartyId query parameter is empty and InstanceOwner is missing from instance template. You must populate instanceOwnerPartyId or InstanceOwner"));
                }
            }
            else
            {
                instanceTemplate = new Instance
                {
                    InstanceOwner = new InstanceOwner {
                        PartyId = instanceOwnerPartyId.Value.ToString()
                    }
                };
            }

            Party party;

            try
            {
                party = await LookupParty(instanceTemplate);
            }
            catch (Exception partyLookupException)
            {
                return(NotFound($"Cannot lookup party: {partyLookupException.Message}"));
            }

            XacmlJsonRequestRoot request = DecisionHelper.CreateXacmlJsonRequest(org, app, HttpContext.User, "instantiate", party.PartyId.ToString(), null);
            bool authorized = await _pdp.GetDecisionForUnvalidateRequest(request, HttpContext.User);

            if (!authorized)
            {
                return(Forbid());
            }

            if (!InstantiationHelper.IsPartyAllowedToInstantiate(party, application.PartyTypesAllowed))
            {
                return(Forbid($"Party {party?.PartyId} is not allowed to instantiate this application {org}/{app}"));
            }

            // use process controller to start process
            instanceTemplate.Process = null;

            Instance instance;

            try
            {
                instance = await _instanceService.CreateInstance(org, app, instanceTemplate);

                if (instance == null)
                {
                    throw new PlatformClientException("Failure instantiating instance. UnknownError");
                }
            }
            catch (Exception instanceException)
            {
                string message = $"Failure in multipart prefil. Could not create an instance of {org}/{app} for party {instanceTemplate.InstanceOwner.PartyId}.";

                _logger.LogError($"{message} - {instanceException}");
                return(StatusCode(500, $"{message} - {instanceException.Message}"));
            }

            try
            {
                await StorePrefillParts(instance, application, parsedRequest.Parts);

                // get the updated instance
                instance = await _instanceService.GetInstance(app, org, int.Parse(instance.InstanceOwner.PartyId), Guid.Parse(instance.Id.Split("/")[1]));

                Instance instanceWithStartedProcess = await StartProcessAndGotoNextTask(instance);

                if (instanceWithStartedProcess != null)
                {
                    instance = instanceWithStartedProcess;
                }
                else
                {
                    return(Conflict($"Unable to start and move process to next task for instance {instance.Id}"));
                }
            }
            catch (Exception dataException)
            {
                string message = $"Failure storing multipart prefil data. Could not create a data element for {instance.Id} of {org}/{app}.";
                _logger.LogError($"{message} - {dataException}");

                // todo add compensating transaction (delete instance)
                return(StatusCode(500, $"{message} Exception: {dataException.Message}"));
            }

            SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request);
            string url = instance.SelfLinks.Apps;

            return(Created(url, instance));
        }