apache deltaspike the cdi toolbox

36
APACHE DELTASPIKE THE CDI TOOLBOX @antoine_sd

Upload: antoine-sabot-durand

Post on 15-Jul-2015

1.994 views

Category:

Technology


0 download

TRANSCRIPT

APACHE DELTASPIKETHE CDI TOOLBOX

@antoine_sd

Font: Avenir LightFont-size: 64ptLetter-spacing: 410

RGB: 51,181 229HEX: #35b4e3 C=66.45 M=8.61 Y=1.97 K=0

Submitted by J. Parenti of Visuale

ANTOINE SABOT-DURAND

• Senior Software Engineer @Red Hat

• Java & OSS :

• CDI co-spec lead

• CDI community development

• Apache Deltaspike committer

• @antoine_sd

AGENDA

• What is Apache Deltaspike?

• Deltaspike Core

• Deltaspike Modules

• Conclusion

WHAT IS APACHE DELTASPIKE

CDI & DELTASPIKE

• CDI is a specification. It doesn’t provide business features

• but it includes a powerful hook to add these business features

• The “portable extensions” feature is this hook

• Thanks to it, CDI can be easily enhanced with new high level features

APACHE DELTASPIKE IS…

• A collection of ready to use extensions to help you in your projects

• A toolbox to help you develop new CDI portable extensions

• A great way to learn how to develop your own extension by browsing the source code

• The most obvious entry point to CDI eco-system

WHERE DOES IT COMES FROM?

Font: Avenir LightFont-size: 64ptLetter-spacing: 410

RGB: 51,181 229HEX: #35b4e3 C=66.45 M=8.61 Y=1.97 K=0

Submitted by J. Parenti of Visuale

Miscellaneous CDI Initiatives

TESTED WITH• CDI 1.0, 1.1, 1.2

• JBoss Weld 1.1.3 to 2.2.8

• OpenWebBeans 1.1.1 to 1.2.7

• JBoss AS 7.x, WildFly 8.x

• JBoss EAP 6.x

• TomEE 1.0.x - 1.7.x

• GlassFish 3.x, 4.x

• Weblogic 12c

A BIT OF HISTORY

Dec 2011 Feb 2012 May 2013 June 2014

Proj

ect L

aunc

h

rel. 0

.1

rel. 0

.4 (o

ut o

f inc

ubat

or)

rel. 1

.0

Dec 2014

rel. 1

.2.1

WHAT’S INCLUDED?Apache Deltaspike is organized in the following modules

Container control provides a portable way to boot CDI containerCore Module core features and helpers. Used by all other modules belowPartial Bean Module develop generic handler to choose code dynamically at runtimeScheduler Module add job scheduling with Quartz or any other schedulerSecurity Module add security checking. Integration of 3rd party security frameworkBean Validation Module CDI integration for Bean Validation 1.0JPA Module Enhance JPA integration for CDI 1.0. Mostly useless in Java EE 7Data Module Implements repository pattern removing JPA boilerplate codeServlet Module Enhance Servlet integration for CDI 1.0. Mostly useless in Java EE 7JSF Module Enhance JSF by adding CDI scopes, typesafe view config, etc…Test control provide a test solution for CDI based on Junit

MODULES AND DEPENDENCIES

Partial Bean Core

Bean Validation

JPAData

Security

JSF

Scheduler Servlet

Test CTRL

Containers CTRL

ADDING DELTASPIKE TO YOUR POM.XML<dependency> <groupId>org.apache.deltaspike.core</groupId> <artifactId>deltaspike-core-api</artifactId> <version>1.2.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.deltaspike.core</groupId> <artifactId>deltaspike-core-impl</artifactId> <version>1.2.1</version> <scope>runtime</scope> </dependency>

DELTASPIKE CORE

CONFIGURATION 1/2• DeltaSpike provides a powerful configuration API / SPI

• It doesn’t depend on CDI, thus it can be used in portable extension

• The entry point is the ConfigResolver class

• ConfigSource SPI allows to add new configuration source

