Tuesday, 24 April 2018

Oracle Linux 7 Update 5 is out: time to create a new Vagrant Base Box

It's been busy, so unfortunately it's already been almost two weeks I wrote my introductory story on Vagrant. Today I happen to have an afternoon off, and I noticed that Oracle Linux 7 Update 5 is out. I based my first boxes on 7.4, so nice moment to start with creating a new Base Box.

De essentials on creating a Vagrant base box can be read here. But I'm going to guide you trough the process step by step, so I hope you will be able to repeat this yourself, using this guide-through.

First of, Vagrant recommends Packer to automate the creation of base boxes. But I'm a bit confused, because in this guide it is apparently stated that this is deprecated by march 2018. I haven't tried Packer yet, but I feel that over the years I created a base VM only a few times. I used to create a base VM that I import/clone to create new VMs over and over again. And often, I start of with a VM that already contains a pre-installed database for instance.

Vagrant has a built in command to create a base box out of an existing VM. That is what I use.

Base box requirements

What is a Base Box actually? Well, it's in fact sort of a template that is used by Vagrant to create and configure a new VM and provision that. It should contain the following
  • An OS: I use Oracle Linux 7 Update 5 for this story. I also have a base box with Ubuntu. Ubuntu has some peculiarities I want to discuss later on in this series. For this base box I'll install a server-with-gui. But further as basic as possible.
  • A vagrant user. The vagrant user is used for provisioning the box. We'll place a public insecure key in it, that will be replaced by Vagrant at first startup. We'll add vagrant to the sudoers list, so the user can sudo without passwords.
  • A started ssh daemon:  Vagrant connects via ssh using the vagrant-user to do the provisioning.
  • A NAT (Network Address Translation) Adapter as the first one: needed to do kernel/package updates without further network configuration.
  • VirtualBox GuestAdditions installed: Vagrant makes use of shared folders to map the project folder to get to the scripts. Also it's convenient to add an extra stage folder mapping. 
  • Password of root: not a requirement, but apparently it's a bit of a standard to set the root password to vagrant as ease of sharing. But at least note down the passwords.
That's about it. Maybe I forget something, but since it's digital, I can edit it later... So let's get started.

Download  Oracle Linux

All the serious enterprise stuff of Oracle can be downloaded at edelivery. Search for Oracle Linux:
Then add the 7.5 version to the Cart by clicking it:

Follow the wizard instructions and you'll get to:
I downloaded V975367-01.iso        Oracle Linux Release 7 Update 5 for x86 (64 bit), 4.1 GB.

Create the VM

The ISO is downloading, so let's create a VM in VirtualBox. I assume VirtualBox with VirtualBox Extension Pack is installed. And for later on Vagrant of course.

From the Oracle VM VirtualBox Manager, create a new VM, I called it OL75, for Oracle Linux 64 bit:
I followed the wizard and gave it 10240 MB memory and a 128GB dynamically allocated virtual disk:

In the VM Settings, I set the number of processors to 4 and for now I kept everything to the default.

In the meantime my download is ready, so in the VM Settings, under Storage I added the disk by clicking the disk icon next to the IDE controller:

Then navigate to your downloaded iso:
and select it. Now the VM is ready to kick-off:


It will startup automatically after a minute, but let's not wait that long.

I don't need much, but in the Sofware Selection I do want Server with GUI:
But with out selecting other packages. What I might need later on, I'll install at provisioning.

I do not like default local domain networknames. So I changed the network hostname to darlin-vce.darwin-it.local:
Hostname darlin stands for Darwin Linux and vce for Virtual Course Environment.

Then hit Begin Installation:


Soon in the installation the installer asks for the Root password:
And the password is as said: vagrant.
Then I add also a vagrant with the same password:
Having done that, we need to wait for the installer to finish. At the end of the Install, do a reboot:

This leads to 2 questions to be answered. One is about accepting the licensing. I assume that can be answered without guidance. The other is about connecting the network.

