I'm using Symfony 4, ApiPlatform 1 and VichUploaderBundle 1.
Did everything as stated in docs but got error: Cannot validate values of type \"NULL\" automatically. Please provide a constraint.
I even don't understand how to debug it – error and backtrace are so useless. Where start searching? Help, please.
My Image entity:
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* #ORM\Entity(repositoryClass="App\Repository\ImageRepository")
* #ApiResource(iri="http://schema.org/MediaObject")
* #Vich\Uploadable
*/
class Image
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
* #Groups({"user"})
*/
private $id;
/**
* #var File|null
* #Assert\NotNull()
* #Vich\UploadableField(mapping="image", fileNameProperty="contentUrl")
*/
public $file;
/**
* #var string|null
* #ORM\Column(nullable=true)
* #ApiProperty(iri="http://schema.org/contentUrl")
* #Groups({"user"})
*/
private $contentUrl;
public function getId(): ?int { return $this->id; }
public function getContentUrl(): ?string { return $this->contentUrl; }
public function setContentUrl(string $contentUrl): void { $this->contentUrl = $contentUrl; }
}
Route yaml configuration:
app_image_upload:
methods : ['POST']
path : '/images'
defaults:
_controller : App\Controller\CreateImageAction
_api_resource_class: App\Entity\Image
_api_receive : false
Custom operation for it:
<?php
namespace App\Controller;
use ApiPlatform\Core\Bridge\Symfony\Validator\Exception\ValidationException;
use App\Entity\Image;
use App\Form\ImageType;
use Symfony\Bridge\Doctrine\RegistryInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Vich\UploaderBundle\Templating\Helper\UploaderHelper;
final class CreateImageAction
{
private $validator;
private $doctrine;
private $factory;
private $uploader;
public function __construct(
RegistryInterface $doctrine,
FormFactoryInterface $factory,
ValidatorInterface $validator,
UploaderHelper $uploader
) {
$this->validator = $validator;
$this->doctrine = $doctrine;
$this->factory = $factory;
$this->uploader = $uploader;
}
public function __invoke(Request $request): Image
{
$image = new Image();
$form = $this->factory->create(ImageType::class, $image);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->doctrine->getManager();
$em->persist($image);
$em->flush();
$image->setContentUrl($this->uploader->asset($image, 'file'));
$em->merge($image);
$em->flush();
// Prevent the serialization of the file property
$image->file = null;
return $image;
}
// This will be handled by API Platform and returns a validation error.
throw new ValidationException($this->validator->validate($image));
}
}
And form:
<?php
namespace App\Form;
use App\Entity\Image;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
final class ImageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('file', FileType::class, [
'label' => 'label.file',
'required' => false,
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Image::class,
'csrf_protection' => false,
]);
}
public function getBlockPrefix(): string
{
return '';
}
}
My request looks like this:
$ http -v --form 'api.example.com/api/images' #image.png
POST /api/images HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Authorization: Bearer [API_TOKEN]
Connection: keep-alive
Content-Length: 48888
Content-Type: multipart/form-data; boundary=aedf69840efb693f8ef3f566bc1be656
Host: api.example.com
User-Agent: HTTPie/1.0.2
+-----------------------------------------+
| NOTE: binary data not shown in terminal |
+-----------------------------------------+
And response:
HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache, private
Connection: keep-alive
Content-Type: application/ld+json; charset=utf-8
Date: Sat, 29 Dec 2018 04:10:27 GMT
Link: <http://api.example.com/api/docs.jsonld>; rel="http://www.w3.org/ns/hydra/core#apiDocumentation"
Transfer-Encoding: chunked
X-Content-Type-Options: nosniff
X-Frame-Options: deny
{
"#context": "/api/contexts/Error",
"#type": "hydra:Error",
"hydra:description": "Cannot validate values of type \"NULL\" automatically. Please provide a constraint.",
"hydra:title": "An error occurred",
"trace": [
{
"args": [],
"class": "",
"file": "/Users/SOMEUSER/Projects/MYPROJECT/www/vendor/symfony/validator/Validator/RecursiveContextualValidator.php",
"function": "",
"line": 166,
"namespace": "",
"short_class": "",
"type": ""
},
{
"args": [
[
"null",
null
],
[
"null",
null
],
[
"array",
[
[
"string",
"Default"
]
]
]
],
"class": "Symfony\\Component\\Validator\\Validator\\RecursiveContextualValidator",
"file": "/Users/SOMEUSER/Projects/MYPROJECT/www/vendor/symfony/validator/Validator/RecursiveValidator.php",
"function": "validate",
"line": 100,
"namespace": "Symfony\\Component\\Validator\\Validator",
"short_class": "RecursiveContextualValidator",
"type": "->"
},
{
"args": [
[
"null",
null
],
[
"null",
null
],
[
"null",
null
]
],
"class": "Symfony\\Component\\Validator\\Validator\\RecursiveValidator",
"file": "/Users/SOMEUSER/Projects/MYPROJECT/www/vendor/symfony/validator/Validator/TraceableValidator.php",
"function": "validate",
"line": 66,
"namespace": "Symfony\\Component\\Validator\\Validator",
"short_class": "RecursiveValidator",
"type": "->"
},
{
"args": [
[
"null",
null
],
[
"null",
null
],
[
"null",
null
]
],
"class": "Symfony\\Component\\Validator\\Validator\\TraceableValidator",
"file": "/Users/SOMEUSER/Projects/MYPROJECT/www/vendor/api-platform/core/src/Bridge/Symfony/Validator/Validator.php",
"function": "validate",
"line": 61,
"namespace": "Symfony\\Component\\Validator\\Validator",
"short_class": "TraceableValidator",
"type": "->"
},
{
"args": [
[
"null",
null
],
[
"array",
{
"groups": [
"null",
null
]
}
]
],
"class": "ApiPlatform\\Core\\Bridge\\Symfony\\Validator\\Validator",
"file": "/Users/SOMEUSER/Projects/MYPROJECT/www/vendor/api-platform/core/src/Validator/EventListener/ValidateListener.php",
"function": "validate",
"line": 59,
"namespace": "ApiPlatform\\Core\\Bridge\\Symfony\\Validator",
"short_class": "Validator",
"type": "->"
},
{
"args": [
[
"object",
"Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent"
],
[
"string",
"kernel.view"
],
[
"object",
"Symfony\\Component\\HttpKernel\\Debug\\TraceableEventDispatcher"
]
],
"class": "ApiPlatform\\Core\\Validator\\EventListener\\ValidateListener",
"file": "/Users/SOMEUSER/Projects/MYPROJECT/www/vendor/symfony/event-dispatcher/Debug/WrappedListener.php",
"function": "onKernelView",
"line": 111,
"namespace": "ApiPlatform\\Core\\Validator\\EventListener",
"short_class": "ValidateListener",
"type": "->"
},
{
"args": [
[
"object",
"Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent"
],
[
"string",
"kernel.view"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\EventDispatcher"
]
],
"class": "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener",
"file": "/Users/SOMEUSER/Projects/MYPROJECT/www/vendor/symfony/event-dispatcher/EventDispatcher.php",
"function": "__invoke",
"line": 212,
"namespace": "Symfony\\Component\\EventDispatcher\\Debug",
"short_class": "WrappedListener",
"type": "->"
},
{
"args": [
[
"array",
[
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
]
]
],
[
"string",
"kernel.view"
],
[
"object",
"Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent"
]
],
"class": "Symfony\\Component\\EventDispatcher\\EventDispatcher",
"file": "/Users/SOMEUSER/Projects/MYPROJECT/www/vendor/symfony/event-dispatcher/EventDispatcher.php",
"function": "doDispatch",
"line": 44,
"namespace": "Symfony\\Component\\EventDispatcher",
"short_class": "EventDispatcher",
"type": "->"
},
{
"args": [
[
"string",
"kernel.view"
],
[
"object",
"Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent"
]
],
"class": "Symfony\\Component\\EventDispatcher\\EventDispatcher",
"file": "/Users/SOMEUSER/Projects/MYPROJECT/www/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php",
"function": "dispatch",
"line": 142,
"namespace": "Symfony\\Component\\EventDispatcher",
"short_class": "EventDispatcher",
"type": "->"
},
{
"args": [
[
"string",
"kernel.view"
],
[
"object",
"Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent"
]
],
"class": "Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher",
"file": "/Users/SOMEUSER/Projects/MYPROJECT/www/vendor/symfony/http-kernel/HttpKernel.php",
"function": "dispatch",
"line": 155,
"namespace": "Symfony\\Component\\EventDispatcher\\Debug",
"short_class": "TraceableEventDispatcher",
"type": "->"
},
{
"args": [
[
"object",
"Symfony\\Component\\HttpFoundation\\Request"
],
[
"integer",
1
]
],
"class": "Symfony\\Component\\HttpKernel\\HttpKernel",
"file": "/Users/SOMEUSER/Projects/MYPROJECT/www/vendor/symfony/http-kernel/HttpKernel.php",
"function": "handleRaw",
"line": 67,
"namespace": "Symfony\\Component\\HttpKernel",
"short_class": "HttpKernel",
"type": "->"
},
{
"args": [
[
"object",
"Symfony\\Component\\HttpFoundation\\Request"
],
[
"integer",
1
],
[
"boolean",
true
]
],
"class": "Symfony\\Component\\HttpKernel\\HttpKernel",
"file": "/Users/SOMEUSER/Projects/MYPROJECT/www/vendor/symfony/http-kernel/Kernel.php",
"function": "handle",
"line": 198,
"namespace": "Symfony\\Component\\HttpKernel",
"short_class": "HttpKernel",
"type": "->"
},
{
"args": [
[
"object",
"Symfony\\Component\\HttpFoundation\\Request"
]
],
"class": "Symfony\\Component\\HttpKernel\\Kernel",
"file": "/Users/SOMEUSER/Projects/MYPROJECT/www/public/index.php",
"function": "handle",
"line": 37,
"namespace": "Symfony\\Component\\HttpKernel",
"short_class": "Kernel",
"type": "->"
}
]
}
UPD: MWE on GitHub
by following the docs more accurately, everything works fine: you just forgot the proper #ApiResource annotation and a use statement in Image.php
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Serializer\Annotation\Groups;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use App\Controller\CreateImageAction;
/**
* #ORM\Entity(repositoryClass="App\Repository\ImageRepository")
* #ApiResource(iri="http://schema.org/MediaObject", collectionOperations={
* "get",
* "post"={
* "method"="POST",
* "path"="/images",
* "controller"=CreateImageAction::class,
* "defaults"={"_api_receive"=false},
* },
* })
* #Vich\Uploadable
*/
class Image
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
* #Groups({"user"})
*/
private $id;
/**
* #var File|null
* #Vich\UploadableField(mapping="image", fileNameProperty="contentUrl")
*/
public $file;
/**
* #var string|null
* #ORM\Column(nullable=true)
* #ApiProperty(iri="http://schema.org/contentUrl")
* #Groups({"user"})
*/
private $contentUrl;
public function getId(): ?int { return $this->id; }
public function getContentUrl(): ?string { return $this->contentUrl; }
public function setContentUrl(?string $contentUrl = null): void { $this->contentUrl = $contentUrl; }
}
Related
I'm trying to update an Frontdoor WAF policy by API following the article in the link below but I'm running into several issues.
-Article seems to be focused on Frontdoor Classic, not premium, so the json in the article doesn't work.
-Adding an empty tags value solves the tags error.
https://learn.microsoft.com/en-us/rest/api/frontdoorservice/webapplicationfirewall/policies/create-or-update?tabs=HTTP#skuname
Can't get anywhere with MS Support, hoping anyone here has experience with this.
HTTP Respons:
{
"errors": {
"sku": [
"Could not find member 'sku' on object of type 'WebApplicationFirewallPatchRequestModel'. Path 'sku', line 1, position 7070."
],
"tags": [
"Required property 'tags' not found in JSON. Path '', line 1, position 7104."
],
"location": [
"Could not find member 'location' on object of type 'WebApplicationFirewallPatchRequestModel'. Path 'location', line 1, position 12."
],
"properties": [
"Could not find member 'properties' on object of type 'WebApplicationFirewallPatchRequestModel'. Path 'properties', line 1, position 35."
]
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-1006d4208c3a8e569d9ec0ff3513ca31-cc06e3e858308547-01"
}
Json post (shortend):
{
"location": "global",
"properties": {
"customRules": {
"rules": [
{
"name": "AllowCDN",
"enabledState": "Enabled",
"priority": 110,
"ruleType": "MatchRule",
"rateLimitDurationInMinutes": 1,
"rateLimitThreshold": 100,
"matchConditions": [
{
"matchVariable": "RequestUri",
"selector": null,
"operator": "Contains",
"negateCondition": false,
"matchValue": [
"snip.azureedge.net",
"snip.azureedge.net"
],
"transforms": [
"Lowercase"
]
}
],
"action": "Allow"
}
]
},
"managedRules": {
"managedRuleSets": [
{
"ruleSetType": "Microsoft_DefaultRuleSet",
"ruleSetVersion": "2.1",
"ruleSetAction": "Block",
"ruleGroupOverrides": [],
"exclusions": []
},
{
"ruleSetType": "Microsoft_BotManagerRuleSet",
"ruleSetVersion": "1.0",
"ruleSetAction": null,
"ruleGroupOverrides": [
{
"ruleGroupName": "GoodBots",
"rules": [
{
"ruleId": "Bot200200",
"enabledState": "Enabled",
"action": "Block",
"exclusions": []
}
],
"exclusions": []
},
{
"ruleGroupName": "UnknownBots",
"rules": [
{
"ruleId": "Bot300200",
"enabledState": "Enabled",
"action": "Block",
"exclusions": []
},
{
"ruleId": "Bot300600",
"enabledState": "Enabled",
"action": "Block",
"exclusions": []
},
{
"ruleId": "Bot300700",
"enabledState": "Enabled",
"action": "Log",
"exclusions": []
},
{
"ruleId": "Bot300400",
"enabledState": "Enabled",
"action": "Log",
"exclusions": []
},
{
"ruleId": "Bot300300",
"enabledState": "Enabled",
"action": "Block",
"exclusions": []
}
],
"exclusions": []
}
],
"exclusions": []
}
]
},
"policySettings": {
"enabledState": "Enabled",
"mode": "Prevention",
"redirectUrl": null,
"customBlockResponseStatusCode": null,
"customBlockResponseBody": null,
"requestBodyCheck": "Enabled"
}
},
"sku": {
"name": "Premium_AzureFrontDoor"
}
}
Updating an existing Frontdoor Premium WAF policy doesn't work.
I was able to execute the Update REST API above though for my Azure Front Door Standard. The process I followed was to make the GET REST API Call first and then copy the response body and then make the updates required in the JSON and use this JSON as a request Body in the Update REST API. The reference JSON below worked for me.
{
"id": "/subscriptions/xxxxx/resourcegroups/xxxxx/providers/Microsoft.Network/frontdoorwebapplicationfirewallpolicies/xxxxx",
"type": "Microsoft.Network/frontdoorwebapplicationfirewallpolicies",
"name": "xxxxx",
"location": "Global",
"tags": {
"Reason": "Repro",
"CreatedDate": "12/29/2022 2:40:29 AM",
"CreatedBy": "xxxxx",
"OwningTeam": "xxxxx"
},
"sku": {
"name": "Standard_AzureFrontDoor"
},
"properties": {
"policySettings": {
"enabledState": "Enabled",
"mode": "Detection",
"redirectUrl": null,
"customBlockResponseStatusCode": 403,
"customBlockResponseBody": null,
"requestBodyCheck": "Disabled"
},
"customRules": {
"rules": [
{
"name": "testcustomrule",
"enabledState": "Enabled",
"priority": 100,
"ruleType": "MatchRule",
"rateLimitDurationInMinutes": 1,
"rateLimitThreshold": 100,
"matchConditions": [
{
"matchVariable": "SocketAddr",
"selector": null,
"operator": "GeoMatch",
"negateCondition": false,
"matchValue": [
"UY"
],
"transforms": []
}
],
"action": "Block"
},
{
"name": "testcustomrule2",
"enabledState": "Enabled",
"priority": 101,
"ruleType": "MatchRule",
"rateLimitDurationInMinutes": 1,
"rateLimitThreshold": 100,
"matchConditions": [
{
"matchVariable": "SocketAddr",
"selector": null,
"operator": "GeoMatch",
"negateCondition": false,
"matchValue": [
"AU"
],
"transforms": []
}
],
"action": "Block"
}
]
},
"managedRules": {
"managedRuleSets": []
},
"frontendEndpointLinks": [],
"securityPolicyLinks": [
{
"id": "/subscriptions/xxxxx/resourcegroups/xxxxx/providers/Microsoft.Cdn/profiles/xxxxx/securitypolicies/xxxxx"
}
],
"routingRuleLinks": [],
"resourceState": "Enabled",
"provisioningState": "Succeeded"
}
}
I am unable to find any library to convert nested JSON schema(2020-12) to scala case classes for scala project.
I am using api first approach, so its necessary.
Found few projects supporting scala case class to JSON Schema but none for JSON schema to scala case class.
Looking for something like this
Example JSON:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/product.schema.json",
"title": "Product",
"type": "object",
"properties": {
"productId": {
"type": "integer"
},
"tags": {
"description": "Tags for the product",
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
},
"dimensions": {
"type": "object",
"properties": {
"length": {
"type": "number"
},
"width": {
"type": "number"
},
"height": {
"type": "number"
}
},
"required": [
"length"
]
}
},
"required": [
"productId",
"price"
]
}
Converted to:
case class Product (
productId: Int,
tags: Option[List[String]],
dimensions: Option[Dimensions]
){
assert( tags.get.length >= 1, "`tags.get` violates 'minItems' constraint" )
assert( tags.get.length == tags.get.distinct.length, "`tags.get` violates 'uniqueItems' constraint" )
}
/**
* #param length
* #param width
* #param height
*/
case class Dimensions (
length: Double,
width: Option[Double],
height: Option[Double]
)
I need to write a Avro schema for the following data. The exposure is a array of arrays with 3 numbers.
{
"Response": {
"status": "",
"responseDetail": {
"request_id": "Z618978.R",
"exposure": [
[
372,
20000000.0,
31567227140.238808
]
[
373,
480000000.0,
96567227140.238808
]
[
374,
23300000.0,
251567627149.238808
]
],
"product": "ABC",
}
}
}
So I came up with a schema like the following:
{
"name": "Response",
"type":{
"name": "algoResponseType",
"type": "record",
"fields":
[
{"name": "status", "type": ["null","string"]},
{
"name": "responseDetail",
"type": {
"name": "responseDetailType",
"type": "record",
"fields":
[
{"name": "request_id", "type": "string"},
{
"name": "exposure",
"type": {
"type": "array",
"items":
{
"name": "single_exposure",
"type": {
"type": "array",
"items": "string"
}
}
}
},
{"name": "product", "type": ["null","string"]}
]
}
}
]
}
}
When I tried to register the schema. I got the following error. TypeError: unhashable type: 'dict' which means I used a list as a dictionary key.
Traceback (most recent call last):
File "sa_publisher_main4test.py", line 28, in <module>
schema_registry_client)
File "/usr/local/lib64/python3.6/site-packages/confluent_kafka/schema_registry/avro.py", line 175, in __init__
parsed_schema = parse_schema(schema_dict)
File "fastavro/_schema.pyx", line 71, in fastavro._schema.parse_schema
File "fastavro/_schema.pyx", line 204, in fastavro._schema._parse_schema
TypeError: unhashable type: 'dict'
Can anyone help point out what is causing the error?
There are a few issues.
First, at the very top level of your schema, you have the following:
{
"name": "Response",
"type": {...}
}
But this isn't right. The top level should be a record type with a field called Response. So it should look like this:
{
"name": "Response",
"type": "record",
"fields": [
{
"name": "Response",
"type": {...}
}
]
}
The second problem is that for the array of arrays, you currently have the following:
{
"name":"exposure",
"type":{
"type":"array",
"items":{
"name":"single_exposure",
"type":{
"type":"array",
"items":"string"
}
}
}
}
But instead it should look like this:
{
"name":"exposure",
"type":{
"type":"array",
"items":{
"type":"array",
"items":"string"
}
}
}
After fixing those, the schema will be able to be parsed, but your data contains an array of array of floats and your schema says it should be an array of array of string. Therefore either the schema needs to be changed to float, or the data needs to be strings.
For reference, here's an example script that works after fixing those issues:
import fastavro
s = {
"name":"Response",
"type":"record",
"fields":[
{
"name":"Response",
"type": {
"name":"algoResponseType",
"type":"record",
"fields":[
{
"name":"status",
"type":[
"null",
"string"
]
},
{
"name":"responseDetail",
"type":{
"name":"responseDetailType",
"type":"record",
"fields":[
{
"name":"request_id",
"type":"string"
},
{
"name":"exposure",
"type":{
"type":"array",
"items":{
"type":"array",
"items":"string"
}
}
},
{
"name":"product",
"type":[
"null",
"string"
]
}
]
}
}
]
}
}
]
}
data = {
"Response":{
"status":"",
"responseDetail":{
"request_id":"Z618978.R",
"exposure":[
[
"372",
"20000000.0",
"31567227140.238808"
],
[
"373",
"480000000.0",
"96567227140.238808"
],
[
"374",
"23300000.0",
"251567627149.238808"
]
],
"product":"ABC"
}
}
}
parsed_schema = fastavro.parse_schema(s)
fastavro.validate(data, parsed_schema)
The error you get is because Schema Registry doesn't accept your schema. Your top element has to be a record with "Response" field.
This schema should work, I changed array item type, as in your message you have float and not string.
{
"type": "record",
"name": "yourMessage",
"fields": [
{
"name": "Response",
"type": {
"name": "AlgoResponseType",
"type": "record",
"fields": [
{
"name": "status",
"type": [
"null",
"string"
]
},
{
"name": "responseDetail",
"type": {
"name": "ResponseDetailType",
"type": "record",
"fields": [
{
"name": "request_id",
"type": "string"
},
{
"name": "exposure",
"type": {
"type": "array",
"items": {
"type": "array",
"items": "float"
}
}
},
{
"name": "product",
"type": [
"null",
"string"
]
}
]
}
}
]
}
}
]
}
Your message is not correct, as array elements should have comma between them.
{
"Response": {
"status": "",
"responseDetail": {
"request_id": "Z618978.R",
"exposure": [
[
372,
20000000.0,
31567227140.238808
],
[
373,
480000000.0,
96567227140.238808
],
[
374,
23300000.0,
251567627149.238808
]
],
"product": "ABC",
}
}
}
As you are using fastavro, I recommend running this code to check that your message is an example of a schema.
from fastavro.validation import validate
import json
with open('schema.avsc', 'r') as schema_file:
schema = json.loads(schema_file.read())
message = {
"Response": {
"status": "",
"responseDetail": {
"request_id": "Z618978.R",
"exposure": [
[
372,
20000000.0,
31567227140.238808
],
[
373,
480000000.0,
96567227140.238808
],
[
374,
23300000.0,
251567627149.238808
]
],
"product": "ABC",
}
}
}
try:
validate(message, schema)
print('Message is matching schema')
except Exception as ex:
print(ex)
I'm getting this error, and I didn't understand why
Call to undefined method DesignMyNight\\Mongodb\\Passport\\Client::confidential()
Knowing that I'm using MongoDB as a database
I sent a POST request with this header and body:
Header:
Content-Type:application/json
Accept:application/json
Body:
{
"email": "khalil#gmail.com",
"password": "123456"
}
knowing that the email and the password are correct, and the register route works fine.
My Controller function :
public function login(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required|min:6'
]);
if(Auth::attempt(["email" => $request->email, "password" => $request->password])){
$user = Auth::user();
$token = $user->createToken($user->email."-".now());
$token = $token->accessToken;
return response()->json([
"token" => $token
]);
}
}
My composer.json file:
{
"name": "laravel/laravel",
"type": "project",
"description": "The Laravel Framework.",
"keywords": [
"framework",
"laravel"
],
"license": "MIT",
"require": {
"php": "^7.2",
"designmynight/laravel-mongodb-passport": "^1.2",
"fideloper/proxy": "^4.0",
"jenssegers/mongodb": "^3.6",
"laravel/framework": "^6.2",
"laravel/tinker": "^2.0"
},
"require-dev": {
"facade/ignition": "^1.4",
"fzaninotto/faker": "^1.4",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^3.0",
"phpunit/phpunit": "^8.0"
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"extra": {
"laravel": {
"dont-discover": []
}
},
"autoload": {
"psr-4": {
"App\\": "app/"
},
"classmap": [
"database/seeds",
"database/factories"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"#php artisan package:discover --ansi"
],
"post-root-package-install": [
"#php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"#php artisan key:generate --ansi"
]
}
}
My User Model:
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use DesignMyNight\Mongodb\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use Notifiable, HasApiTokens;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
The Return:
{
"message": "Call to undefined method DesignMyNight\\Mongodb\\Passport\\Client::confidential()",
"exception": "BadMethodCallException",
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php",
"line": 50,
"trace": [
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php",
"line": 36,
"function": "throwBadMethodCallException",
"class": "Illuminate\\Database\\Eloquent\\Model",
"type": "::"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php",
"line": 1620,
"function": "forwardCallTo",
"class": "Illuminate\\Database\\Eloquent\\Model",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/jenssegers/mongodb/src/Jenssegers/Mongodb/Eloquent/Model.php",
"line": 480,
"function": "__call",
"class": "Illuminate\\Database\\Eloquent\\Model",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/passport/src/Bridge/ClientRepository.php",
"line": 78,
"function": "__call",
"class": "Jenssegers\\Mongodb\\Eloquent\\Model",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/passport/src/Bridge/ClientRepository.php",
"line": 54,
"function": "handlesGrant",
"class": "Laravel\\Passport\\Bridge\\ClientRepository",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/league/oauth2-server/src/Grant/AbstractGrant.php",
"line": 182,
"function": "validateClient",
"class": "Laravel\\Passport\\Bridge\\ClientRepository",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/passport/src/Bridge/PersonalAccessGrant.php",
"line": 21,
"function": "validateClient",
"class": "League\\OAuth2\\Server\\Grant\\AbstractGrant",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/league/oauth2-server/src/AuthorizationServer.php",
"line": 198,
"function": "respondToAccessTokenRequest",
"class": "Laravel\\Passport\\Bridge\\PersonalAccessGrant",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/passport/src/PersonalAccessTokenFactory.php",
"line": 114,
"function": "respondToAccessTokenRequest",
"class": "League\\OAuth2\\Server\\AuthorizationServer",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/passport/src/PersonalAccessTokenFactory.php",
"line": 71,
"function": "dispatchRequestToAuthorizationServer",
"class": "Laravel\\Passport\\PersonalAccessTokenFactory",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/passport/src/HasApiTokens.php",
"line": 67,
"function": "make",
"class": "Laravel\\Passport\\PersonalAccessTokenFactory",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/app/Http/Controllers/AuthController.php",
"line": 48,
"function": "createToken",
"class": "App\\User",
"type": "->"
},
{
"function": "login",
"class": "App\\Http\\Controllers\\AuthController",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Routing/Controller.php",
"line": 54,
"function": "call_user_func_array"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php",
"line": 45,
"function": "callAction",
"class": "Illuminate\\Routing\\Controller",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
"line": 219,
"function": "dispatch",
"class": "Illuminate\\Routing\\ControllerDispatcher",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
"line": 176,
"function": "runController",
"class": "Illuminate\\Routing\\Route",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 681,
"function": "run",
"class": "Illuminate\\Routing\\Route",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 130,
"function": "Illuminate\\Routing\\{closure}",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php",
"line": 41,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 171,
"function": "handle",
"class": "Illuminate\\Routing\\Middleware\\SubstituteBindings",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
"line": 59,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 171,
"function": "handle",
"class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 105,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 683,
"function": "then",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 658,
"function": "runRouteWithinStack",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 624,
"function": "runRoute",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 613,
"function": "dispatchToRoute",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
"line": 170,
"function": "dispatch",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 130,
"function": "Illuminate\\Foundation\\Http\\{closure}",
"class": "Illuminate\\Foundation\\Http\\Kernel",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
"line": 21,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 171,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
"line": 21,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 171,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php",
"line": 27,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 171,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php",
"line": 63,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 171,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/fideloper/proxy/src/TrustProxies.php",
"line": 57,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 171,
"function": "handle",
"class": "Fideloper\\Proxy\\TrustProxies",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 105,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
"line": 145,
"function": "then",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
"line": 110,
"function": "sendRequestThroughRouter",
"class": "Illuminate\\Foundation\\Http\\Kernel",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/public/index.php",
"line": 55,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Kernel",
"type": "->"
},
{
"file": "/home/ixi/Desktop/TuniSales/Dev/v1.0.0/server.php",
"line": 21,
"function": "require_once"
}
]
}
With Laravel 6.2 you need Laravel/Passport v7.5.1 not ^8.0
You do not need DesignMyNight package for Laravel/Passport to work with jenssegers/mongodb.
No migrations are required to be ran, you should call the Passport::ignoreMigrations method in the register method of your AppServiceProvider.
You may want to create a custom migration just to setup optimal indexes for the passport collections if you are expecting heavy load.
Here is a sample of my setup:
"require": {
"php": "^7.2",
"fideloper/proxy": "^4.0",
"jenssegers/mongodb": "3.6.*",
"jenssegers/mongodb-session": "1.3.*",
"laravel/framework": "^6.2",
"laravel/passport": "7.5.1",
"laravel/tinker": "^2.0",
"predis/predis": "^1.1"
},
I have a Dataset coming from a Rest webservice having an # in the column name:
Like:
{
data[{
#id : 1,
#value : "a"
}, {
#id : 2,
#value : "b"
}
]
}
i want to use it in a foreach and access the specific column:
in the foreach i get the output like #activity('Lookup').output.value
in the foreach there is a stored procedure
as parameter input i tried to get the column: i tried #item().#value but got the error "the string character '#' at position 'xx' is not expected".
is there a way to escape the # in the column name? or can i rename the column?
Thank you very much
edit:
here is the JSON from the ADF pipeline:
{
"name": "pipeline3",
"properties": {
"activities": [
{
"name": "Lookup1",
"type": "Lookup",
"policy": {
"timeout": "7.00:00:00",
"retry": 0,
"retryIntervalInSeconds": 30,
"secureOutput": false,
"secureInput": false
},
"typeProperties": {
"source": {
"type": "HttpSource",
"httpRequestTimeout": "00:01:40"
},
"dataset": {
"referenceName": "HttpFile1",
"type": "DatasetReference"
},
"firstRowOnly": false
}
},
{
"name": "ForEach2",
"type": "ForEach",
"dependsOn": [
{
"activity": "Lookup1",
"dependencyConditions": [
"Succeeded"
]
}
],
"typeProperties": {
"items": {
"value": "#activity('Lookup1').output.value",
"type": "Expression"
},
"activities": [
{
"name": "Stored Procedure12",
"type": "SqlServerStoredProcedure",
"policy": {
"timeout": "7.00:00:00",
"retry": 0,
"retryIntervalInSeconds": 30,
"secureOutput": false,
"secureInput": false
},
"typeProperties": {
"storedProcedureName": "[dbo].[testnv]",
"storedProcedureParameters": {
"d": {
"value": {
"value": "#item().#accno",
"type": "Expression"
},
"type": "String"
}
}
},
"linkedServiceName": {
"referenceName": "AzureSqlDatabase1",
"type": "LinkedServiceReference"
}
}
]
}
}
]
},
"type": "Microsoft.DataFactory/factories/pipelines"
}
Please try "#item()['#accno']" for #item().#accno
Also replied in MSDN.