I have to validate the incoming json payload and throw custom errors if the json is not valid. I tried implementing the validator interface as shown in the above image. But how should I access the payload now?In earlier versions the method accepted a mule event through which we could easily get the payload:
public interface Validator
{
/**
* Performs the validation and generates a
* {#link ValidationResult} back.
*
* #param event the current {#link MuleEvent}
* #return a {#link ValidationResult}
*/
ValidationResult validate(MuleEvent event);
}
Related
I'm having a difficulty understanding how to configure the following.
Since spring-kafka:2.8.4 thee KafkaListener interface can be configured with a filter which will be applied to all incoming messages, the Javadoc for the filter method:
/**
* Set an {#link org.springframework.kafka.listener.adapter.RecordFilterStrategy} bean
* name to override the strategy configured on the container factory. If a SpEL
* expression is provided ({#code #{...}}), the expression can either evaluate to a
* {#link org.springframework.kafka.listener.adapter.RecordFilterStrategy} instance or
* a bean name.
* #return the error handler.
* #since 2.8.4
*/
String filter() default "";
RecordFilterStrategy has a single method:
/**
* Return true if the record should be discarded.
* #param consumerRecord the record.
* #return true to discard.
*/
boolean filter(ConsumerRecord<K, V> consumerRecord);
Basically I need to create a kind of a lambda, but I don't understand how to reference the consumerRecord variable, this is what I have already tried:
#{#consumerRecord.key().equals(T(com.example.kafkaconsumer.EventType).CREATE.toString())}
It fails with the exception:
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1011E:
Method call: Attempted to call method key() on null context object
This is what I'm trying to implement using SPEL:
#Bean
public RecordFilterStrategy<String, Foo> recordFilterStrategy() {
return rec -> !Objects.equals(rec.key(), EventType.CREATE.toString());
}
See that JavaDocs one more time:
Set an {#link org.springframework.kafka.listener.adapter.RecordFilterStrategy} bean
* name
Since you already have a recordFilterStrategy bean, so that's enough for your to use in that filter() attribute:
filter = "recordFilterStrategy"
No need to fight with a complex SpEL.
with org.springframework.boot update from 2.0.4.RELEASE to 2.0.5.RELEASE start to get exception:
RepositoryConfigurationExtensionSupport
=> useRepositoryConfiguration
=> InvalidDataAccessApiUsageException: "Reactive Repositories are not supported by %s. Offending repository is %s!"
what is the best/simplest Spring Data workaround for this? Could someone provide example? if it is possible without redefinition of #EnableJpaRepositories and JpaRepositoriesRegistrar...
This is solution, but I don't like it.. +3 new classes..
EnableXxxJpaRepositories is practically exact copy of EnableJpaRepositories..
EnableXxxJpaRepositories:
#Target(ElementType.TYPE)
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Inherited
#Import(XxxJpaRepositoriesRegistrar.class)
public #interface EnableXxxJpaRepositories {
/**
* Alias for the {#link #basePackages()} attribute. Allows for more concise annotation
* declarations e.g.: {#code #EnableXxxJpaRepositories("org.my.pkg")} instead of {#code
*
* #EnableXxxJpaRepositories(basePackages="org.my.pkg")}.
*/
String[] value() default {};
/**
* Base packages to scan for annotated components. {#link #value()} is an alias for (and mutually
* exclusive with) this attribute. Use {#link #basePackageClasses()} for a type-safe alternative
* to String-based package names.
*/
String[] basePackages() default {};
/**
* Type-safe alternative to {#link #basePackages()} for specifying the packages to scan for
* annotated components. The package of each class specified will be scanned. Consider creating a
* special no-op marker class or interface in each package that serves no purpose other than being
* referenced by this attribute.
*/
Class<?>[] basePackageClasses() default {};
/**
* Specifies which types are eligible for component scanning. Further narrows the set of candidate
* components from everything in {#link #basePackages()} to everything in the base packages that
* matches the given filter or filters.
*/
Filter[] includeFilters() default {};
/**
* Specifies which types are not eligible for component scanning.
*/
Filter[] excludeFilters() default {};
/**
* Returns the postfix to be used when looking up custom repository implementations. Defaults to
* {#literal Impl}. So for a repository named {#code PersonRepository} the corresponding
* implementation class will be looked up scanning for {#code PersonRepositoryImpl}.
*/
String repositoryImplementationPostfix() default "Impl";
/**
* Configures the location of where to find the Spring Data named queries properties file. Will
* default to {#code META-INF/jpa-named-queries.properties}.
*/
String namedQueriesLocation() default "";
/**
* Returns the key of the {#link QueryLookupStrategy} to be used for lookup queries for query
* methods. Defaults to {#link Key#CREATE_IF_NOT_FOUND}.
*/
Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND;
/**
* Returns the {#link FactoryBean} class to be used for each repository instance. Defaults to
* {#link JpaRepositoryFactoryBean}.
*/
Class<?> repositoryFactoryBeanClass() default JpaRepositoryFactoryBean.class;
/**
* Configure the repository base class to be used to create repository proxies for this particular
* configuration.
*
* #since 1.9
*/
Class<?> repositoryBaseClass() default DefaultRepositoryBaseClass.class;
// JPA specific configuration
/**
* Configures the name of the {#link EntityManagerFactory} bean definition to be used to create
* repositories discovered through this annotation. Defaults to {#code entityManagerFactory}.
*/
String entityManagerFactoryRef() default "entityManagerFactory";
/**
* Configures the name of the {#link PlatformTransactionManager} bean definition to be used to
* create repositories discovered through this annotation. Defaults to {#code
* transactionManager}.
*/
String transactionManagerRef() default "transactionManager";
/**
* Configures whether nested repository-interfaces (e.g. defined as inner classes) should be
* discovered by the repositories infrastructure.
*/
boolean considerNestedRepositories() default false;
/**
* Configures whether to enable default transactions for Spring Data JPA repositories. Defaults to
* {#literal true}. If disabled, repositories must be used behind a facade that's configuring
* transactions (e.g. using Spring's annotation driven transaction facilities) or repository
* methods have to be used to demarcate transactions.
*
* #return whether to enable default transactions, defaults to {#literal true}.
*/
boolean enableDefaultTransactions() default true;
}
XxxJpaRepositoriesRegistrar:
#Configuration
public class XxxJpaRepositoriesRegistrar extends RepositoryBeanDefinitionRegistrarSupport {
#Override
protected Class<? extends Annotation> getAnnotation() {
return EnableXxxJpaRepositories.class;
}
#Override
protected RepositoryConfigurationExtension getExtension() {
return new XxxJpaRepositoryConfigExtension();
}
}
XxxJpaRepositoryConfigExtension:
#Component
public class XxxJpaRepositoryConfigExtension extends JpaRepositoryConfigExtension {
#Override
protected boolean useRepositoryConfiguration(RepositoryMetadata metadata) {
//return super.useRepositoryConfiguration(metadata);
//return metadata.isReactiveRepository();
return true;
}
}
I need to get an original Request (specifically Request::server()) in my listeners for these Laravel internal events:
Illuminate\Auth\Events\Login
Illuminate\Auth\Events\Failed
Understandably, I cannot use values Request returns in my listener, since it's constructed separately server-side on queue.
Any help is highly appreciated!
In the constructor of the listener you can save the request to a member of the class, then you will be able to use it inside the handle function. For example:
class LogSuccessfulLogin implements ShouldQueue
{
protected $request;
/**
* Create the event listener.
*
* #return void
*/
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* Handle the event.
*
* #param Login $event
* #return void
*/
public function handle(Login $event)
{
// here you can use $this->request->ip(); for example.
}
}
I am beginner and as I understand #Transactional simply make sure that all the internal work of a class or method annotated with #Transactional will be wrapped in one transaction and all of the calls from external sources will create a new transaction but why do we actually need these annotations in Repository below and what are advantages of using it with readOnly = true in common cases? This is Spring pet-clinic example application using Spring & Hibernate (https://github.com/spring-projects/spring-petclinic).
/**
* Repository class for <code>Pet</code> domain objects All method names are compliant with Spring Data naming
* conventions so this interface can easily be extended for Spring Data See here: http://static.springsource.org/spring-data/jpa/docs/current/reference/html/jpa.repositories.html#jpa.query-methods.query-creation
*
* #author Ken Krebs
* #author Juergen Hoeller
* #author Sam Brannen
* #author Michael Isvy
*/
public interface PetRepository extends Repository<Pet, Integer> {
/**
* Retrieve all {#link PetType}s from the data store.
* #return a Collection of {#link PetType}s.
*/
#Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name")
#Transactional(readOnly = true)
List<PetType> findPetTypes();
/**
* Retrieve a {#link Pet} from the data store by id.
* #param id the id to search for
* #return the {#link Pet} if found
*/
#Transactional(readOnly = true)
Pet findById(Integer id);
/**
* Save a {#link Pet} to the data store, either inserting or updating it.
* #param pet the {#link Pet} to save
*/
void save(Pet pet);
}
From the explanation of Oliver Gierke - the Spring Data author:
Reading methods like findAll() and findOne(…) are using
#Transactional(readOnly = true) which is not strictly necessary but
triggers a few optimizations in the transaction infrastructure
(setting the FlushMode to MANUAL to let persistence providers
potentially skip dirty checks when closing the EntityManager). Beyond
that the flag is set on the JDBC Connection as well which causes
further optimizations on that level.
Depending on what database you use it can omit table locks or even
reject write operations you might trigger accidentally. Thus we
recommend using #Transactional(readOnly = true) for query methods as
well which you can easily achieve adding that annotation to you
repository interface. Make sure you add a plain #Transactional to the
manipulating methods you might have declared or re-decorated in that
interface.
Further reading:
Spring read-only transaction Hibernate optimization
Read-write and read-only transaction routing with Spring
I have read how to validate forms in server side with sf2. The solution is by using the Constraints in the Entity as annotations, validation.yml or inside the EntityType (Form).
Everything is fine, however, all of these validations work just with the form. But when you instance a new object and try to persist, validation doesn't work.
I will give you an example.
Imagine I have a user entity:
/**
* #ORM\Entity
* #ORM\Table(name="sf_user")
*/
class User{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #ORM\Column( name="username", type="string", length=50, unique=true )
*/
protected $username;
/**
* #var string
* #ORM\Column( name="email", type="string", length=100, unique=true )
*/
protected $email;
public static function loadValidatorMetadata(\Symfony\Component\Validator\Mapping\ClassMetadata $metadata)
{
$metadata->addPropertyConstraint('username', new \Symfony\Component\Validator\Constraints\NotBlank());
$metadata->addPropertyConstraint('email', new \Symfony\Component\Validator\Constraints\NotNull());
}
}
Then, in some controller I try to save my form with:
$this->form = $this->create(new UserType());
$this->form->setData(new User());
$this->form->bind($this->request);
if( $this->form->isValid())
{
//Persist with entity manager
}
Everything works perfectly because I have an association between my Entity and my form. But what happen if i need to instance an object without a form?. I should do something like this:
$user = new User();
$user->setUsername("username");
//Persist with entity manager
If I do that, entity is not validated and DB throws an error because the field "email" is required.
Should I always associate my entity with the form to validate? If that is the case, I don't agree at all because if I am working with web services, I don't wanna create a form just to validate on the server side.
So, how could I do this validation?. Thanks for your help.
You can use the validation service
$validator = $this->get('validator');
$validator->validate($user);
see the docs about this.
By the way there is a cleaner way to specify validation in you entity.
use Symfony\Component\Validator\Constraints as Assert;
class User{
/**
* #Assert\NotNull
*/
protected $username;
/**
* #Assert\NotBlank
* #Assert\Email
*/
protected $email;