Saturday, June 29, 2013

Consensus-based Whole Server Migration

I have a cluster with 2 MS

On both MS, tick "enable whole server migration", and select both machines as possible targets (you will need both, if you want to migrate your server back)

At cluster level, don't forget to switch to "Consensus" (the default is "Database"), and again to choose both machines as target (not sure why this double settings):

At this point, after a good restart of both MS, you will be able to migrate a MS from one machine to the other - this will shutdown MS from 310 and startup on 311:

The end result will be that both MS are running on the same machine:

You can now bring down the first machine for maintenance.

Be aware that, if your MS uses a Virtual IP, and WSM is enabled, whenever you migrate a MS the VIP will be removed from the Origin machine and added to the Target machine.

If you forget to enable consensus, you will get this error:
BEA-003109 Cluster osbpp4cl uses database as the migration basis but no data source for migration has been configured.

Poll result: XMHell

I am surprised to see so little XML hatred.

I personally find XML one of the biggest blunders in IT.

Count stuck threads in WebLogic

nice little script to count the stuck threads in all instances of WebLogic (or any other Java processes) running under the current user:


echo "pid user stuck"
ps -ef | grep java | grep -v grep | while read LINE
  SOAUSER=$(echo $LINE | awk '{print $1}')
   PID=$(echo $LINE | awk '{print $2}')
   NAME=$(echo $LINE | sed -n -e 's/.*-Dweblogic.Name=\([^ ]*\).*/\1/p')
   if [ -z "$NAME" ] ; then
     NAME=$(echo $LINE | sed -n -e 's/.*weblogic.\(NodeManager\).*/\1/p')
   if [ -z "$NAME" ] ; then
   STUCKCOUNT=`jstack $PID | grep "STUCK" | wc -l`

Python/Jithon version associated to WLST

It's becoming a real issue to have to use such an old version of Python, 2.2, in WLST. There are lovely products like SQLAlchemy that we cannot use with such an old version.

I have opened an SR with Oracle, they say that it's a common request, they will provide an update in the future, and any version of Python other than the one shipped with WebLogic is unsupported.

Since we use WLST merely for configuration tasks, it's quite easy to check if it's doing the right thing: just check the configuration XML generated.

Anyway here we are not willing to hack the product and risk a legal suit. It's awkward to code in 2.2 when there is a 2.7 available, but such is life.

Friday, June 28, 2013

SQL to display SQL history

This to display all SQL statements processed in Oracle DB withing a certain range of time and coming from certain machines:

select a.sql_id,a.sql_text,b.cnt from dba_hist_sqltext a, 
select sql_id,count(1) cnt from 
select session_id,sql_id,machine,sample_time,count(1) from 
select * from dba_hist_active_sess_history
sample_time between to_date('19/06/2013 07:00','dd/mm/yyyy hh24:mi') and to_date('19/06/2013 10:00','dd/mm/yyyy hh24:mi')
and program = 'JDBC Thin Client' 
and machine like 'myhost1%'
--and rownum < 10
where sql_id is not null
group by session_id,sql_id,machine,sample_time
order by sample_time asc
) group by sql_id) b
where a.sql_id(+)=b.sql_id

if you simply want the active sessions:

select * from dba_hist_active_sess_history
sample_time between to_date('19/06/2013 07:00','dd/mm/yyyy hh24:mi') and to_date('19/06/2013 10:00','dd/mm/yyyy hh24:mi')
and program = 'JDBC Thin Client' 
and machine like 'myhost1%'

Thursday, June 27, 2013

Date and Time in History

echo 'export HISTTIMEFORMAT="%d/%m/%y %T "' >> ~/.bashrc

I don't understand why it's not a default...

Monday, June 24, 2013

creating symbolic link, Permission denied

The situation is: ls -ltr /opt/oracle/
java -> /usr/lib/jvm/java-1.6.0-sun-