You need to switch on the network adapter, but to have it done automatically you need to configure it and check the box Automatically connect to this network when it is available on the General tab. You'll need to have this done, otherwise Vagrant will have difficulties in connecting to the box.
Then finish the configuration:

Install guest additions

To be able to install the guest additions, we need to add some kernel packages. We could have done that by installing additional kernel packages. But I wanted to have a as basic as possible installation. And the following is more fun...

So open a terminal and switch to the super user:

[vagrant@darlin-vce ~]$ su -
Password: 
Last login: Tue Apr 24 09:41:21 EDT 2018 on pts/0
...


Then stop package kit, because it will probably hold a lock pausing yum:
[root@darlin-vce ~]# systemctl stop packagekit

And then install the packages kernel-uek-devel kernel-uek-devel-4.1.12-112.16.4.el7uek.x86_64, that are suggested by the GuestAdditions installer, by the way:
[root@darlin-vce ~]# yum -q -y install kernel-uek-devel kernel-uek-devel-4.1.12-112.16.4.el7uek.x86_64
No Presto metadata available for ol7_UEKR4
warning: /var/cache/yum/x86_64/7Server/ol7_latest/packages/cpp-4.8.5-28.0.1.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID ec551f03: NOKEY
Public key for cpp-4.8.5-28.0.1.el7.x86_64.rpm is not installed
Public key for kernel-uek-devel-4.1.12-124.14.1.el7uek.x86_64.rpm is not installed
Importing GPG key 0xEC551F03:
 Userid     : "Oracle OSS group (Open Source Software group) "
 Fingerprint: 4214 4123 fecf c55b 9086 313d 72f9 7b74 ec55 1f03
 Package    : 7:oraclelinux-release-7.5-1.0.3.el7.x86_64 (@anaconda/7.5)
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-oracle

Having done that, insert the GuestAdditions CD:
It brings the following pop-up, click Run:

And provide the Administrator password:

In my case the script ran and during that the display got messed up. But after a reset of the VM (I waited until I got the impression it was done), the VM got up with a Hi-res display, indicating that the install went ok. Also the bi-directional clipboard worked.

Configure vagrant user

Again in a terminal switch to super user and add the following line to the /etc/sudoers file:
vagrant ALL=(ALL) NOPASSWD: ALL

Exit and as vagrant user create a .ssh folder in the vagrant home folder, cd to it and create the file authorized_keys:
[vagrant@darlin-vce ~]$ mkdir .ssh
[vagrant@darlin-vce ~]$ cd .ssh
[vagrant@darlin-vce .ssh]$ vi authorized_keys

Insert the following content:
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key

This is the insecure key of vagrant that can be downloaded here.
It will be replaced by Vagrant at first startup.

Package the box

So, now we have a base install that can function as a base box for Vagrant. Thus we can now shut it down to export it to an OVA (just as a backup for VirtualBox) and then create are base box out of it.

After creating your export of the OVA, that I skip describing here, you just open a command window. I assume you have Vagrant installed.

To package the box, you use the package subcommand of vagrant:

Microsoft Windows [Version 10.0.16299.371]
(c) 2017 Microsoft Corporation. All rights reserved.

d:\Projects\vagrant>vagrant package --base OL75 --output d:\Projects\vagrant\boxes\OL75v1.0.box
==> OL75: Exporting VM...
==> OL75: Compressing package to: d:/Projects/vagrant/boxes/OL75v1.0.box

d:\Projects\vagrant>

Conclusion

Well, that concludes this part of the series. We have our own base box and it's barely 3GB. Next: create a VM with it. Stay tuned.




Thursday, 19 April 2018

Garbage First in JDeveloper

At my current customer we work with VDI's: Virtual Desktop Images, that at several times a day very, very slow. Even so slow that it more or less stalls for a minute or two.