• Each config has a priority (ordinal). This highest is picked first

CONFIGURATION 2/2Out of the Box Config Sources

ConfigSource Priority Notes

System properties 400

Environment properties 300

JNDI values 200 java:comp/env/deltaspike

Properties files value 100 META-INF/apache-deltaspike.properties

CONFIGURATION USAGE//ConfigResolver can be used directly without CDI dependency (useful in extensions)String dbUserName = ConfigResolver.getPropertyValue("databaseconfig.username"); … //Config can also be used in CDI mode and typeSafe config@Inject@ConfigProperty(name = "endpoint.poll.interval") private Integer p; // DS provides conversion for String, Integer, Long, Boolean, Float … //But you can provide your own ConfigProperty producer to perform custom conversion@ApplicationScopedpublic class MyConfigPropertyProducer extends BaseConfigPropertyProducer { @Produces @ConfigProperty(name = "ignored") public MyType produceStringConfiguration(InjectionPoint injectionPoint) { String strValue = getStringPropertyValue(injectionPoint); … } }

PROJECT STAGES

• Allows to use implementations depending on current environment

• You can defined your owned stage or used the provided ones

• Pre-defined project stages:

• UnitTest, Development, SystemTest, IntegrationTest, Staging, Production

• Project Stage is configured thru DS configuration mechanism

PROJECT STAGE EXAMPLE

//Setting project stage with environment property -Dorg.apache.deltaspike.ProjectStage=Development

//Using project stage@Injectprivate ProjectStage projectStage; boolean isDevProjectStage = ProjectStage.Development.equals(this.projectStage);

BEAN EXCLUSION WITH @EXCLUDE

@Exclude //like CDI 1.1+ @Vetoed but limited to a class

@Exclude(ifProjectStage=Production.class) //based on project stage @Exclude(exceptIfProjectStage=UnitTest.class) //based on project stage @Exclude(onExpression="myProperty==myValue") //based on config value @Exclude(onExpression="[cust exp]", interpretedBy=CustomExpInterpreter.class) //custom

EXCEPTION HANDLERS

• Based on CDI event

• ExceptionToCatchEvent class sends the exception to DS

• @ExceptionHandler marks a class as handlers container

• @Handles and ExceptionEvent<T> handle an exception