where /usr/lib/jvm/java-1.6.0-sun.x86_64 -> /usr/lib/jvm/java-1.6.0-sun- and I issue
ln -s /usr/lib/jvm/java-1.6.0-sun.x86_64 /opt/oracle/java
because I want /opt/oracle/java to point to /usr/lib/jvm/java-1.6.0-sun.x86_64 and not to /usr/lib/jvm/java-1.6.0-sun- (I need an extra level of indirection)
The funny thing is that I get a:
ln: creating symbolic link `/opt/oracle/java/java-1.6.0-sun.x86_64' to `/usr/lib/jvm/java-1.6.0-sun.x86_64': Permission denied
This is because PROBABLY the ln command goes ahead resolving /opt/oracle/java, and to avoid a recursive situation it backs up.
Just do an "unlink /opt/oracle/java" before the ln, and you will be fine.

Enabling/Disabling remote desktop

If Remote Desktop is disabled on your Windows machine, you have 2 choices:

- install RealVNC, excellent product

- run regedit and set HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\fDenyTSConnections to 0


Of course there is a third possibility: thrown away Windows and install some Linux.

"Javadoc" for ORACLE DB

Documentation should be embedded in code. Everything else is way, way suboptimal.

You can easily document your DB like this:
This will display all tables
SELECT table_name FROM user_tables;
This will display all Comments on all Tables, Views, Columns:
SELECT TABLE_NAME, table_type, comments from user_tab_comments order by table_name;

To make it only for TABLEs:
SELECT TABLE_NAME, table_type, comments from user_tab_comments where table_name = 'TABLE' order by table_name;

Sunday, June 23, 2013

Book review: Puppet Cookbook

Let's face it, Puppet Pro is definitely BORING.

Puppet Cookbook is much more readable, with plenty of funny quotes and useful examples. I would not call it a masterpiece, but definitely worth reading because it exposes a lot of cool Puppet best practices.

yum install blocked by yum-updatesd-he

I was doing
yum install graphviz
and got the message
"Another app is currently holding the yum lock; waiting for it to exit... The other application is: yum-updatesd-he"

rm -rf /var/run/

did the trick and let me proceed.

Duplicate IP detection

First, check that you can sudo arping:

sudo -l
you should see something like:
(root) NOPASSWD: /sbin/ifconfig, (root) /sbin/arping
then, you can issue the command
sudo /sbin/arping -D -I bond0 -c 2

to check if the IP is mounted in 2 places.

Friday, June 21, 2013


####<Jun 19, 2013 2:17:38 PM CEST> <Warning> <RMI> <hqchnesoa108> <osbpr1as> <[ACTIVE] ExecuteThread: '14' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <465bebdd30aa6335:3ab6711e:13f5b98936f:-8000-000000000000794c> <1371644258776> <BEA-080005> <Exception thrown by rmi server: sending exception
 org.omg.CORBA.OBJECT_NOT_EXIST: No such oid: 481  vmcid: OMG  minor code: 1  completed: No.