JDeveloper is not known as a Ferrari under the IDE's. One of the causes is that by default heap settings is very poor: 128M-800M. Especially when you use it in  SOA or BPM Quickstart then at startup it will need to grow several times. But very soon working in it you'll get out of memory errors.

Because of the VDI's I did several changes to try to improve performance.
Main thing is set Xms and Xmx both at 2048M. I haven't found needing more up to this day.

But I found using the Garbage First collector gives me a slightly better performance.

To set it, together with the heap, add/change the following options in the ide.conf in ${JDEV_HOME}\jdeveloper\ide\bin\:
# Set the default memory options for the Java VM which apply to both 32 and 64-bit VM's.
# These values can be overridden in the user .conf file, see the comment at the top of this file.
#AddVMOption  -Xms128M
#AddVMOption  -Xmx800M
AddVMOption  -Xms2048M
AddVMOption  -Xmx2048M
AddVMOption  -XX:+UseG1GC 
AddVMOption  -XX:MaxGCPauseMillis=200

Find more on the command line options in this G1GC tutorial.

You can also use the ParNew incombination with the ParOld or ConcMarkSeep collector, as suggested in this blog. But from Java9 onwards G1GC is the default, and I expect that it better fits the behavior of JDeveloper, as in SOASuite and OSB installations.

Wednesday, 11 April 2018

The vagrant way of provisioning - an introduction

About 2003, I guess, I was introduced into VMWare by a colleague. I was hooked about right away.
Since then I made numerous VMs for as many purposes. I played around with several VMWare products, but since Oracle acquired Sun, I stuck with VirtualBox.

A few years ago the tool Vagrant was mentioned to me. But I did not get the advantage of it, since all I needed to do I could do using VirtualBox.

However, over the years I found that maintaining VM's is a tedious job. And often I create and use a VM, but shut it down for months. And when I need it again, I don't the state anymore. Although you can use snapshots, it's nice to be able to start with a fresh install again.

In between, Oracle can have come up with another (minor) version of Fusion Middleware. Oracle Linux can have an new upgrade. There's a new patch set. Then you want to do a re-install of the software. And I find it nice that I can drop a VM and recreate it from scratch again.

For those purposes Vagrant comes in handy. It allows you to define a Box, based on a template, a base box, and configure it by configure CPU and memory settings, add disks and then after first boot, provision it.
So if I want to adapt a VM with a slightly different setting, or I need an extra disk, I destroy my box, adapt my Vagrant project file, and boot my box up again.

So, let's see what Vagrant is, actually. Then in a follow-up, I'll explain how I setup my Vagrant Project.


Vagrant is an open-source software product for building and maintaining portable virtual software development environments. So it helps you in creating and building Virtual Machines, especially in situations where you need to do that regularly and distribute those.

It simplifies software configuration management of virtualizations, to increase development productivity. Vagrant automates both the creation of VM’s and the provisioning of created VM's.  It does this by abstracting the configuration of the virtualization component and the installation/setup of the software within the VM, via a project file.

The architecture distinguishes two building blocks: Providers and Provisioners.
Providers are services to set up and create VMs, for instance:
  • VirtualBox
  • Docker
  • Vmware
  • AWS
Provisioners are tools to customize the configuration of VM, for example, configure the guest OS and install software within the VM. Possible provisioners are: 
  • Shell
  • Ansible
  • Puppet
  • Chef
I haven't made my self familiar with Ansible or Puppet, yet, (still on my list), so I work with the default provisioner: Shell.

A Vagrant project is in fact a folder with the Vagrant file in it. The vagrant file contains all the configuration of the resulting Vagrant box, the actual created VM.

A Vagrant project is always based on  a base box. Often, a downloadable box from a Vagrant repository is used. In fact, if you don't specify an url, but only a name, it will try to find it from the Vagrant repository. A popular one is the hashicorp/precise64, used in many examples. However, I prefer to use my own local box. For two main reasons:
  • I then know what's init.
  • It's local, so I don't have to download it.