EXCEPTION HANDLER EXAMPLEpublic class InventoryActions { @PersistenceContext private EntityManager em; @Inject private Event<ExceptionToCatchEvent> catchEvent; public Integer queryForItem(Item i) { try { Query q = em.createQuery("SELECT i from Item i where i.id = :id"); q.setParameter("id", item.getId()); return q.getSingleResult(); } catch (PersistenceException e) { catchEvent.fire(new ExceptionToCatchEvent(e)); } }} … @ExceptionHandlerpublic class MyHandler { void handleTheException(@Handles ExceptionEvent<Throwable> exEvent) { // Do anything with the exception exEvent.handleAndContinue(); } }

INJECTABLE RESOURCE

@Inject@InjectableResource(location = "/version.txt") private InputStream is; //Can be customised for alternate sources

public String getVersion() throws IOException { try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) { return br.readLine(); } }

INTERNATIONALISATION (I18N)package org.apache.deltaspike.example@MessageBundle // Can only be applied on an interfacepublic interface SimpleMessage // Will map the org/apache/deltaspike/example/SimpleMessage bundle{ @MessageTemplate(“{my_message}”) // Will map my_message key in bundle String welcomeToDeltaSpike();

// For value with parameter i.e welcome_to = Welcome to %s @MessageTemplate("{welcome_to}") String welcomeTo(String name); }

CDI METADATA BUILDERS• Creating CDI SPI metadata for you extension can be cumbersome

• Deltaspike provides builder to ease the work and reduce code verbosity

• Major builder are

• AnnotatedTypeBuilder

• BeanBuilder

• WrapperBeanBuilder

BUILDING META DATA EXAMPLESvoid addTimedBinding(@Observes BeforeBeanDiscovery bbd) { AnnotationLiteral<Nonbinding> nonbindingLiteral = new AnnotationLiteral<Nonbinding>(){}; AnnotatedTypeBuilder<Timed> atb = new AnnotatedTypeBuilder<Timed>() .readFromType(Timed.class) .addToMethod(Timed.class.getMethod("name"), nonbindingLiteral) .addToMethod(Timed.class.getMethod(“absolute"),nonbindingLiteral); bbd.addInterceptorBinding(atb.create()); } … public void registerGenericBeans(@Observes AfterBeanDiscovery abd) { BeanBuilder<User> ubb = new BeanBuilder<User>(beanManager) .readFromType(User.class) .passivationCapable(true) .addTypes(otherTypes); if (weAreOnWeb) ubb.scope(SessionScoped.class); else ubb.scope(ApplicationScoped.class); abd.addBean(ubb.create()); }

DELTASPIKE MODULES

CONTAINER CONTROLpublic class MainApp { public static void main(String[] args) { CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer(); cdiContainer.boot(); // Starting the application-context enables use of @ApplicationScoped beans ContextControl contextControl = cdiContainer.getContextControl(); contextControl.startContext(ApplicationScoped.class); // You can use CDI here cdiContainer.shutdown(); } }

TEST CONTROL EXAMPLES@RunWith(CdiTestRunner.class) public class MyCdiTest { @Inject private MyBean bean; } … @RunWith(CdiTestSuiteRunner.class) @Suite.SuiteClasses({ TestX.class, TestY.class}) public class SuiteLevelContainerControl{}… @RunWith(CdiTestRunner.class) @TestControl(projectStage = CustomTestStage.class) public class TestStageControl { @Test @TestControl(projectStage = ProjectStage.Development.class) public void checkDevEnv(){}}

SECURITY@Retention(value = RetentionPolicy.RUNTIME)@Target({ ElementType.TYPE, ElementType.METHOD })@Documented@SecurityBindingTypepublic @interface AdminOnly {} … @ApplicationScopedpublic class ApplicationAuthorizer { @Secures @AdminOnly // Binding security to permission verifier public boolean verifyPermission(InvocationContext invocationContext, BeanManager manager, @Logged User user) throws Exception { return user.getRole().equalsIgnoreCase("Admin"); } } … @AdminOnlypublic void startAdministrativeTask() { // Only admins can start admin tasks}

SCHEDULER

@Scheduled(cronExpression = "0 0/10 * * * ?") public class CdiAwareQuartzJob implements org.quartz.Job{ @Inject private MyService service; @Override public void execute(JobExecutionContext context) throws JobExecutionException { //... } }

DATA MODULE

DATA MODULE

• Data module is an implementation of the repository pattern

• At the moment it only support RDBMS thru JPA

• But it could be extended to support other data services

• It uses the “partial bean” module to dynamically create implementation at runtime

-Eric Evans (in Domain Driven Design)

« A Repository represents all objects of a certain type as a conceptual set. It acts like a collection,

except with more elaborate querying capability.»

REPOSITORY PATTERN DEFINITION

SIMPLE EXAMPLE@Repository //Repo definition to put an interfacepublic interface UserRepository extends EntityRepository<User, Long> { // method signature creates the JPQL with the partial bean mechanism public User findByUsernameAndPassword(String username, char[] password); } … @Repositorypublic interface PostRepostiory extends EntityRepository<Post, Long> { @Query("SELECT p FROM Post AS p WHERE p.author in (?1)") public List<Post> findByFollowing(List<User> following); }

JPA FUNCTIONS SUPPORTED• count();

• findAll();

• findBy(PK);

• flush();

• refresh();

• remove();

• save();

• saveAndFlush();

CONCLUSION• More info & doc on http://deltaspike.apache.org

• Follow @Deltaspiketeam on Twitter

• Visit examples: https://deltaspike.apache.org/external.html

• & http://jboss.org/developer-materials/#!keyword=Deltaspike

• Questions ?