org.omg.CORBA.OBJECT_NOT_EXIST: No such oid: 481  vmcid: OMG  minor code: 1  completed: No
        at weblogic.iiop.EndPointImpl.replyNoSuchObject(
        at weblogic.iiop.EndPointImpl.handleIncomingRequest(
        at weblogic.iiop.EndPointImpl.processMessage(
        at weblogic.iiop.EndPointImpl.processFragment(
        at weblogic.iiop.EndPointImpl.processMessage(
        at weblogic.iiop.EndPointImpl.handleMessage(
        at weblogic.iiop.EndPointImpl.dispatch(
        at weblogic.iiop.ConnectionManager.dispatch(
        at weblogic.iiop.MuxableSocketIIOP.dispatch(
        at weblogic.socket.BaseAbstractMuxableSocket.dispatch(
        at weblogic.socket.SocketMuxer.readReadySocketOnce(
        at weblogic.socket.SocketMuxer.readReadySocket(
        at weblogic.socket.PosixSocketMuxer.processSockets(
        at weblogic.socket.SocketReaderRequest.execute(
        at weblogic.kernel.ExecuteThread.execute(

This started to happen on the Admin server after a network hiccup which requested a restart of the MS 1,2,3,4 in sparse order, some before and some after the Admin.

Try enabling all the debugIIOP flags,


and setting the System Property -Dweblogic.kernel.debug=true and restart the server.

Thursday, June 20, 2013

bash for loop

just a quick note, I always forget the syntax:

for i in {1..5}; do wget --no-check-certificate; done

Monday, June 17, 2013

weblogic find difference between two domains

If you have 2 working domains and want to find out in which way they differ, you have several options:

- use Enterprise manager, which has a Compare domains tool

- tar up the DOMAIN_HOME/bin folder and the  DOMAIN_HOME/config folder and use Beyond Compare

- do a domainToScript() with WLST and do a diff

- find all .sh and .xml and .properties files under /opt/oracle/fmw, tar up and diff with beyond compare

- see for rsync (I suggest to tar and copy both domains to another machine)

- do a jinfo PID on each instance of server, and do a diff

-  find /opt/oracle/fmw11_1_1_5/ -name *.jar | sort | xargs md5sum > allmd5.txt

Friday, June 14, 2013

Don Giovanni, a cenar teco

possibly 1000 years from now someone will be able to explain scientifically the magnetizing effect this piece has on our souls..... in the meantime, we can only listen in awe and let this sublime piece shake our foundations.

Don Giovanni a cenar teco
m’invitasti e son venuto!

Non l’avrei giammai creduto;
ma farò quel che potrò.
Leporello, un altra cena
fa che subito si porti!

Ah padron! Siam tutti morti.

Vanne dico!

Ferma un po’! Non si pasce di cibo mortale
chi si pasce di cibo celeste!
Altre cure più gravi di queste
altra brama quaggiù mi guidò!

La terzana d’avere mi sembra,
e le membra fermar più non so.

Parla dunque! Che chiedi? Che vuoi?

Parlo; ascolta! Più tempo non ho! ecc.

Parla, parla, ascoltando ti sto, ecc.

E le membra fermar più non so, ecc.

Tu m’invitasti a cena,
il tuo dover or sai,
rispondimi: verrai tu a cenar meco?

Oibò; tempo non ha, scusate.

A torto di viltate
tacciato mai sarò.


Ho già risolto.


Dite di no!

Ho fermo il core in petto.
Non ho timor: verrò!

Dammi la mano in pegno!


Che gelo è questo mai?

Pentiti, cangia vita,
è l’ultimo momento!

No, no, ch’io non mi pento
vanne lontan da me!

Pentiti, scellerato!

No, vecchio infatuato!

Pentiti! ecc.

No! ecc.



Sì! Sì!

No! No!

Ah! tempo più non v’è!

Da qual tremore insolito
sento assalir gli spiriti!
Dond’escono quei vortici
di foco pien d’orror?

Tutto a tue colpe è poco!
Vieni, c’è un mal peggior!

Chi l’anima mi lacera?
Chi m’agita le viscere?
Che strazio, ohimè, che smania!
Che inferno, che terror!

Che ceffo disperato!
Che gesti da dannato!
Che gridi, che lamenti!
Come mi fa terror!

Tutto a tue colpe, ecc.

Chi l’anima, ecc.

Che ceffo, ecc.


Tuesday, June 11, 2013

SQLServerDriver timeout

LoginTimeout The amount of time, in seconds, that the driver waits for a connection to be established before timing out the connection request.
Valid Values 0| x where x is a number of seconds.
If set to 0, the driver does not time out a connection request.
If set to x, the driver waits for the specified number of seconds before returning control to the application and throwing a timeout exception.
Default: 0
Data Type: int

QueryTimeout Sets the default query timeout (in seconds) for all statements created by a connection.
Valid Values: -1 |0 | x where x is a number of seconds.
If set to x, the driver uses the value as the default timeout for any statement created by the connection. To override the default timeout value set by this connection option, call the Statement.setQueryTimeout() method to set a timeout value for a particular statement.
If set to -1, the query timeout functionality is disabled. The driver silently ignores calls to the Statement.setQueryTimeout() method.
If set to 0 (the default), the default query timeout is infinite (the query does not time out).
Default: 0
Data Type: int

After you apply these settings QueryTimeout=60 and LoginTimeout=30 to the weblogic.jdbc.sqlserver.SQLServerDriver, you get this error message on test:

Connection test failed with the following exception: weblogic.common.resourcepool.ResourceDeadException: 0:weblogic.common.ResourceException: Could not create pool connection. The DBMS driver exception was: [FMWGEN][SQLServer JDBC Driver]Login has timed out.

WebLogic, Testing Datasources

print 'starting the script ....'
username = 'weblogic'
password = 'weblogic1'
urls=['t3://', 't3://', 't3://']
servers=['osbts4as', 'osbts4ms1', 'osbts4ms2']

for index in range(0, 3):
    print "connecting to ", url
    cd('/JDBCServiceRuntime/' + myserver)
    for tmpDS in allRuntimes:
        print "testing", tmpDS
        print tmpDS.testPool()
        print "testing", tmpDS, " success"


Monday, June 10, 2013

Book review: Memories and Visions of Paradise

This is a fascinating book on the common factors of ancient myths over the Paradise. Learn how originally "Paradise" meant "enclosure with garden" in old Persian, how most pre-colombian american tribes shared the idea of a golden age where there was no war nor scarcity, and people lived in peace.... and much more. A must for anybody interested in religion and mythopoiesis .

Sunday, June 9, 2013

WLST, applying security policy to a JMS Module

The requirement is: only an authenticated user belonging to the Administrator group can access any JMS queue in a JMS module.

On Console, to understand what this operation entails, I associate this policy to PV_OSB_TESTModule JMSModule:
Group = Administrators

There is no change in the config.xml and other config files. All goes in LDAP.

To visualize the policyId, I do the following in the WLConsole:
myrealm/migration/export and I export to folder /tmp/exportmyrealm
these files are generated:

I dig into XACMLAuthorizer.dat and I see:

<Policy PolicyId="urn:bea:xacml:2.0:entitlement:resource:type@E@Fjms@G@M@Oapplication@EPV_OSB_TESTModule" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"><Description>Grp(Administrators)</Description><Target><Resources><Resource><ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"><AttributeValue DataType="">type=<jms>, application=PV_OSB_TESTModule</AttributeValue><ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:2.0:resource:resource-ancestor-or-self" DataType="" MustBePresent="true"/></ResourceMatch></Resource></Resources></Target><Rule RuleId="primary-rule" Effect="Permit"><Condition><Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-is-in"><AttributeValue DataType="">Administrators</AttributeValue><SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:2.0:subject:group" DataType=""/></Apply></Condition></Rule><Rule RuleId="deny-rule" Effect="Deny"></Rule></Policy>

NOTE: it should be "type= & lt ; jms & gt ;" (remove the blanks.... XML encoding is HELLONEARTH)
This WLST can automate the operation:
connect('weblogic', 'weblogic1', 't3://')  

cd /SecurityConfiguration/osbpl1do/DefaultRealm/myrealm/Authorizers/XACMLAuthorizer

This can be automated for any JMSModule, just change PV_OSB_TESTModule to YourModuleName in the policy.xml and WLST.


It's not a spectacular tool, but I think it can be added to the toolbox of an Operations guy.

It quickly gives you an overview of all the running JVMs, with number of threads, GC overhead and CPU utilized.

I like the option of single PID mode (./ PID), since it shows you the top 10 threads eating more CPU. Quite useful for a quick debugging.

Saturday, June 8, 2013

Getting started with Btrace

User Guide:

Download binaries here:

Java class under test:
public class BTraceTest {
    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 1000000; i++) {

    public static void doSomething() {


Btrace profiling class:
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
import java.lang.reflect.Field;

@BTrace public class Btrace1 {
  public static void onDoSomething() {
      println("got it");

compile it:
./btracec -classpath . ./
run it:
./btrace -classpath . 24160 ./Btrace1.class
where 24160 is the PID of the BTraceTest java application
It works! It's great!
A slightly more advanced example using Class parameters:

public class BTraceTest {
    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 1000000; i++) {
    BTraceParam param = new BTraceParam(); = "hello " + i;

    public static void doSomething(BTraceParam param) {
        System.out.println("something" +;


public class BTraceParam {
 String name;

import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.AnyType;
import java.lang.reflect.Field;

@BTrace public class Btrace1 {

  public static void anyDoSomething(@ProbeClassName String pcn, @ProbeMethodName String pmn, AnyType[] args) {

this way you can print the value also of any parameter !

To print the stacktrace (very useful!) use jstack();

DIA-48315: ADR unavailable

After an incident occurs, creation of the
oracle.dfw.incident.IncidentCreationException: DFW-40116: failure creating incident
Cause: DFW-40112: There was an error executing adrci commands; the following errors have been found "DIA-48315: ADR unavailable
DIA-48315: ADR unavailable
DIA-48315: ADR unavailable
Action: Ensure that command line tool "adrci" can be executed from the command line.
        at oracle.dfw.impl.incident.DiagnosticsDataExtractorImpl.createADRIncident(
        at oracle.dfw.impl.incident.DiagnosticsDataExtractorImpl.createIncident(
        at oracle.dfw.spi.weblogic.JMXWatchNotificationListener.handleNotification(
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor$ListenerWrapper.handleNotification(DefaultMBeanServerInterceptor.ja
        at com.bea.diagnostics.notifications.JMXNotificationService.send(
Caused By: oracle.dfw.common.DiagnosticsException: DFW-40112: failed to execute the adrci commands "create home base="/opt/oracle/domains/osbts4do/servers/osbts4ms1/adr" product_type=ofm product_id=osbts4do instance_id=osbts4ms1
debug ami 72
set base /opt/oracle/domains/osbts4do/servers/osbts4ms1/adr
set homepath diag/ofm/osbts4do/osbts4ms1
create incident problem_key="BEA-101017 [HTTP][javax.servlet.ServletException]" error_facility="BEA" error_number=101017 error_message="null" create_time="2013-06-07 14:33:20.516 +02:00" ecid="87e67e9e23221171:-2788ccc2:13f1e8879ce:-8000-000000000000006c"
Cause: There was an error executing adrci commands; the following errors have been found "DIA-48315: ADR unavailable
DIA-48315: ADR unavailable
DIA-48315: ADR unavailable

We are still investigating this issue.

Thursday, June 6, 2013

sqldeveloper export date with time

I am using SQLDeveloper 3.2


Tools/preferences/ date format="yyyy/mm/dd/ hh24:mi:ss"
this will generate dates as to_date('2013/05/07/ 12:03:43','yyyy/mm/dd/ hh24:mi:ss')

SchemaCrawler for Oracle DB diff

I want to be able to trace all the modifications to my CMDB, and email the diff report on a regular basis. Lots of tools there but none seems to be a) free b) simple to use. SchemaCrawler doesn't do the diff, but you can export the whole schema and data into a txt file, and do a diff.

Download from and unzip.

Copy C:\Oracle\Middleware\wlserver_10.3\server\ext\jdbc\oracle\11g\ojdbc6_g.jar into the $SC_HOME/lib folder.

This will NOT display data, only structure:
sc -port=1522 -user=CMDBTRUNK -infolevel=maximum -password=blablabla -c=details > cmdbtrunk.txt

This will display data (dump):
sc -port=1522 -user=CMDBTRUNK -infolevel=maximum -password=blablabla -c=details,dump > cmdbtrunk.txt

This one will dump tables ACME but NOT tables ACME_BLA:

./ -port=1522 -user=CMDBTRUNK -infolevel=standard -password=blablabla -schemas=.*CMDBTRUNK.*  -tabletypes=TABLE -tables=(?!.*\.ACME_BLA.*)(.*\.ACME.*) -c=details,dump > CMDBTRUNK.txt

Wednesday, June 5, 2013

NodeManager inactive

On a 2 nodes cluster, for one node (machine) I was getting that NodeManager was Inactive/Unreachable:

Could not execute command "getVersion" on the node manager. Reason: "Access to domain for user BLA denied

I have done the usual check on file. then googling I found this post so I have edited:

vi /opt/oracle/domains/osbstg1do/config/nodemanager/



and restarted the NodeManager. After restart the file contains only a line hashed=blablabla.

The same username/password must be entered in Domain/Security/General in "NodeManager Username" and "NodeManager Password"

See also

Monday, June 3, 2013

WebLogic and OSB cluster in an Oracle VirtualBox

I want to run a OSB-WebLogic cluster spanning 2 machines (VBs).

Official doc here

An extra requirement is being able to mount an arbitrary IP alias on the NIC, to dedicate an IP (channel) to each managed server/admin. This with the certitude that this IP should not interfere with the Host network (enough of duplicate IPs causing panic in the firm).

I wonder what is the best strategy to configure the Virtual Network in the VB.

Excellent post on the different virtual networking modes in VirtualBox:

These are the alternatives:

  • Network Address Translation (NAT)
  • Bridged Networking
  • Internal Networking
  • Host-only Networking
  • Port-Forwarding with NAT Networking

I feel more inspired by an Internal Networking, since I need no access from the outside world, and actually I want to shield myself from causing trouble to the rest of the organization - for instance by mounting unwanted IPs.
more later...

Sunday, June 2, 2013

VirtualBox: setting a home for Virtual Boxes

Sadly, when you install VirtualBox on Linux, by default it chooses your /home/oracle home (my user is oracle) to store the VMs. I hate having stuff installed in my home.

In /home/oracle/.VirtualBox/VirtualBox.xml there is an entry
SystemProperties defaultMachineFolder="/home/oracle/VirtualBox VMs"
You can change this by running VirtualBox and changing preferences (File/Preferences); it's irritating because this requires to open a graphic session, which is not scriptable.

Since in my home partition I have little space, every attempt to create a VM dies with:
vagrant up VBoxManage: error: Could not create the clone medium VERR_DISK_FULL

Another way is to create a symbolic link (mmmmmm) /home/oracle/VirtualBox VMs -> /oracle/VirtualBox VMs
(besides, who chose a folder name containing SPACES???? Are you working at Microsoft or what?)

or also you manually hack the VirtualBox.xml

So far, my experience with Vagrant and VirtualBox has not been very good. These tools still need to be ironed to make them fool (me) proof.

Like, the idea of Vagrant to put all its stuff in a .vagrant.d (initial .) is moronic, it took me a while to find out this hidden repository. I assume you can change this by setting VAGRANT_HOME (see ). It would be so much better if one could choose these settings during an installation phase.

Anarchy in the IT

Although the ideas of Anarchism are very appealing to me, in IT it simply doesn't work.

I am more in favour of a societal model like the one of typical hunter-gatherers tribes, where a group of old (and fat :o) ), experienced hunters have a leadership and control over the team, letting nevertheless young energetic warriors and hunters contribute with their ideas and innovations. Old leaders who go insane should be demoted (unlike in Italy where the older and more rotten you are, the more you rise in politics).

Saturday, June 1, 2013 is needed by VirtualBox

trying to install VirtualBox on a RHEL 5.6, I get this error:

sudo rpm -i /opt/oracle/software/VirtualBox-4.2-4.2.12_84980_el5-1.x86_64.rpm
warning: /opt/oracle/software/VirtualBox-4.2-4.2.12_84980_el5-1.x86_64.rpm: Header V4 DSA signature: NOKEY, key ID 98ab5139
error: Failed dependencies: is needed by VirtualBox-4.2-4.2.12_84980_el5-1.x86_64

yum provides */
yum search SDL       
yum install SDL

Error Downloading Packages:
  SDL-1.2.10-8.el5.x86_64: failure: SDL-1.2.10-8.el5.x86_64.rpm from ol5_latest: [Errno 256] No more mirrors to try.
  SDL-1.2.10-8.el5.i386: failure: SDL-1.2.10-8.el5.i386.rpm from ol5_latest: [Errno 256] No more mirrors to try.

download it from

(choose binary package)

sudo rpm -i SDL-1.2.10-9.el5.i386.rpm
sudo rpm -i SDL-1.2.10-9.el5.x86_64.rpm

Putty: generating session configuration from code

I am an automation freak, and I hate doing manual copy and paste of information around.

I have to work on some 30 different accounts, so it's quite nice to store all this info in a CMDB and generate all the Putty session from it.

Unfortunately Putty uses the Windows Registry - which sucks. There are information on how to export this info, but I could not figure out how to store the hostname-username-password.

I find it much easier to bypass putty with MTPutty and generate myself the mtputty.xml file.
Here they explain how:

I am creating mtputty.xml myself. How can I encrypt my passwords?

You can use XML tag "PlainPassword" instead of "Password". Specify your password under this tag as a plaintext. When you quit MTPuTTY, PlainPassword will be removed automatically, but your password will be saved encrypted.

I will ignore the MTPutty/Servers/Putty section and do only the MTPutty/Internals/Putty/Node. Each node is like this:
<Node Type="1">
 <CLParams>-load PH30-0KWP355 -ssh -P 2228 -l oracle -pw *****</CLParams>