To be able to be used by Vagrant, a box has the following requirements:
  • It contains an actual VM, with OS installed in it.
  • A vagrant user is defined, with sudo rights, and an insecure key (downloadable from vagrant's github, but it will be replaced by a generated secure key at first startup), but  you can specify a password (as I do).
  • NAT network adapter as a first NIC.
  • SSH deamon running.
There is a tool, called Packer, that is  able to create a box, with an OS installed. I haven't tried it, but actually, I created a very simple VM in VirtualBox, installed Oracle Linux 7 Update 4, with the server with gui option as a next-next-finish install in it, defined the vagrant user as mentioned in it. And then with the vagrant package command I got the particular box. I had a few iterations to get it as I wanted it. But once you get it right, you should not need to touch it. Unless another Linux update comes along.

Now I have only one simple base box, and I only need to define different vagrant projects and a stage folder with the latest greatest on the software downloaded. And a simple vagrant up command will create my VM a new, and install all the software in it.

Last year, on the NLOUG's Tech Experience '17, together with my colleague Rob, I spoke about how to script a complete Oracle Fusion MiddleWare environment. It was a result of a series of projects we did up to the event, where we tried to automate the environment creation as much as possible. See my series of blogs on the matter. In the upcoming period, I plan to write about how to leverage these scripts with Vagrant to set up a complete VM, with the latest greatest FMW in it.

So stay tuned.




Tuesday, 10 April 2018

PaaSForum and the talk with the two ladies...

It's already been a week or three that I've been to the excellent PaaSForum '18 in Budapest.
Much is already said and written about it. About the talks and breakout sessions.
To see and hear about the state of art of the Oracle PaaS products: every year I'm having a good time with Oracle Friends around Europe and beyond.

It was nice to play around with API Management, Dynamic Processes, Oracle JET and ChatBots. And, ..., to do a few runs to the Donau and back again. I hadn't run for about half a year because of my relocation and remodelling of our new home.

But besides the great talks with Product Management and other Oracle Friends, the thing that maybe made me most exciting was the talk with two ladies: Mary Beth and Liza... A review session about the User Experience of the Oracle PaaS products.

My major concern about the PaaS products, or maybe the Oracle Cloud products in general, is that they're very 'siloed'. Looking at ICS, PCS, VBCS (now bundled in OIC), API Management, Chatbots, CX, etc., they all have a very different history of birth.
Created in different teams. And all have a different User Experience, although Oracle did work in creating a uniform UI definition.
If I want to start with a project with different services, then I need to create and provision my different services. Those all have different URLs, etc. And if I want to move my artifacts to PreProduction or Production, I need to create new services, with their own authentication and authorisation schemas.
And I need to do the release/install of those artifacts to the different environments, myself.


In the feedback session, Liza presented me two personas (Mary Beth was taking notes): a Development Manager and a Developer.
The Development manager will be able to login to the PaaS environment landing page and create a new project. He will be able to select the components by himself or base the project on a template. This will then select the particular components, or project features, so to speak. You could compare it with creating an application in JDeveloper where you get to choose between a Java application, ServiceBus, SOA Suite or BPM Suite, and one or more appropriate projects. Creating such a PaaS Project will provision the necessary Cloud services, as indicated by the chosen components. The Development Manager can also invite project members, that get an invite with URL via email, or Slack, etc.

The Developer, can follow the link in the invite and log on to the Unified PaaS environment, or One PaaS, and from a palette can select a component he/she wants to create and work upon. I suggested that the palette should be restricted by the components selected on creation by the Development Manager. Cloud Services cost subscription fees, pressing on the budget. So, when a developer finds he needs to be able to create a certain component, the Development Manager should approve the addition of that component type, to solve the particular problem. Maybe the tiles of component types for which the project does not have a Cloud Service could be grayed out.

Another suggested addition is the environments management. They foresee a kind of devops administration page, where you can see the dev, test, pre-prod and production environments, and the artifact-versions mapped over that. So that you can see what version of which artifacts are on which environment/services. I suggested that it would be nice, in my opinion, to define releases or configurations of artifacts. Some artifacts are related to each other, for instance a certain version of a VBCS screen is dependent on a version of a REST service in OIC and/or API Mgt. So you want to combine those in a release, to make sure that they're released/installed to the next environment together.

Of course I can't show you any screens or inside information. Not lastly because I only saw mock-up screens myself. 

I got a nice present, a small Bluetooth speaker with a surprisingly great sound.  But, and be assured: I don't have Oracle shares (anymore), the biggest takeaway for me, that made me enthusiastic was the knowledge and the assurance that Oracle is really putting much effort in this. It is important and I believe this is going to make the big difference in the PaaS offering. Although the different offerings on their own are promising, a unified UI and development and management experience is going to make it actually usable. As a developer I do want to create UI's or Processes or Integrations, but I do not want to bother about the URLs to use for which environment. And I want to be helped by promoting my artifacts on a uniform way to the next environment. I should not export artifacts in different ways and import those one by one in a target cloud service.

The other day I also had an introductory meeting with one of the directors for UI/UX design. And that stressed the importance of UX on the unified PaaS UX initiatives.

As you'll understand: I'm very curious and looking forward to see new developments. If they reach me, I'll keep you posted (as far as I'm allowed of course).


