Featured FREE Whitepapers

What's New Here?

java-interview-questions-answers

The future is Micro Service Architectures on Apache Karaf

This is a guest blog post by Jamie Goodyear (blog, @icbts). He is an open source advocate, Apache developer, and computer systems analyst with Savoir Technologies; he has designed, critiqued, and supported architectures for large organizations worldwide. He holds a Bachelor of Science degree in Computer Science from Memorial University of Newfoundland.      Jamie has worked in systems administration, software quality assurance, and senior software developer roles for businesses ranging from small start-ups to international corporations. He has attained committer status on Apache Karaf, ServiceMix, and Felix, Project Management Committee member on Apache Karaf, and is an Apache Software Foundation member. His first printed publication was co-authoring Instant OSGi Starter, Packt Publishing, with Johan Edstrom followed by Learning Apache Karaf, Packt Publishing, with Johan Edstrom and Heath Kesler. His third and latest publication is Apache Karaf Cookbook, Packt Publishing, with Johan Edstrom, Heath Kesler, and Achim Nierbeck. I like Micro Service Architectures. There are many descriptions of what constitutes a micro service, and many specifications that could be described as following the pattern. In short, I tend to describe them as being the smallest unit of work that an application can do as a service for others. Bringing together these services we’re able to build larger architectures that are modular, light weight, and resilient to change. From the point of view of modern systems architecture the ability to provision small applications with full life cycle control is our idea platform. Operators need only deploy the services they need, updating them in place, spinning up additional instances as required. Another way of describing this is as Applications as a Service (AaaS). Take particular small services such as Apache Camel routes or Apache CXF endpoints and bring them up and down with out destroying the whole application. Apache Karaf IS the platform to do micro services. To make micro services easier, Karaf provides many helpful features right out of the box;A collection of well tested libraries and frameworks to help taken the guess work out of assembling a platform for your applications. Provisioning of libraries or applications via a variety of mechanisms such as Apache Maven. Feature descriptors to allow deployment of related services & resources together. Console and web-based commands to help make fine grained control easy, and Simplified integration testing via Pax Exam.One of my favourite micro service patterns is to use Apache Camel with a Managed Service Factory (MSF) on Apache Karaf. Camel provides a simple DSL for wiring together Enterprise Integration Patterns, moving data from endpoint A to endpoint B as an example. A Managed Service Factory is an Modular Pattern for configuration driven deployments of your micro services – it ties together ConfigAdmin, the OSGi Service Registry, and our application code.For instance, a user could create a configuration to wire their Camel route, using a MSF, unique PIDs will be generated per a configuration. This pattern is truly powerful. Create 100 configurations, and 100 corresponding micro services (Camel routes) will be instantiated. Only one set of code however requires maintenance. Let’s take a close look at the implementation of the Managed Service Factory. The ManagedServiceFactory is responsible for managing instantiations (configurationPid), creating or updating values of instantiated services, and finally, cleaning up after service instantiations. Read more on the ManagedServiceFactory API. public class HelloFactory implements ManagedServiceFactory {@Override public String getName() { return configurationPid; }@Override public void updated(String pid, Dictionary dict) throws ConfigurationException { // Create a dispatching engine for given configuration. }@Override public void deleted(String pid) { // Delete corresponding dispatch engine for given configuration. }//We wire in blueprint public void init() {} public void destroy() {} public void setConfigurationPid(String configurationPid) {} public void setBundleContext(BundleContext bContext) {} public void setCamelContext(CamelContext camelContext) {} } We override the given ManageServiceFactory interface to work with DispatchEngines. The DispatchEngine is a simple class that contains code for instantiating a Camel route using a given configuration. public class HelloDispatcher {public void start() { // Create routeBuilder using configuration, add to CamelContext. // Here ‘greeting’ and ‘name’ comes from configuration file.from(“timer://helloTimer?fixedRate=true.=1000"). routeId("Hello " + name). log(greeting + " " + name); }public void stop() { // remove route from CamelContext. } }When we deploy these classes as a bundle into Karaf we obtain a particularly powerful Application as a Service. Each configuration we provision to the service instantiates a new Camel router (these configuration files quite simply consist of Greeting and Name). Camel’s Karaf commands allow for fine grained control over these routes, providing the operator with simple management. Complete code for the above example is available via github, and is explored in detail in Packt Publishing’s Apache Karaf Cookbook. Micro Service Architectures such as above unleash the power of OSGi for common applications such as a Camel route or CXF endpoint. These are not the only applications which benefit however. I’d like to share one of our Karaf success stories that highlights how Apache Karaf helped bring structure to an existing large scale micro service based project. Imagine having hundreds of bundles distributed over dozens of interconnected projects essentially being deployed in a plain OSGi core and left to best luck to successfully boot properly. This is the situation that OpenDaylight, a platform for SDN and NFV, found themselves in a few months ago.Using Karaf Feature descriptors each project was able to organize their dependencies, bundles, and other resources into coherent structures. Custom commands were developed to interact with their core services. Integration testing of each project into the project’s whole were automated. Finally all of these projects have been integrated into their own custom distribution. Their first Karaf-based release, Helium, is due out very soon. We’re all looking forward to welcoming the SDN & NFV community to Karaf. While Apache Karaf 3.0.x line is maintained as our primary production target, the community has been busy as ever developing the next generation of Karaf containers. The 4.0.x line will ship with OSGi Rev5 support via Felix 4.4.1 and Equinox 3.9.1-v20140110-1610, and a completely refactored internal framework based on Declarative Services instead of Blueprint. From a users point of view these changes will yield a smaller, more efficient Karaf core. There will be a Blueprint feature present in Karaf so that you can easily install Blueprint based applications. You will always be capable of using Blueprint in Karaf. So the main difference from a user perspective is that you’d need to depend on the Blueprint service if you need it. This has been a very brief overview of Micro Service Architectures on Apache Karaf, and Karaf’s future direction. I’d suggest anyone interested in Micro Services to visit the OSGi Alliance website, and join Apache Karaf community. For those whom whom would like to dive into an advanced custom Karaf distribution have a look into Aetos. Apache Karaf is also part of JBoss Fuse.Reference: The future is Micro Service Architectures on Apache Karaf from our JCG partner Markus Eisele at the Enterprise Software Development with Java blog....
java-interview-questions-answers

Identity Anti-patterns: Federation Silos and Spaghetti Identity

A recent research done by the analyst firm Quocirca confirms that many businesses now have more external users than internal ones: in Europe 58 percent transact directly with users from other businesses and/or consumers; for the UK alone the figure is 65 percent. If you look at the history, most enterprises grow today via acquisitions, mergers and partnerships. In U.S only, mergers and acquisitions volume totaled to $865.1 billion in the first nine months of 2013, according to Dealogic. That’s a 39% increase over the same period a year ago — and the highest nine-month total since 2008. What does this mean to enterprise identity management ?   You would have to work with multiple heterogeneous user stores – authentication protocols – legacy systems and many more. SAML, OpenID, OpenID Connect, WS-Federation all support identity federation – cross domain authentication. But, can we always expect all the parties in a federation use case to support SAML, OpenID or OpenID Connect ? Most of the federation systems we see today are in silos. It can be a silo of SAML federation, a silo of OpenID Connect federation or a silo of OpenID federation.Even in a given federation silo how do you scale with increasing number of service providers and identity providers? Each service provider has to trust each identity provider and this leads into the Spaghetti Identity anti-pattern.Federation Silos and Spaghetti Identity are two anti-patterns directly addressed by the Identity Bus pattern. With Identity Bus, a given service provider is not coupled to a given identity provider – and also not coupled to a given federation protocol. A user should be able to login into a service provider which accepts only SAML 2.0 tokens with an identity provider who only issues OpenID Connect tokens. The identity bus acts as the middle-man who mediates and transforms identity tokens between heterogeneous identity protocols. Let’s see some of the benefits of the Identity Bus pattern.Introducing a new service provider is extremely easy. You only need to register the service provider at the identity bus and from the there pick which identity providers it trusts. No need to add the service provider configuration to each and every identity provider. Removing an existing service provider is extremely easy. You only need to remove the service provider from the identity bus. No need to remove the service provider from each and every identity provider. Introducing an new identity provider is extremely easy. You only need to register the identity provider at the identity bus. It will be available for any service provider. Removing an existing identity provider is extremely easy. You only need to remove the identity provider from the identity bus. Enforcing new authentication protocols is extremely easy. Say you need to authenticate users with both the username/password and duo-security (SMS based authentication) – you only need to add that capability to the identity bus and from there you pick the required set of authentication protocols against a given service provider at the time of service provider registration. Each service provider can pick how it wants to authenticate users at the identity bus. Claim transformations. Your service provider may read user’s email address from the http://sp1.org/claims/email attribute id – but the identity provider of the user may send it as http://idp1.org/claims/emai. Identity bus can transform the claims it receives from the identity provider to the format expected by the service provider. Role mapping. Your service provider needs to authorize users once they are logged in. What the user can do at the identity provider is different from what the same user can do at the service provider. User’s roles from the identity provider define what he can do at the identity provider. Service provider’s roles define the things a user can do at the service provider. Identity bus is capable of mapping identity provider’s roles to the service provider’s roles. For example a user may bring idp-admin role from his identity provider – in a SAML response – then the identity bus will find the mapped service provider role corresponding to this, say sp-admin, and will add that into the SAML response returning back to the service provider from the identity bus. Just-in-time provisioning. Since identity bus is at the middle of all identity transactions – it can provision all external user identities to an internal user store. Centralized monitoring and auditing. Introducing a new federation protocol needs minimal changes. If you have a service provider or an identity provider, which supports a proprietary federation protocol, then you only need to add that capability to the identity bus. No need to implement it at each and every identity provider or service provider.WSO2 Identity Server is an open source Identity and Entitlement management server, which supports SAML 2.0, OpenID, OAuth 2.0, OpenID Connect, XACML 3.0, SCIM, WS-Federation (passive) and many other identity federation patterns. Following diagram shows the high-level architecture of  WSO2 Identity Server – which supports the Identity Bus pattern.Reference: Identity Anti-patterns: Federation Silos and Spaghetti Identity from our JCG partner Prabath Siriwardena at the Facile Login blog....
java-interview-questions-answers

DI Containers are Code Polluters

While dependency injection (aka, “DI”) is a natural technique of composing objects in OOP (known long before the term was introduced by Martin Fowler), Spring IoC, Google Guice, Java EE6 CDI, Dagger and other DI frameworks turn it into an anti-pattern. I’m not going to discuss obvious arguments against “setter injections” (like in Spring IoC) and “field injections” (like in PicoContainer). These mechanisms simply violate basic principles of object-oriented programming and encourage us to create incomplete, mutable objects, that get stuffed with data during the course of application execution. Remember: ideal objects must be immutable and may not contain setters.   Instead, let’s talk about “constructor injection” (like in Google Guice) and its use with dependency injection containers. I’ll try to show why I consider these containers a redundancy, at least. What is Dependency Injection? This is what dependency injection is (not really different from a plain old object composition): public class Budget { private final DB db; public Budget(DB data) { this.db = data; } public long total() { return this.db.cell( "SELECT SUM(cost) FROM ledger" ); } } The object data is called a “dependency”. A Budget doesn’t know what kind of database it is working with. All it needs from the database is its ability to fetch a cell, using an arbitrary SQL query, via method cell(). We can instantiate a Budget with a PostgreSQL implementation of the DB interface, for example: public class App { public static void main(String... args) { Budget budget = new Budget( new Postgres("jdbc:postgresql:5740/main") ); System.out.println("Total is: " + budget.total()); } } In other words, we’re “injecting” a dependency into a new object budget. An alternative to this “dependency injection” approach would be to let Budget decide what database it wants to work with: public class Budget { private final DB db = new Postgres("jdbc:postgresql:5740/main"); // class methods } This is very dirty and leads to 1) code duplication, 2) inability to reuse, and 3) inability to test, etc. No need to discuss why. It’s obvious. Thus, dependency injection via a constructor is an amazing technique. Well, not even a technique, really. More like a feature of Java and all other object-oriented languages. It’s expected that almost any object will want to encapsulate some knowledge (aka, a “state”). That’s what constructors are for. What is a DI Container? So far so good, but here comes the dark side — a dependency injection container. Here is how it works (let’s use Google Guice as an example): import javax.inject.Inject; public class Budget { private final DB db; @Inject public Budget(DB data) { this.db = data; } // same methods as above } Pay attention: the constructor is annotated with @Inject. Then, we’re supposed to configure a container somewhere, when the application starts: Injector injector = Guice.createInjector( new AbstractModule() { @Override public void configure() { this.bind(DB.class).toInstance( new Postgres("jdbc:postgresql:5740/main") ); } } ); Some frameworks even allow us to configure the injector in an XML file. From now on, we are not allowed to instantiate Budget through the new operator, like we did before. Instead, we should use the injector we just created: public class App { public static void main(String... args) { Injection injector = // as we just did in the previous snippet Budget budget = injector.getInstance(Budget.class); System.out.println("Total is: " + budget.total()); } } The injection automatically finds out that in order to instantiate a Budget it has to provide an argument for its constructor. It will use an instance of class Postgres, which we instantiated in the injector. This is the right and recommended way to use Guice. There are a few even darker patterns, though, which are possible but not recommended. For example, you can make your injector a singleton and use it right inside the Budget class. These mechanisms are considered wrong even by DI container makers, however, so let’s ignore them and focus on the recommended scenario. What Is This For? Let me reiterate and summarize the scenarios of incorrect usage of dependency injection containers:Field injection Setter injection Passing injector as a dependency Making injector a global singletonIf we put all of them aside, all we have left is the constructor injection explained above. And how does that help us? Why do we need it? Why can’t we use plain old new in the main class of the application? The container we created simply adds more lines to the code base, or even more files, if we use XML. And it doesn’t add anything, except an additional complexity. We should always remember this if we have the question: “What database is used as an argument of a Budget?” The Right Way Now, let me show you a real life example of using new to construct an application. This is how we create a “thinking engine” in rultor.com (full class is in Agents.java): final Agent agent = new Agent.Iterative( new Array( new Understands( this.github, new QnSince( 49092213, new QnReferredTo( this.github.users().self().login(), new QnParametrized( new Question.FirstOf( new Array( new QnIfContains("config", new QnConfig(profile)), new QnIfContains("status", new QnStatus(talk)), new QnIfContains("version", new QnVersion()), new QnIfContains("hello", new QnHello()), new QnIfCollaborator( new QnAlone( talk, locks, new Question.FirstOf( new Array( new QnIfContains( "merge", new QnAskedBy( profile, Agents.commanders("merge"), new QnMerge() ) ), new QnIfContains( "deploy", new QnAskedBy( profile, Agents.commanders("deploy"), new QnDeploy() ) ), new QnIfContains( "release", new QnAskedBy( profile, Agents.commanders("release"), new QnRelease() ) ) ) ) ) ) ) ) ) ) ) ), new StartsRequest(profile), new RegistersShell( "b1.rultor.com", 22, "rultor", IOUtils.toString( this.getClass().getResourceAsStream("rultor.key"), CharEncoding.UTF_8 ) ), new StartsDaemon(profile), new KillsDaemon(TimeUnit.HOURS.toMinutes(2L)), new EndsDaemon(), new EndsRequest(), new Tweets( this.github, new OAuthTwitter( Manifests.read("Rultor-TwitterKey"), Manifests.read("Rultor-TwitterSecret"), Manifests.read("Rultor-TwitterToken"), Manifests.read("Rultor-TwitterTokenSecret") ) ), new CommentsTag(this.github), new Reports(this.github), new RemovesShell(), new ArchivesDaemon( new ReRegion( new Region.Simple( Manifests.read("Rultor-S3Key"), Manifests.read("Rultor-S3Secret") ) ).bucket(Manifests.read("Rultor-S3Bucket")) ), new Publishes(profile) ) ); Impressive? This is a true object composition. I believe this is how a proper object-oriented application should be instantiated. And DI containers? In my opinion, they just add unnecessary noise. Related Posts You may also find these posts interesting:Getters/Setters. Evil. Period. Anti-Patterns in OOP Avoid String Concatenation Objects Should Be Immutable Why NULL is Bad?Reference: DI Containers are Code Polluters from our JCG partner Yegor Bugayenko at the About Programming blog....
java-interview-questions-answers

JPA Tutorial: Mapping Entities – Part 2

In my last post I showed a simple way of persisting an entity. I explained the default approach that JPA uses to determine the default table for an entity. Let’s assume that we want to override this default name. We may like to do so because the data model has been designed and fixed before and the table names do not match with our class names (I have seen people to create tables with “tbl_” prefix, for example). So how should we override the default table names to match the existing data model? Turns out, it’s pretty simple. If we need to override the default table names assumed by JPA, then there are a couple of ways to do it:    We can use the name attribute of the @Entity annotation to provide an explicit entity name to match with the database table name. For our example we could have used @Entity(name = “tbl_address”) in our Address class if our table name was tbl_address. We can use a @Table (defined in the javax.persistence package) annotation just below the @Entity annotation and use its name attribute to specify the table name explicitly.@Entity @Table(name = "tbl_address") public class Address { // Rest of the class } From these two approaches the @Table annotation provides more options to customize the mapping. For example, some databases like PostgreSQL have a concept of schemas, using which you can further categorize/group your tables. Because of this feature you can create two tables with the same name in a single database (although they will belong to two different schemas). To access these tables you then add the schema name as the table prefix in your query. So if a PostgreSQL database has two different schemas named public (which is sort of like default schema for a PostgreSQL database) and document, and both of these schemas contain tables named document_collection, then both of these two queries are perfectly valid: -- fetch from the table under public schema SELECT * FROM public.document_collection;-- fetch from the table under document schema SELECT * FROM document.document_collection; In order to map an entity to the document_collection table in the document schema, you will then use the @Table annotation with its schema attribute set to document: @Entity @Table(name="document_collection", schema="document") public class DocumentCollection { // rest of the class } When specified this way, the schema name will be added as a prefix to the table name when the JPA goes to the database to access the table, just like we did in our queries. What if rather than specifying the schema name in the @Table annotation you append the schema name in the table name itself, like this: @Entity @Table(name = "document.document_collection") public class DocumentCollection { // rest of the class } Inlining the schema name with the table name this way is not guaranteed to work across all JPA implementations because support for this is not specified in the JPA specification (non-standard). So it’s better if you do not make a habit of doing this even if your persistence provider supports it. Let’s turn our attention to the columns next. In order to determine the default columns, JPA does something similar to the following:At first it checks to see if any explicit column mapping information is given. If no column mapping information is found, it tries to guess the default values for columns. To determine the default values, JPA needs to know the access type of the entity states i.e., the way to read/write the states of the entity. In JPA two different access types are possible – field and property. For our example we have used the field access (actually JPA assumed this from the location/placement of the @Id annotation,  but more on this later). If you use this access type then states will be written/read directly from the entity fields using the Reflection API. After the access type is known, JPA then tries to determine the column names. For field access type JPA directly treats the field name as the column names, which means if an entity has a field named status then it will be mapped to a column named status.At this point it should be clear to us how the states of the Address entities got saved into the corresponding columns. Each of the fields of the Address entity has an equivalent column in the database table tbl_address, so JPA directly saved them into their corresponding columns. The id field was saved into the id column, city field into the city column and so on. OK then, let’s move on to overriding column names. As far as I know there is only one way (if you happen to know of any other way please comment in!) to override the default column names for entity states, which is by using the @Column (defined in the javax.persistence package) annotation. So if the id column of the tbl_address table is renamed to be address_id then we could either change our field name to address_id, or we could use the @Column annotation with its name attribute set to address_id: @Entity @Table(name = "tbl_address") public class Address { @Id @GeneratedValue @Column(name = "address_id") private Integer id;// Rest of the class } You can see that for all the above cases the default approaches that JPA uses are quite sensible, and most of the cases you will be happy with it. However, changing the default values are also very easy and can be done very quickly. What if we have a field in the Address entity that we do not wish to save in the database? Suppose that the Address entity has a column named transientColumn which does not have any corresponding default column in the database table: @Entity @Table(name = "tbl_address") public class Address { @Id @GeneratedValue @Column(name = "address_id") private Integer id;private String street; private String city; private String province; private String country; private String postcode; private String transientColumn;// Rest of the class } If you compile your code with the above change then you will get an exception which looks something like below:Exception in thread “main” java.lang.ExceptionInInitializerError at com.keertimaan.javasamples.jpaexample.Main.main(Main.java:33) Caused by: javax.persistence.PersistenceException: Unable to build entity manager factory at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:83) at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:54) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39) at com.keertimaan.javasamples.jpaexample.persistenceutil.PersistenceManager.<init>(PersistenceManager.java:31) at com.keertimaan.javasamples.jpaexample.persistenceutil.PersistenceManager.<clinit>(PersistenceManager.java:26) … 1 more Caused by: org.hibernate.HibernateException: Missing column: transientColumn in jpa_example.tbl_address at org.hibernate.mapping.Table.validateColumns(Table.java:365) at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1336) at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:155) at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:525) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1857) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:843) at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:842) at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:75) … 6 moreThe exception is saying that the persistence provider could not find any column in the database whose name is transientColumn, and we did not do anything to make it clear to the persistence provider that we do not wish to save this field in the database. The persistence provider took it as any other fields in the entity which are mapped to database columns. In order to fix this problem, we can do any of the following:We can annotate the transientColumn field with the @Transient (defined in javax.persistence package) annotation to let the persistence provider know that we do not wish to save this field, and it does not have any corresponding column in the table. We can use the transient keyword that Java has by default.The difference between these two approaches that comes to my mind is that, if we use the transient keyword instead of the annotation, then if one of the Address entities gets serialized from one JVM to another then the transientColumn field will get reinitialized again (just like any other transient fields in Java). For the annotation, this will not happen and the transientColumn field will retain its value across the serialization. As a rule of thumb, I always use the annotation if I do not need to worry about serialization (and in most of the cases I don’t). So using the annotation, we can fix the problem right away: @Entity @Table(name = "tbl_address") public class Address { @Id @GeneratedValue @Column(name = "address_id") private Integer id;private String street; private String city; private String province; private String country; private String postcode;@Transient private String transientColumn;// Rest of the class } So that’s it for today folks. If you find any mistakes/have any input, please feel free to comment in! Until next time.Reference: JPA Tutorial: Mapping Entities – Part 2 from our JCG partner Sayem Ahmed at the Random Thoughts blog....
software-development-2-logo

Logical vs physical clock optimistic locking

Introduction In my previous post I demonstrated why optimistic locking is the only viable solution for application-level transactions. Optimistic locking requires a version column that can be represented as:a physical clock (a timestamp value taken from the system clock) a logical clock (an incrementing numeric value)This article will demonstrate why logical clocks are better suited for optimistic locking mechanisms. System time The system time is provided by the operating system internal clocking algorithm. The programmable interval timer periodically sends an interrupt signal (with a frequency of 1.193182 MHz). The CPU receives the time interruption and increments a tick counter. Both Unix and Window record time as the number of ticks since a predefined absolute time reference (an epoch). The operating system clock resolution varies from 1ms (Android) to 100ns (Windows) and to 1ns (Unix). Monotonic time To order events, the version must advance monotonically. While incrementing a local counter is a monotonic function, system time might not always return monotonic timestamps. Java has two ways of fetching the current system time. You can either use:System#currentTimeMillis(), that gives you the number of milliseconds elapsed since Unix epochThis method doesn’t give you monotonic time results because it returns the wall clock time which is prone to both forward and backward adjustments (if NTP is used for system time synchronization).For monotonic currentTimeMillis, you can check Peter Lawrey’s solution or Bitronix Transaction Manager Monotonic Clock. System#nanoTime(), that returns the number of nanoseconds elapsed since an arbitrarily chosen time referenceThis method tries to use the current operating system monotonic clock implementation, but it falls back to wall clock time if no monotonic clock could be found. Argument 1: System time is not always monotonically incremented. Database timestamp precision The SQL-92 standard defines the TIMESTAMP data type as YYYY-MM-DD hh:mm:ss. The fraction part is optional and each database implements a specific timestamp data type:RDBMS Timestamp resolutionOracle TIMESTAMP(9) may use up to 9 fractional digits (nano second precision).MSSQL DATETIME2 has a precision of 100ns.MySQL MySQL 5.6.4 added microseconds precision support for TIME, DATETIME, and TIMESTAMP types (e.g. TIMESTAMP(6)). Previous MySQL versions discard the fractional part of all temporal types.PostgreSQL Both TIME and TIMESTAMP types have microsecond precision.DB2 TIMESTAMP(12) may use up to 12 fractional digits (picosecond precision).When it comes to persisting timestamps, most database servers offer at least 6 fractional digits. MySQL users have long been waiting for a more precise temporal type and the 5.6.4 version had finally added microsecond precision. On a pre-5.6.4 MySQL database server, updates might be lost during the lifespan of any given second. That’s because all transactions updating the same database row will see the same version timestamp (which points to the beginning of the current running second). Argument 2: Pre-5.6.4 MySQL versions only support second precision timestamps. Handling time is not that easy Incrementing a local version number is always safer because this operation doesn’t depends on any external factors. If the database row already contains a higher version number your data has become stale. It’s as simple as that. On the other hand, time is one of the most complicated dimension to deal with. If you don’t believe me, check the for daylight saving time handling considerations. It took 8 versions for Java to finally come up with a mature Date/Time API. Handling time across application layers (from JavaScript, to Java middle-ware to database date/time types) makes matters worse. Argument 3: Handling system time is a challenging job. You have to hanlde leap seconds, daylight saving, time zones and various time standards. Lessons from distributed computing Optimistic locking is all about event ordering, so naturally we’re only interested in the happened-before relationship. In distributed computing, logical clocks are favored over physical ones (system clock), because networks time synchronization implies variable latencies. Sequence number versioning is similar to Lamport timestamps algorithm, each event incrementing only one counter. While Lamport timestamps was defined for multiple distributed nodes event synchronization, database optimistic locking is much simpler, because there is only on node (the database server) where all transactions are synchronized (coming from concurrent client connections). Argument 4: Distributed computing favors logical clock over physical ones, because we are only interested in event ordering anyway. Conclusion Using physical time might seem convenient at first, but it turns out to be a naive solution. In a distributed environment, perfect system time synchronization is mostly unlikely. All in all, you should always prefer logical clocks when implementing an optimistic locking mechanism.Reference: Logical vs physical clock optimistic locking from our JCG partner Vlad Mihalcea at the Vlad Mihalcea’s Blog blog....
agile-logo

Six Tips for Interviewing Scrum Masters, Part 2

Now that you know what you expect from your Scrum Master’s job (the deliverables), and you know the essential and desirable skills (the first three tips), you can focus on creating the interview questions and audition. (If you have not yet read Six Tips for Interviewing Scrum Masters, Part 1 for the first three tips, please do so now.) Tip 4: Create Behavior-Description Questions for Your Scrum Master Based on Essential Qualities, Preferences, and Non-Technical Skills For initiative, you might ask behavior-description questions like these:Give me an example of a recent time you thought the team was stuck. How did you know the team was stuck and what did you do? (You want to know if the SM was command-and-control, interfering or helpful.) Tell me about a time when your Product Owner was convinced the story was as small as possible, but the story was a month long. Have you encountered something like this? (Maybe a month is longer than what the candidate encountered. Maybe it wasn’t the PO. Listen to their experience.) What happened? (Listen for what the SM did or did not do. Different Scrum Masters facilitate differently. There Is No Right Answer.) Tell me about a recent time the team had many stories in progress and didn’t finish at the end of a sprint. What happened? (Listen for what the SM did or did not do. Different Scrum Masters facilitate differently. There Is No Right Answer.)For flexibility, consider these questions:What do you consider negotiable in a Scrum team? Why? Give me a recent example of that flexibility. Give me an example of a time you and the team were stymied by something. What happened? Have you ever needed to compromise as a Scrum Master? Tell me about it.Again, you have to listen for the context and what the Scrum Master did in the different context for the project and the organization. There is no right answer. There are answers that don’t fit your context. Make sure you keep reading down to see my question about learning from past experiences. For perseverance, you might like these questions:Tell me about a time you advocated for something you wanted. Tell me about a work obstacle you had to overcome. Tell me about a time you had to maintain focus when it seemed everyone else was losing their focus.Do you see the pattern? Apply behavior-description questions to your essential qualities, preferences and non-technical skills. Tip 5: Create at Least One Audition Based on Deliverables Back in Six Tips for Interviewing Scrum Masters, Part 1, I said that you needed to define deliverables. I suggested a potential list of 10 deliverables. You might have these candidate auditions:Facilitate a standup Facilitate a retrospective Look at a Scrum board and tell you what it means Look at a team’s measurements and tell you what they meanI’m not saying these are the best auditions, because I don’t know what you need Your Scrum Master to do. These are candidate auditions. I have a lot more about how to create auditions in Hiring Geeks That Fit. Tip 6: Ignore Certifications and Look for the Growth Mindset I have never been a fan of certifications. If I have to choose between a candidate with a certification and a candidate with a growth mindset, I’ll select the candidate with the growth mindset. (Remember, you can buy a certification by taking a class. That’s it.) Certifications are good for learning. They are not good for helping people prove they have executed anything successfully. When you interview for the growth mindset, you ask behavior-description questions. When they answer in a way that intrigues you, you ask, “What did you learn from that?” (a reflective hypothetical question). Then ask, “How have you put that learning into practice?” (a behavior-description question). Now, you have yourself a terrific conversation, which is the basis for a great interview. Okay, there are my six tips for hiring a Scrum Master. If you want to understand how to hire without fear, read Hiring Geeks That Fit.Reference: Six Tips for Interviewing Scrum Masters, Part 2 from our JCG partner Johanna Rothman at the Managing Product Development blog....
software-development-2-logo

Chained Access Delegation Pattern

Suppose a medium-scale enterprise that sells bottled water has a RESTful API (Water API) that can be used to update the amount of water consumed by a registered user. Any registered user can access the API via any client application. It could be an Android app, an iOS app, or even a web application. The company only provides the API—anyone can develop client applications to consume it. All the user data is stored in Microsoft Active Directory. Client applications shouldn’t be able to access the API directly and query to find out information about users. Only registered users can access the API. These users shouldn’t be able to see other users’ information. At the same time, for each update made by a user, the Water API must update the user’s healthcare record maintained at MyHealth.org. The user also has a personal record at MyHealth.org, and it too exposes an API (MyHealth API). The Water API has to call the MyHealth API to update the user record on the user’s behalf. In summary, a mobile application accesses the Water API on behalf of the end user, and then the Water API has to access the MyHealth API on behalf of the end user. The Water API and the MyHealth API are in two independent domains. This suggests the need for an access-delegation protocol. Again, the catch here is the statement, “the Water API must also update the user’s healthcare record maintained at MyHealth.org.” The challenge has two solutions. In the first solution, the end user must get an access token from MyHealth.org for the Water API (the Water API acts as the OAuth client), and then the Water API must store the token internally according to the user’s name. Whenever the user sends an update through a mobile application to the Water API, the app first updates its own record and then finds the MyHealth access token corresponding to the end user and uses it to access the MyHealth API. With this approach, the Water API has the overhead of storing the MyHealth API access token, and it should refresh the access token whenever needed. The second solution is explained in the above figure. It’s built around the OAuth 2.0 Chain Grant Type profile. The mobile app must carry a valid access token to access the Water API on behalf of the end user. In step 3, the Water API talks to its own authorization server to validate the access token. Then, in step 4, the Water API exchanges the access token it got from the mobile application for a JWT access token. The JWT access token is a special access token that carries some meaningful data, and it’s also signed by the authorization server in the Water API’s domain. The JWT includes the end user’s local identifier as well as its mapping identifier in the MyHealth domain. The end user must permit this action at the Water API domain. In step 6, the Water API accesses the MyHealth API using the JWT access token. The MyHealth API validates the JWT access token by talking to its own authorization server. It verifies the signature; and, if it’s signed by a trusted entity, the access token is treated as valid. Because the JWT includes the mapping username from the MyHealth domain, it can identify the corresponding local user record. However, this raises a security concern. If you let users update their profiles in the Water API domain with the mapping MyHealth identifier, they can map it to any user identifier, and this leads to a security hole. To avoid that, the account-mapping step must initiate an OpenID Connect authentication with the MyHealth domain. When the user wants to add their MyHealth account identifier, the Water API domain initiates the OpenID Connect authentication flow and receives the corresponding ID token. Then the account mapping is done with the user identifier in the ID token. This is one of the ten API security patterns covered in my book Advanced API Security. You can find more details about this from the book.Reference: Chained Access Delegation Pattern from our JCG partner Prabath Siriwardena at the Facile Login blog....
jboss-drools-logo

Trace output with Drools

Drools 6 includes a trace output that can help get an idea of what is going on in your system,  and how often things are getting executed, and with how much data. It can also help to understand that Drools 6 is now a goal based algorithm, using a linking mechanism to link in rules for evaluation. More details on that here: http://www.javacodegeeks.com/2013/11/r-i-p-rete-time-to-get-phreaky.html The first thing to do is set your slf4j logger to trace mode:       <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <!-- %l lowers performance --> <!--<pattern>%d [%t] %-5p %l%n %m%n</pattern>--> <pattern>%d [%t] %-5p %m%n</pattern> </encoder> </appender><logger name="org.drools" level="trace"/><root level="info"><!-- TODO We probably want to set default level to warn instead --> <appender-ref ref="consoleAppender" /> </root> </configuration> Let’s take the shopping example, you can find the Java and Drl files for this here:https://github.com/droolsjbpm/drools/blob/master/drools-examples/src/main/resources/org/drools/examples/shopping/Shopping.drl https://github.com/droolsjbpm/drools/blob/master/drools-examples/src/main/java/org/drools/examples/shopping/ShoppingExample.javaRunning the example will give output a very detailed and long log of execution. Initially you’ll see objects being inserted, which causes linking. Linking of nodes and rules is explained in the Drools 6 algorithm link. In summary 1..n nodes link in a segment, when object are are inserted. 2014-10-02 02:35:09,009 [main] TRACE Insert [fact 0:1:1455177644:1455177644:1:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Customer@56bc3fac] 2014-10-02 02:35:09,020 [main] TRACE LinkNode notify=false nmask=1 smask=1 spos=0 rules= Then 1..n segments link in a rule. When a Rule is linked in it’s schedule on the agenda for evaluation. 2014-10-02 02:35:09,043 [main] TRACE LinkRule name=Discount removed notification 2014-10-02 02:35:09,043 [main] TRACE Queue RuleAgendaItem [Activation rule=Discount removed notification, act#=0, salience=0, tuple=null] 2014-10-02 02:35:09,043 [main] TRACE Queue Added 1 [Activation rule=Discount removed notification, act#=0, salience=0, tuple=null] When it eventually evaluates a rule it will indent as it visits each node, as it evaluate from root to tip. Each node will attempt to tell you how much data is being inserted, updated or deleted at that point. 2014-10-02 02:35:09,046 [main] TRACE Rule[name=Apply 10% discount if total purchases is over 100] segments=2 TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,047 [main] TRACE 1 [ AccumulateNode(12) ] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,047 [main] TRACE Segment 1 2014-10-02 02:35:09,047 [main] TRACE 1 [ AccumulateNode(12) ] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,047 [main] TRACE rightTuples TupleSets[insertSize=2, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,056 [main] TRACE 2 [RuleTerminalNode(13): rule=Apply 10% discount if total purchases is over 100] TupleSets[insertSize=1, deleteSize=0, updateSize=0] You can use this information to see how often rules evaluate, how much linking and unlinking happens, how much data propagates and more important how much wasted work is done.  Here is the full log: 2014-10-02 02:35:08,889 [main] DEBUG Starting Engine in PHREAK mode 2014-10-02 02:35:08,927 [main] TRACE Adding Rule Purchase notification 2014-10-02 02:35:08,929 [main] TRACE Adding Rule Discount removed notification 2014-10-02 02:35:08,931 [main] TRACE Adding Rule Discount awarded notification 2014-10-02 02:35:08,933 [main] TRACE Adding Rule Apply 10% discount if total purchases is over 100 2014-10-02 02:35:09,009 [main] TRACE Insert [fact 0:1:1455177644:1455177644:1:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Customer@56bc3fac] 2014-10-02 02:35:09,020 [main] TRACE LinkNode notify=false nmask=1 smask=1 spos=0 rules= 2014-10-02 02:35:09,020 [main] TRACE LinkSegment smask=2 rmask=2 name=Discount removed notification 2014-10-02 02:35:09,025 [main] TRACE LinkSegment smask=2 rmask=2 name=Apply 10% discount if total purchases is over 100 2014-10-02 02:35:09,028 [main] TRACE LinkNode notify=true nmask=1 smask=1 spos=0 rules=[RuleMem Purchase notification], [RuleMem Discount removed notification], [RuleMem Discount awarded notification], [RuleMem Apply 10% discount if total purchases is over 100] 2014-10-02 02:35:09,028 [main] TRACE LinkSegment smask=1 rmask=1 name=Purchase notification 2014-10-02 02:35:09,028 [main] TRACE LinkSegment smask=1 rmask=3 name=Discount removed notification 2014-10-02 02:35:09,043 [main] TRACE LinkRule name=Discount removed notification 2014-10-02 02:35:09,043 [main] TRACE Queue RuleAgendaItem [Activation rule=Discount removed notification, act#=0, salience=0, tuple=null] 2014-10-02 02:35:09,043 [main] TRACE Queue Added 1 [Activation rule=Discount removed notification, act#=0, salience=0, tuple=null] 2014-10-02 02:35:09,043 [main] TRACE LinkSegment smask=1 rmask=1 name=Discount awarded notification 2014-10-02 02:35:09,043 [main] TRACE LinkSegment smask=1 rmask=3 name=Apply 10% discount if total purchases is over 100 2014-10-02 02:35:09,043 [main] TRACE LinkRule name=Apply 10% discount if total purchases is over 100 2014-10-02 02:35:09,043 [main] TRACE Queue RuleAgendaItem [Activation rule=Apply 10% discount if total purchases is over 100, act#=1, salience=0, tuple=null] 2014-10-02 02:35:09,043 [main] TRACE Queue Added 2 [Activation rule=Apply 10% discount if total purchases is over 100, act#=1, salience=0, tuple=null] 2014-10-02 02:35:09,043 [main] TRACE Added Apply 10% discount if total purchases is over 100 to eager evaluation list. 2014-10-02 02:35:09,044 [main] TRACE Insert [fact 0:2:14633842:14633842:2:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Product@df4b72] 2014-10-02 02:35:09,044 [main] TRACE Insert [fact 0:3:732189840:732189840:3:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Product@2ba45490] 2014-10-02 02:35:09,044 [main] TRACE Insert [fact 0:4:939475028:939475028:4:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Purchase@37ff4054] 2014-10-02 02:35:09,045 [main] TRACE BetaNode insert=1 stagedInsertWasEmpty=true 2014-10-02 02:35:09,045 [main] TRACE LinkNode notify=true nmask=1 smask=1 spos=1 rules=[RuleMem Purchase notification] 2014-10-02 02:35:09,045 [main] TRACE LinkSegment smask=2 rmask=3 name=Purchase notification 2014-10-02 02:35:09,045 [main] TRACE LinkRule name=Purchase notification 2014-10-02 02:35:09,046 [main] TRACE Queue RuleAgendaItem [Activation rule=Purchase notification, act#=2, salience=10, tuple=null] 2014-10-02 02:35:09,046 [main] TRACE Queue Added 1 [Activation rule=Purchase notification, act#=2, salience=10, tuple=null] 2014-10-02 02:35:09,046 [main] TRACE BetaNode insert=1 stagedInsertWasEmpty=true 2014-10-02 02:35:09,046 [main] TRACE LinkNode notify=true nmask=1 smask=1 spos=1 rules=[RuleMem Apply 10% discount if total purchases is over 100] 2014-10-02 02:35:09,046 [main] TRACE LinkSegment smask=2 rmask=3 name=Apply 10% discount if total purchases is over 100 2014-10-02 02:35:09,046 [main] TRACE LinkRule name=Apply 10% discount if total purchases is over 100 2014-10-02 02:35:09,046 [main] TRACE Added Apply 10% discount if total purchases is over 100 to eager evaluation list. 2014-10-02 02:35:09,046 [main] TRACE Insert [fact 0:5:8996952:8996952:5:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Purchase@894858] 2014-10-02 02:35:09,046 [main] TRACE BetaNode insert=2 stagedInsertWasEmpty=false 2014-10-02 02:35:09,046 [main] TRACE BetaNode insert=2 stagedInsertWasEmpty=false 2014-10-02 02:35:09,046 [main] TRACE Rule[name=Apply 10% discount if total purchases is over 100] segments=2 TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,047 [main] TRACE 1 [ AccumulateNode(12) ] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,047 [main] TRACE Segment 1 2014-10-02 02:35:09,047 [main] TRACE 1 [ AccumulateNode(12) ] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,047 [main] TRACE rightTuples TupleSets[insertSize=2, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,056 [main] TRACE 2 [RuleTerminalNode(13): rule=Apply 10% discount if total purchases is over 100] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,057 [main] TRACE Segment 1 2014-10-02 02:35:09,057 [main] TRACE 2 [RuleTerminalNode(13): rule=Apply 10% discount if total purchases is over 100] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,057 [main] TRACE Rule[name=Apply 10% discount if total purchases is over 100] segments=2 TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,057 [main] TRACE 3 [ AccumulateNode(12) ] TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,057 [main] TRACE Rule[name=Purchase notification] segments=2 TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,057 [main] TRACE 4 [JoinNode(5) - [ClassObjectType class=org.drools.examples.shopping.ShoppingExample$Purchase]] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,057 [main] TRACE Segment 1 2014-10-02 02:35:09,057 [main] TRACE 4 [JoinNode(5) - [ClassObjectType class=org.drools.examples.shopping.ShoppingExample$Purchase]] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,058 [main] TRACE rightTuples TupleSets[insertSize=2, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,058 [main] TRACE 5 [RuleTerminalNode(6): rule=Purchase notification] TupleSets[insertSize=2, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,058 [main] TRACE Segment 1 2014-10-02 02:35:09,058 [main] TRACE 5 [RuleTerminalNode(6): rule=Purchase notification] TupleSets[insertSize=2, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,058 [main] TRACE Fire "Purchase notification" [[ Purchase notification active=false ] [ [fact 0:4:939475028:939475028:4:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Purchase@37ff4054] [fact 0:1:1455177644:1455177644:1:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Customer@56bc3fac] ] ] Customer mark just purchased shoes 2014-10-02 02:35:09,060 [main] TRACE Fire "Purchase notification" [[ Purchase notification active=false ] [ [fact 0:5:8996952:8996952:5:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Purchase@894858] [fact 0:1:1455177644:1455177644:1:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Customer@56bc3fac] ] ] Customer mark just purchased hat 2014-10-02 02:35:09,061 [main] TRACE Removing RuleAgendaItem [Activation rule=Purchase notification, act#=2, salience=10, tuple=null] 2014-10-02 02:35:09,061 [main] TRACE Queue Removed 1 [Activation rule=Purchase notification, act#=2, salience=10, tuple=null] 2014-10-02 02:35:09,061 [main] TRACE Rule[name=Discount removed notification] segments=2 TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,061 [main] TRACE 6 [NotNode(8) - [ClassObjectType class=org.drools.examples.shopping.ShoppingExample$Discount]] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,061 [main] TRACE Segment 1 2014-10-02 02:35:09,061 [main] TRACE 6 [NotNode(8) - [ClassObjectType class=org.drools.examples.shopping.ShoppingExample$Discount]] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,061 [main] TRACE rightTuples TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,061 [main] TRACE 7 [RuleTerminalNode(9): rule=Discount removed notification] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,061 [main] TRACE Segment 1 2014-10-02 02:35:09,061 [main] TRACE 7 [RuleTerminalNode(9): rule=Discount removed notification] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,061 [main] TRACE Fire "Discount removed notification" [[ Discount removed notification active=false ] [ null [fact 0:1:1455177644:1455177644:1:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Customer@56bc3fac] ] ] Customer mark now has a discount of 0 2014-10-02 02:35:09,063 [main] TRACE Removing RuleAgendaItem [Activation rule=Discount removed notification, act#=0, salience=0, tuple=null] 2014-10-02 02:35:09,063 [main] TRACE Queue Removed 1 [Activation rule=Discount removed notification, act#=0, salience=0, tuple=null] 2014-10-02 02:35:09,063 [main] TRACE Fire "Apply 10% discount if total purchases is over 100" [[ Apply 10% discount if total purchases is over 100 active=false ] [ [fact 0:6:2063009760:1079902208:6:null:NON_TRAIT:120.0] [fact 0:1:1455177644:1455177644:1:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Customer@56bc3fac] ] ] 2014-10-02 02:35:09,071 [main] TRACE Insert [fact 0:7:874153561:874153561:7:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Discount@341a8659] 2014-10-02 02:35:09,071 [main] TRACE LinkSegment smask=2 rmask=3 name=Discount removed notification 2014-10-02 02:35:09,071 [main] TRACE LinkRule name=Discount removed notification 2014-10-02 02:35:09,071 [main] TRACE Queue RuleAgendaItem [Activation rule=Discount removed notification, act#=0, salience=0, tuple=null] 2014-10-02 02:35:09,071 [main] TRACE Queue Added 1 [Activation rule=Discount removed notification, act#=0, salience=0, tuple=null] 2014-10-02 02:35:09,071 [main] TRACE BetaNode insert=1 stagedInsertWasEmpty=true 2014-10-02 02:35:09,071 [main] TRACE LinkNode notify=true nmask=1 smask=1 spos=1 rules=[RuleMem Discount awarded notification] 2014-10-02 02:35:09,071 [main] TRACE LinkSegment smask=2 rmask=3 name=Discount awarded notification 2014-10-02 02:35:09,071 [main] TRACE LinkRule name=Discount awarded notification 2014-10-02 02:35:09,071 [main] TRACE Queue RuleAgendaItem [Activation rule=Discount awarded notification, act#=7, salience=0, tuple=null] 2014-10-02 02:35:09,071 [main] TRACE Queue Added 3 [Activation rule=Discount awarded notification, act#=7, salience=0, tuple=null] Customer mark now has a shopping total of 120.0 2014-10-02 02:35:09,071 [main] TRACE Removing RuleAgendaItem [Activation rule=Apply 10% discount if total purchases is over 100, act#=1, salience=0, tuple=null] 2014-10-02 02:35:09,071 [main] TRACE Queue Removed 2 [Activation rule=Apply 10% discount if total purchases is over 100, act#=1, salience=0, tuple=null] 2014-10-02 02:35:09,071 [main] TRACE Rule[name=Discount removed notification] segments=2 TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,072 [main] TRACE 8 [NotNode(8) - [ClassObjectType class=org.drools.examples.shopping.ShoppingExample$Discount]] TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,072 [main] TRACE Segment 1 2014-10-02 02:35:09,072 [main] TRACE 8 [NotNode(8) - [ClassObjectType class=org.drools.examples.shopping.ShoppingExample$Discount]] TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,072 [main] TRACE rightTuples TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,073 [main] TRACE 9 [RuleTerminalNode(9): rule=Discount removed notification] TupleSets[insertSize=0, deleteSize=1, updateSize=0] 2014-10-02 02:35:09,073 [main] TRACE Segment 1 2014-10-02 02:35:09,073 [main] TRACE 9 [RuleTerminalNode(9): rule=Discount removed notification] TupleSets[insertSize=0, deleteSize=1, updateSize=0] 2014-10-02 02:35:09,073 [main] TRACE Removing RuleAgendaItem [Activation rule=Discount removed notification, act#=0, salience=0, tuple=null] 2014-10-02 02:35:09,073 [main] TRACE Queue Removed 1 [Activation rule=Discount removed notification, act#=0, salience=0, tuple=null] 2014-10-02 02:35:09,073 [main] TRACE Rule[name=Discount awarded notification] segments=2 TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,073 [main] TRACE 10 [JoinNode(10) - [ClassObjectType class=org.drools.examples.shopping.ShoppingExample$Discount]] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,073 [main] TRACE Segment 1 2014-10-02 02:35:09,073 [main] TRACE 10 [JoinNode(10) - [ClassObjectType class=org.drools.examples.shopping.ShoppingExample$Discount]] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,074 [main] TRACE rightTuples TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,074 [main] TRACE 11 [RuleTerminalNode(11): rule=Discount awarded notification] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,074 [main] TRACE Segment 1 2014-10-02 02:35:09,074 [main] TRACE 11 [RuleTerminalNode(11): rule=Discount awarded notification] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,074 [main] TRACE Fire "Discount awarded notification" [[ Discount awarded notification active=false ] [ [fact 0:7:874153561:874153561:7:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Discount@341a8659] [fact 0:1:1455177644:1455177644:1:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Customer@56bc3fac] ] ] Customer mark now has a discount of 10 2014-10-02 02:35:09,074 [main] TRACE Removing RuleAgendaItem [Activation rule=Discount awarded notification, act#=7, salience=0, tuple=null] 2014-10-02 02:35:09,074 [main] TRACE Queue Removed 1 [Activation rule=Discount awarded notification, act#=7, salience=0, tuple=null] 2014-10-02 02:35:09,074 [main] TRACE Delete [fact 0:5:8996952:8996952:5:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Purchase@894858] 2014-10-02 02:35:09,074 [main] TRACE LinkSegment smask=2 rmask=3 name=Purchase notification 2014-10-02 02:35:09,074 [main] TRACE LinkRule name=Purchase notification 2014-10-02 02:35:09,074 [main] TRACE Queue RuleAgendaItem [Activation rule=Purchase notification, act#=2, salience=10, tuple=null] 2014-10-02 02:35:09,074 [main] TRACE Queue Added 1 [Activation rule=Purchase notification, act#=2, salience=10, tuple=null] 2014-10-02 02:35:09,075 [main] TRACE LinkSegment smask=2 rmask=3 name=Apply 10% discount if total purchases is over 100 2014-10-02 02:35:09,075 [main] TRACE LinkRule name=Apply 10% discount if total purchases is over 100 2014-10-02 02:35:09,075 [main] TRACE Queue RuleAgendaItem [Activation rule=Apply 10% discount if total purchases is over 100, act#=1, salience=0, tuple=null] 2014-10-02 02:35:09,075 [main] TRACE Queue Added 2 [Activation rule=Apply 10% discount if total purchases is over 100, act#=1, salience=0, tuple=null] 2014-10-02 02:35:09,075 [main] TRACE Added Apply 10% discount if total purchases is over 100 to eager evaluation list. Customer mark has returned the hat 2014-10-02 02:35:09,075 [main] TRACE Rule[name=Apply 10% discount if total purchases is over 100] segments=2 TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,075 [main] TRACE 12 [ AccumulateNode(12) ] TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,075 [main] TRACE Segment 1 2014-10-02 02:35:09,075 [main] TRACE 12 [ AccumulateNode(12) ] TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,075 [main] TRACE rightTuples TupleSets[insertSize=0, deleteSize=1, updateSize=0] 2014-10-02 02:35:09,075 [main] TRACE 13 [RuleTerminalNode(13): rule=Apply 10% discount if total purchases is over 100] TupleSets[insertSize=0, deleteSize=1, updateSize=0] 2014-10-02 02:35:09,075 [main] TRACE Segment 1 2014-10-02 02:35:09,075 [main] TRACE 13 [RuleTerminalNode(13): rule=Apply 10% discount if total purchases is over 100] TupleSets[insertSize=0, deleteSize=1, updateSize=0] 2014-10-02 02:35:09,075 [main] TRACE Delete [fact 0:7:874153561:874153561:7:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Discount@341a8659] 2014-10-02 02:35:09,075 [main] TRACE LinkSegment smask=2 rmask=3 name=Discount removed notification 2014-10-02 02:35:09,075 [main] TRACE LinkRule name=Discount removed notification 2014-10-02 02:35:09,075 [main] TRACE Queue RuleAgendaItem [Activation rule=Discount removed notification, act#=0, salience=0, tuple=null] 2014-10-02 02:35:09,075 [main] TRACE Queue Added 3 [Activation rule=Discount removed notification, act#=0, salience=0, tuple=null] 2014-10-02 02:35:09,075 [main] TRACE UnlinkNode notify=true nmask=1 smask=0 spos=1 rules=[RuleMem Discount awarded notification] 2014-10-02 02:35:09,076 [main] TRACE UnlinkSegment smask=2 rmask=1 name=[RuleMem Discount awarded notification] 2014-10-02 02:35:09,076 [main] TRACE UnlinkRule name=Discount awarded notification 2014-10-02 02:35:09,076 [main] TRACE Queue RuleAgendaItem [Activation rule=Discount awarded notification, act#=7, salience=0, tuple=null] 2014-10-02 02:35:09,076 [main] TRACE Queue Added 2 [Activation rule=Discount awarded notification, act#=7, salience=0, tuple=null] 2014-10-02 02:35:09,076 [main] TRACE Rule[name=Purchase notification] segments=2 TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,076 [main] TRACE 14 [JoinNode(5) - [ClassObjectType class=org.drools.examples.shopping.ShoppingExample$Purchase]] TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,076 [main] TRACE Segment 1 2014-10-02 02:35:09,076 [main] TRACE 14 [JoinNode(5) - [ClassObjectType class=org.drools.examples.shopping.ShoppingExample$Purchase]] TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,076 [main] TRACE rightTuples TupleSets[insertSize=0, deleteSize=1, updateSize=0] 2014-10-02 02:35:09,076 [main] TRACE 15 [RuleTerminalNode(6): rule=Purchase notification] TupleSets[insertSize=0, deleteSize=1, updateSize=0] 2014-10-02 02:35:09,076 [main] TRACE Segment 1 2014-10-02 02:35:09,076 [main] TRACE 15 [RuleTerminalNode(6): rule=Purchase notification] TupleSets[insertSize=0, deleteSize=1, updateSize=0] 2014-10-02 02:35:09,076 [main] TRACE Removing RuleAgendaItem [Activation rule=Purchase notification, act#=2, salience=10, tuple=null] 2014-10-02 02:35:09,076 [main] TRACE Queue Removed 1 [Activation rule=Purchase notification, act#=2, salience=10, tuple=null] 2014-10-02 02:35:09,076 [main] TRACE Rule[name=Discount removed notification] segments=2 TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,076 [main] TRACE 16 [NotNode(8) - [ClassObjectType class=org.drools.examples.shopping.ShoppingExample$Discount]] TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,076 [main] TRACE Segment 1 2014-10-02 02:35:09,076 [main] TRACE 16 [NotNode(8) - [ClassObjectType class=org.drools.examples.shopping.ShoppingExample$Discount]] TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,076 [main] TRACE rightTuples TupleSets[insertSize=0, deleteSize=1, updateSize=0] 2014-10-02 02:35:09,077 [main] TRACE 17 [RuleTerminalNode(9): rule=Discount removed notification] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,077 [main] TRACE Segment 1 2014-10-02 02:35:09,077 [main] TRACE 17 [RuleTerminalNode(9): rule=Discount removed notification] TupleSets[insertSize=1, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,077 [main] TRACE Fire "Discount removed notification" [[ Discount removed notification active=false ] [ null [fact 0:1:1455177644:1455177644:1:DEFAULT:NON_TRAIT:org.drools.examples.shopping.ShoppingExample$Customer@56bc3fac] ] ] Customer mark now has a discount of 0 2014-10-02 02:35:09,077 [main] TRACE Removing RuleAgendaItem [Activation rule=Discount removed notification, act#=0, salience=0, tuple=null] 2014-10-02 02:35:09,077 [main] TRACE Queue Removed 1 [Activation rule=Discount removed notification, act#=0, salience=0, tuple=null] 2014-10-02 02:35:09,077 [main] TRACE Rule[name=Discount awarded notification] segments=2 TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,077 [main] TRACE 18 [JoinNode(10) - [ClassObjectType class=org.drools.examples.shopping.ShoppingExample$Discount]] TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,077 [main] TRACE Segment 1 2014-10-02 02:35:09,077 [main] TRACE 18 [JoinNode(10) - [ClassObjectType class=org.drools.examples.shopping.ShoppingExample$Discount]] TupleSets[insertSize=0, deleteSize=0, updateSize=0] 2014-10-02 02:35:09,077 [main] TRACE rightTuples TupleSets[insertSize=0, deleteSize=1, updateSize=0] 2014-10-02 02:35:09,077 [main] TRACE 19 [RuleTerminalNode(11): rule=Discount awarded notification] TupleSets[insertSize=0, deleteSize=1, updateSize=0] 2014-10-02 02:35:09,077 [main] TRACE Segment 1 2014-10-02 02:35:09,077 [main] TRACE 19 [RuleTerminalNode(11): rule=Discount awarded notification] TupleSets[insertSize=0, deleteSize=1, updateSize=0] 2014-10-02 02:35:09,077 [main] TRACE Removing RuleAgendaItem [Activation rule=Discount awarded notification, act#=7, salience=0, tuple=null] 2014-10-02 02:35:09,077 [main] TRACE Queue Removed 1 [Activation rule=Discount awarded notification, act#=7, salience=0, tuple=null] 2014-10-02 02:35:09,077 [main] TRACE Removing RuleAgendaItem [Activation rule=Apply 10% discount if total purchases is over 100, act#=1, salience=0, tuple=null] 2014-10-02 02:35:09,077 [main] TRACE Queue Removed 1 [Activation rule=Apply 10% discount if total purchases is over 100, act#=1, salience=0, tuple=null]Reference: Trace output with Drools from our JCG partner Mark Proctor at the Drools & jBPM blog....
jcg-logo

Java Code Geeks and ej-technologies are giving away FREE JProfiler Licenses (worth over $2000)!

Tired of having performance issues on your live servers? Then we have something especially for you! We are partnering with ej-technologies, creator of cool Java tools, and we are running a contest giving away FREE licenses for the award-winning all-in-one Java profiler, JProfiler. JProfiler is an all-in-one Java profiler that is easy to use and has advanced functionality for solving hard problems. JProfiler’s intuitive UI helps you resolve performance bottlenecks, pin down memory leaks and understand threading issues. To learn more about JProfiler, see http://www.ej-technologies.com/products/jprofiler/overview.html A fully functional evaluation is available from http://www.ej-technologies.com/download/jprofiler/filesWhy use JProfiler?Exceptional ease of use Database profiling for JDBC, JPA and NoSQL Excellent support for Java Enterprise Edition Higher level profiling data Stellar analysis of memory leaks Extensive QA capabilities Broadest support for technologies and tools Low overhead The powerful CPU profiler The integrated thread profilerEnter the contest now to win your very own FREE JProfiler Licence. There will be a total of 5 winners! In addition, we will send you free tips and the latest news from the Java community to master your technical knowledge (you can unsubscribe at any time). In order to increase your chances of winning, don’t forget to refer as much of your friends as possible! You will get 3 more entries for every friend you refer, that is 3 times more chances! Make sure to use your lucky URL to spread the word! You can share it on your social media channels, or even mention it on a blog post if you are a blogger! Good luck and may the force be with you! UPDATE: The giveaway has ended! Here is the list of the lucky winners! (emails hidden for privacy)ro…am@gmail.com cr…oi@yahoo.com de…ol@yahoo.co.uk ja…tv@gmail.com th…va@yahoo.com.brWe like to thank you all for participating to this giveaway. Till next time, Keep up the good work!...
jooq-logo-black-100x80

Don’t Miss out on Writing Java 8 SQL One-Liners with jOOλ or jOOQ

More and more people are catching up with the latest update to our platform by adopting functional programming also for their businesses. At Data Geekery, we’re using Java 8 for our jOOQ integration tests, as using the new Streams API with lambda expressions makes generating ad-hoc test data so much easier. However, we don’t feel that the JDK offers as much as it could, which is why we have also implemented and open-sourced jOOλ, a small utility library that patches those short-comings.   Note, we don’t aim to replace more sophisticated libraries like functionaljava. jOOλ is really just patching short-comings. Putting lambdas to work with jOOλ or jOOQ I’ve recently encountered this Stack Overflow question, which asked for streaming a result set with all columns into a single list. For example: Input +----+------------+------------+ | ID | FIRST_NAME | LAST_NAME | +----+------------+------------+ | 1 | Joslyn | Vanderford | | 2 | Rudolf | Hux | +----+------------+------------+ Output 1 Joslyn Vanderford 2 Rudolf Hux This is a typical school-book example for using functional programming rather than an iterative solution: Iterative solution ResultSet rs = ...; ResultSetMetaData meta = rs.getMetaData();List<Object> list = new ArrayList<>();while (rs.next()) { for (int i = 0; i < meta.getColumnCount(); i++) { list.add(rs.getObject(i + 1)); } } Truth is, the iterative solution isn’t all that bad, but let’s learn how this could be done with functional programming. Using jOOλWe’re using jOOλ for this example for a couple of reasons:JDBC didn’t really adopt the new features. There is no simple ResultSet to Stream conversion, even if there should be. Unfortunately, the new functional interfaces do not allow for throwing checked exceptions. The try .. catch blocks inside lambdas don’t exactly look nice Interestingly, there is no way of generating a finite stream without also implementing an Iterator or SpliteratorSo, here’s the plain code: ResultSet rs = ...; ResultSetMetaData meta = rs.getMetaData();List<Object> list = Seq.generate() .limitWhile(Unchecked.predicate(v -> rs.next())) .flatMap(Unchecked.function(v -> IntStream .range(0, meta.getColumnCount()) .mapToObj(Unchecked.intFunction(i -> rs.getObject(i + 1) )) )) .toList() So far, this looks about as verbose (or a bit more) than the iterative solution. As you can see, a couple of jOOλ extensions were needed here: // This generate is a shortcut to generate an // infinite stream with unspecified content Seq.generate()// This predicate-based stream termination // unfortunately doesn't exist in the JDK // Besides, the checked exception is wrapped in a // RuntimeException by calling Unchecked.wrapper(...) .limitWhile(Unchecked.predicate(v -> rs.next()))// Standard JDK flatmapping, producing a "nested" // stream of column values for the "outer" stream // of database rows .flatMap(Unchecked.function(v -> IntStream .range(0, meta.getColumnCount()) .mapToObj(Unchecked.intFunction(i -> rs.getObject(i + 1) )) ))// This is another convenience method that is more // verbose to write with standard JDK code .toList() Using jOOQ jOOQ has even more convenience API to operate on result records of your SQL statement. Consider the following piece of logic: ResultSet rs = ...;List<Object> list = DSL.using(connection) .fetch(rs) .stream() .flatMap(r -> Arrays.stream(r.intoArray())) .collect(Collectors.toList()); Note that the above example is using standard JDK API, without resorting to jOOλ for convenience. If you want to use jOOλ with jOOQ, you could even write: ResultSet rs = ...;List<Object> list = Seq.seq(DSL.using(connection).fetch(rs)) .flatMap(r -> Arrays.stream(r.intoArray())) .toList(); Easy? I would say so! Let’s remember that this example:Fetches a JDBC ResultSet into a Java Collection Transforms each record in the result set into an array of column values Transforms each array into a stream Flattens that stream into a stream of streams Collects all values into a single listWhew! Conclusion We’re heading towards exciting times! It will take a while until all Java 8 idioms and functional thinking will feel “natural” to Java developers, also in the enterprise. The idea of having a sort of data source that can be configured with pipelined data transformations expressed as lambda expressions to be evaluated lazily is very compelling, though. jOOQ is an API that encapsulates SQL data sources in a very fluent and intuitive way, but it doesn’t stop there. jOOQ produces regular JDK collections of records, which can be transformed out-of-the-box via the new streams API. We believe that this will drastically change the way the Java ecosystem will think about data transformation. Stay tuned for more examples on this blog!Reference: Don’t Miss out on Writing Java 8 SQL One-Liners with jOOλ or jOOQ from our JCG partner Lukas Eder at the JAVA, SQL, AND JOOQ blog....
Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close