Showing posts with label Jet. Show all posts
Showing posts with label Jet. Show all posts

29 Jun 2018

Oracle Jet vs Oracle ADF or Oracle Jet with Oracle ADF

In this post I would like to thank everyone, who managed to attend my session "Oracle Jet vs Oracle ADF or Oracle Jet with Oracle ADF" at ODTUG KScope18 conference in Orlando FL. Thank you guys for coming to listen to me, to learn something new and to ask a lot of interesting questions. 

I promised at the session that the presentation would be available for download. 
The presentation is available here:


That's it!

28 May 2018

Oracle ADF and Oracle Jet work together. Architecture patterns.

In this post I am going to consider various architecture patterns of implementing an application on top of combination of Oracle ADF and Oracle Jet.  An organization practicing ADF may think on incorporating Oracle Jet for existing projects to refresh look&feel and make it modern and responsive and to implement new features in a new way. It may think on using Oracle Jet for totally new projects and obviously for projects related to development of hybrid applications for mobile devices.
Oracle Jet is all about UI it is only about the client side part. So, the server side has to be implemented with something anyway. Obviously that many organizations will decide to use ADF for that in order to reuse their knowledge, experience, implementations and investments in ADF. It makes perfect sense. So, let's have a look at what options we have when it comes to combining Oracle Jet with Oracle ADF.


The first, most obvious and most popular option is to put Oracle Jet on top of ADF BC. So the client side for a web or for a hybrid mobile application is implemented with Jet and the serverside is ADF BC exposed as a Rest service. With JDeveloper 12.2.x you can expose ADF BC as Rest services in a few mouse clicks just like that.


The advantage of this approach is a pretty simple architecture. And what is simple has a chance to work longer. Another very valuable benefit is that we are reusing our resources, our knowledge and ADF experience, and if our existing ADF application is implemented right then we are going to reuse the most critical part of business logic implementation.
However, we have to understand that ADF BC Business services working perfectly in an ADF application might be useless for a Jet applications. Why is that? The main reason is that we have changed the state management model. We switched from the classic ADF stateful behavior to the REST stateless model. Furthermore, more likely the UI design will be different in Jet Web and Hybrid applications. 
So, we need to create new ADF BC services supporting a stateless model and serving for the convenience of the new UI.

The good news is that we don’t have to build everything form scratch. If existing ADF BC model is built in the right way, we can reuse the core part of it including entities and business logic implemented at the entity level. 
So,we can split the entire ADF BC model into the core part containing entities, utilities,  and shared AMs and the facade part containing specific AMs and VOs and providing services for an ADF application and for a Jet application. 





Having reconsidered our ADF BC and getting them ready to serve both ADF and Jet applications we can incorporate now Jet functionality into existing ADF projects. A common architecture approach is 
to implement some pages of the system with ADF,  some web pages are implemented with Jet and there is also a mobile hybrid application which is also implemented with Oracle Jet.

The advantage of this approach is that we keep things separately. It looks like different applications working on top of a common business model. And each application introduces its own UI, suitable for those use-cases they are implemented for. Furthermore they provide different entry points to the entire system. We can access it through a regular ADF page, we can go with a mobile device or we can access it from a Jet web page which in its turn can be easily integrated into any parent web page, for example a portal application.
But this advantage may turn into a disadvantage as for each entry point we should think about authentication, internalization, localization, etc.
This approach brings more running pieces into the entire system structure, so CI, CD, automated testing, the environment become more complicated here.

Another obvious option would be to integrate Jet content into an ADF page, so that from the user perspective it looks like a single page but behind the scene this is a mix of two different web applications.



This option is not my favorite, I would avoid it. Because, basically, what you are doing here is mixing two web applications on the same page. It means there will be two different sessions with separate transactions and therefore separate entity caches and user contexts. 
Jet content is not participating in JSF lifecycle so the entire page is being submitted in two different ways. ADF prefers to own the entire page so such nice features like responsive geometry management and Drag&Drop just won’t work with the Jet content.
In my opinion this approach makes sense in very specific scenarios when we need to show on our page some content form outside. For example if our page is kind of a portal or a dashboard gathering in one place data from different sources. In this case the same Jet component can be used on a page like that and in a regular Jet application.

Same considerations are about the opposite approach when we integrate ADF content into a Jet page by the means of a remote task flow call. This technique makes sense but it should be used only in specific use cases when we want to reuse existing ADF functionality which is not implemented in Jet. At least not at this point in time. This approach should not be used as a standard instrument to build our application.


At the bottom line Oracle ADF and Oracle JET can work perfectly together and this is a good option for organizations having solid ADF background. The only thing is to choose wisely the architecture approach of combining these two completely different tools.


That's it!



28 Apr 2018

Building Oracle Jet applications with Docker Hub

In this post I am going to show a simple CI solution for an Oracle Jet application basing on Docker Hub Automated Builds feature. The solution is container native meaning that Docker Hub is going to automatically build a Docker image according to a Docker file. The image is going to be stored in Docker Hub registry. A Docker file is a set of instructions on how to build a Docker image and those instructions may contain any actions including building an Oracle Jet application. So, what we need to do is to create a proper Docker file and set up Docker Hub Automated Build.
I am going to build an Oracle Jet application with OJet CLI, so I have created a Docker image having OJet CLI installed and serving as an actual builder. The image is built with the following Dockerfile:

FROM node
RUN npm install -g @oracle/ojet-cli

By running this command:
docker built -t eugeneflexagon/ojetbuilder .

Having done that we can use this builder image in a Dockerfile to build our Jet application:
# Create an image from a "builder" Docker image
FROM eugeneflexagon/ojetbuilder

# Copy all sources inside the new image
COPY . .

# Build the appliaction. As a result this will produce web folder.
RUN ojet build


# Create another Docker image which runs Jet application
# It contains Nginx on top of Alpine and our Jet appliction (web folder)
# This image is the result of the build and it is going to be stored in Docker Hub
FROM nginx:1.10.2-alpine
COPY --from=0 web /usr/share/nginx/html
EXPOSE 80

Here we are using the multi-stage build Docker feature when we actually create two Docker images: one for building and one for running, and only the last one is going to be saved as the final image. So, I added this Docker file to my source code on GitHub.

The next step is to configure Docker Hub Automated Build:









That was easy. Now we can change the source code and once it is pushed to GutHub the build is automatically queued:



Once the build is finished we can pull and run the container locally:


docker run -it -p 8082:80 eugeneflexagon/ojetdevops:latest

And see the result at http://localhost:8082


That's it!