Thursday, 22 March 2018

SQLDeveloper: User Defined Extensions and ForeignKey query revised

It was so fun: yesterday I wrote  a small article on creating a query on Foreign Keys refering a certain table. A post with content that I made up dozens of times in my Oracle carreer. And right away I got 2 good comments. One was on the blog itself.
 

And of course Anonymous is absolutely right. So I added 'U' as a constraint type option.

The other comment was from my much appreciated colleague Erik. He brought this to another level, by pointing me out how to add this as a User Defined Extension in SQL Developer.

I must say I was already quite pleased with the Snippets in SQLDeveloper. So I already added the query as a snippet:
But the tip of Erik is much cooler.
He refered to a tip by Sue Harper that explains this (What, it's been in there since 2007?!).

Now what to do? First create an xml file, for instance referred_by_fks.xml,  with the following content:
<items>
    <item type="editor" node="TableNode" vertical="true">
    <title><![CDATA[FK References]]></title>
    <query>
        <sql>
            <![CDATA[select fk.owner,
fk.table_name,
fk.constraint_name,
fk.status
from all_constraints  fk
join all_constraints rpk on rpk.constraint_name = fk.r_constraint_name 
where fk.constraint_type='R'
and rpk.constraint_type in('P','U')
and rpk.table_name = :OBJECT_NAME
and rpk.owner = :OBJECT_OWNER
order by fk.table_name, fk.constraint_name;]]>
        </sql>
    </query>
    </item>
</items>

Note that I updated my query a bit.


Then to add the extension to SQL Developer:
  • Open the prefereces via: Tools > Preferences
  • Navigate to Database > User Defined Extensions
  • Click "Add Row" button
  • In Type choose "EDITOR", Location is where you saved the xml file above
  • Click "Ok" then restart SQL Developer

Now, if you click on a table in the navigater, you will have an extra tab on your table editor:

Cool stuff! And it's been there for ages!

Wednesday, 21 March 2018

Which tables have foreign keys refering to a particular table?

Ok, this time a quick not so exciting post. Actually, I find my self recreating a query again, that I created many times in my carreer. So, why not post it?

Last year, I published my Darwin Object Type Accelerator (Dotacc). It allows you to generate objects from a datamodel. What it also does is create collection types for tables that refer to the tabel you want to generate an object for. For some you want that, but for others you don't. Simply because you don't need them to be queried along. Therefor, I added functionality to disable those.

But then comes the question: which are the tables with their foreignkey constraints that refer to this particular table?

The answer is in the ALL_CONSTRAINTS view (with the variants of DBA_% and USER_%).
There are several types of constraints:
  • C: Check constraints
  • R: Referential -> the particular foreign keys
  • P: Primary Key
  • U: Unique Key
I'm interested in the Foreign keys, thus those where constraint_type='R'. But those refer not to a table but to another constraint. So, I need to get the primary key, constraint_type='P', of the table that I want to query and join those together.

That get's me:
select fk.* 
from all_constraints  fk
join all_constraints rpk on rpk.constraint_name = fk.r_constraint_name 
where fk.constraint_type='R'
and rpk.constraint_type in ('P', 'U')
and rpk.table_name = 'DWN_MY_TABLE';

Thursday, 8 March 2018

Set the minimum password length on your default authenticator in Weblogic

End of last year I wrote how to create a demo community of users in your Weblogic using wlst.
Using these scripts I wanted to do the same at my current customer: creating test users in the DefaultAuthenticator. However, I faced that the minimum password length was 8, while one of the user failed creation, because the password was the same as the user, and only 5 characters long.

So I need to change the password validator. And preferably using WLST (of course). Now, the password validator of de authenticator can also be found through the console. However, the Weblogic realm also has a system password validator. Both have a default length of 8.

Let me show you some snippets (that you can add to the create users script, or your own purpose), on how to change the minimum password length.

First a method to get the default realm:
#
#
def getRealm(name=None):
  cd("/")
  if name == None:
    realm = cmo.getSecurityConfiguration().getDefaultRealm()
  else:
    realm = cmo.getSecurityConfiguration().lookupRealm(name)
  return realm

With that you can get the authenticator:
#
#
def getAuthenticator(realm, name=None):
  if name == None:
    authenticator = realm.lookupAuthenticationProvider("DefaultAuthenticator")
  else:
    authenticator = realm.lookupAuthenticationProvider(name)
  return authenticator

With a realm an an authenticator, we can change the password length:
#
#
def setMinPasswordLengthOnDftAuth(minPasswordLength):
  try:
    edit()
    startEdit()
    # Get Realm and Authenticator
    realm = getRealm()
    authenticator = getAuthenticator(realm)
    authenticator.setMinimumPasswordLength(int(minPasswordLength))
    passwordValidator=realm.lookupPasswordValidator('SystemPasswordValidator')
    passwordValidator.setMinPasswordLength(int(minPasswordLength))    
    save()
    activate(block='true')
    print('Succesfully set minimum password length to '+minPasswordLength+ ' on '+authenticator.getRealm().getName()+'.')
    print('For '+ authenticator.getName() +': '+str(authenticator.getMinimumPasswordLength()))
    print('For SystemPasswordValidator of '+getRealm().getName()+': '+ str(passwordValidator.getMinPasswordLength()))
  except WLSTException:
    stopEdit('y')
    message="Failed to update minimum password length!"
    print (message)
    raise Exception(message)

The minimum password length from the authenticator can be set directly. From the realm this function looks up the SystemPasswordValidator. And on that it set the minimum password length.

This function goes to edit mode, saves and activates the changes. But if you want to add users, you need to get wlst into domainConfig() mode.

Other password validator property setters are:
  • setMinPasswordLength()
  • setMaxPasswordLength()
  • setMaxConsecutiveCharacters()
  • setMaxInstancesOfAnyCharacter()
  • setMinAlphabeticCharacters()
  • setMinNumericCharacters()
  • setMinLowercaseCharacters()
  • setMinUppercaseCharacters()
  • setMinNonAlphanumericCharacters()
  • setMinNumericOrSpecialCharacters()
  • setRejectEqualOrContainUsername(true)
  • setRejectEqualOrContainReverseUsername(true) 
See the docs for more.