Enterprise Architecture & Integration, SOA, ESB, Web Services & Cloud Integration

Enterprise Architecture & Integration, SOA, ESB, Web Services & Cloud Integration

Monday, 10 June 2013

Linux - How much swap memory should I need?

Always, you will encounter a typical question - how much memory should be allocated to swap memory? Should it be same as the size of RAM, twice the size of RAM or else? This blog is not a tutorial on swap memory but a tip on its size.

Earlier recommendations (in the era of smaller size RAM) maintained that one should use swap memory which is twice the size of the RAM. It does not hold good anymore. You needed more swap memory because the size of RAM was small. But, now-a-days, you don't need to rely on swap memory for your (large) memory requirement when adequate RAM is cheaply available. If you have a large RAM that is sufficient to support your applications, then dependency on the swap memory reduces a lot (if not eliminated completely).

See blow recommendation from RedHat.

Amount of RAM in the system Recommended swap space Recommended swap space if allowing for hibernation
⩽ 2GB 2 times the amount of RAM 3 times the amount of RAM
> 2GB – 8GB Equal to the amount of RAM 2 times the amount of RAM
> 8GB – 64GB 0.5 times the amount of RAM 1.5 times the amount of RAM
> 64GB 4GB of swap space No extra space needed

Read the following articles for more information.
https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Installation_Guide/s2-diskpartrecommend-ppc.html#id4394007

https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Storage_Administration_Guide/ch-swapspace.html

Tuesday, 12 March 2013

ERROR 1130 (HY000): Host 'hostname' is not allowed to connect to this MySQL server

By default, My SQL server does not allow remote access to the database, but often this is a requirement when you run your web/application server and database in two different machines.

You will have to put some extra work to make it working. The magic is that you will have to provide access to the client machine from which you are trying to access the remote server. While it may not be great  idea to provide root access to a client machine, this one will allow your client machine quickly to connect to the database server.

Here you go for step by step guide: -

Step1 : Log on to your remote mysql database server: mysql -u root -p
Step 2: Run the command to use mysql schema: use mysql
Step 3: Run the command to provide access: GRANT ALL ON *.* to 'root'@'<client-hostname or IP address>' IDENTIFIED BY '<your password>'
Ste 4: Run the command: flush PRIVILEGES

The above will allow you to access your database remotely.

Sometime, you may get an error "ERROR 1045 (28000): Access denied for user 'root'@'hostname' (using password: YES)". It is mostly due to an incorrect password.

Tuesday, 25 September 2012

Oracle SOA BPEL Exception Handling - WSDL messageType "{http://schemas.oracle.com/bpel/extension}remoteFault" of variable "" is not defined in any of the WSDL files

Exception handling is an essential requirement while building any robust application. It is true for the application that is built using BPEL also. As you would know, Oracle BPEL supports both business specific exceptions (they are declared in the service WSDL) and run time exceptions (Needless to say, they are NOT declared in the WSDL). This post is about supporting run time exception.

Assume that as part of your BPEL flow, you are invoking a SOAP service that is hosted remotely. When the remote service is not up and running, then BPEL flow will send back a fault to the client. The fault message will be something similar to the following: -

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
   <env:Header/>
   <env:Body>
      <env:Fault>
         <faultcode>env:Server</faultcode>
         <faultstring>oracle.fabric.common.FabricInvocationException: Unable to access the following endpoint(s): http://localhost:9090/axis2/services/StockQuoteService.StockQuoteServiceHttpSoap11Endpoint/</faultstring>
         <faultactor/>
         <detail>
            <exception>Unable to access the following endpoint(s): http://localhost:9090/axis2/services/StockQuoteService.StockQuoteServiceHttpSoap11Endpoint/</exception>
         </detail>
      </env:Fault>
   </env:Body>
</env:Envelope>


This is not a correct behaviour for a good application. The application should catch the exceptions and handle it properly depending on the application requirement. Assume that, in this case, you have to return a default value, say -1, instead of sending exception message.

Oracle BPEL supports this by having 'Add Catch' construct which can be added to the 'Scope' construct where in you actually have defined the 'Invoke' activity. In Oracle SOA suite 11g, when you add 'Catch' construct, it will import a WSDL (namely RuntimeFault.wsdl) that defines the structure of the runtime message automatically. The definition is as given below: -

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="RuntimeFault"
             targetNamespace="http://schemas.oracle.com/bpel/extension"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns="http://schemas.xmlsoap.org/wsdl/">

    <message name="RuntimeFaultMessage">
        <part name="code" type="xsd:string"/>
        <part name="summary" type="xsd:string"/>
        <part name="detail" type="xsd:string"/>
    </message>
</definitions>


The above message will support catching code, summary and details of the remote exception thrown because of the downtime of the remote service. In this example, we are not going to use any of these three parts (however, it is possible to do that). Alternatively, we are going to catch the exception and return a default value, say -1.

When you define the 'Catch' construct, it will add a line as given below in your .bpel file: -

<variable messageType="bpelx:remoteFault" name="FaultVar"/>

- where FaultVar is the name of the fault variable using which you can  access its child elements - code, summary and detail


After adding Catch construct, now do a 'Deploy' to application server. But you will get an error as given below: -

Error(67): WSDL messageType "{http://schemas.oracle.com/bpel/extension}remoteFault" of variable "" is not defined in any of the WSDL files

So, what went wrong?

Take a look at these two :-
a) FaultVar variable declaration in the bpel file and
b) RuntimeFaultMessage message definition in the RuntimeFault.wsdl.

The FaultVar is of 'bpelx:remoteFaul' type which is not defined anywhere. Instead, RuntimeFault.wsdl defines another messgae type which is of "RuntimeFaultMessage" type. So, solution is simple - just replace 'remoteFault' by 'RuntimeFaultMessage'. It will do the necessary MAGIC!!!

Now, recompile and deploy to application server. The BPEL service will get deployed onto the application server. When you access the service, now you will get the expected response

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
   <env:Body>
      <processResponse xmlns="http://xmlns.oracle.com/StockApps/StockMarket/StockMarketProcess">
         <result>-1</result>
      </processResponse>
   </env:Body>
</env:Envelope>


Hope this is useful to you.

Happy Fault Handling!

Monday, 17 September 2012

Oracle Business Rules error - Fact not found in the rule engine working memory, rule session execution failed

Recently, I got stuck with the a problem while I was learning Oracle Business Rules. Many of you would have faced this very same issue.

Fact not found in the rule engine working memory, rule session execution failed.
The rule session 60015 failed because an instance of the fact com.oracle.xmlns.rules.insuranceeligibility.ApplicantOutput could not be found in the working memory of the rule session.
This is most likely a rule modeling error. The decision service interaction expects the fact instance to exist in the working memory of the rule session. Check the rule actions in rule designer and make sure that a fact of the expected type is being asserted. If the error persists, contact Oracle Support Services. 60015


I am not intending to create a OBR tutorial page as there several good websites/blogs already available. Herewith I am including only the necessary details.

Please refer to the ruleset which I have created in JDeveloper editor.






There could be several reasons why you got this error. After hours of investigation, I 'accidentally' found the root cause - I have not defined 'else' condition in my rule set. Please find below the modified ruleset.









After the rule modification, now every thing seems to be working fine. Hope this tip will be useful in saving your valuable time. Here is the full BPEL flow for your reference.



Thursday, 2 August 2012

javax.mail.MessagingException: Can't send command to SMTP host & 530 5.7.1 Client was not authenticated

One of the easily available sample programs in the net is java mail application that you can use to send automated emails from java application. While running these java mail application program, sometimes you might get several errors - popular one is "Can't send command to SMTP host;".

The complete stack trace is here:-
Exception in thread "main" javax.mail.MessagingException: Can't send command to SMTP host;
  nested exception is:
    java.net.SocketException: Software caused connection abort: socket write error
    at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2106)
    at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2093)
    at com.sun.mail.smtp.SMTPTransport.close(SMTPTransport.java:1184)
    at javax.mail.Transport.send0(Transport.java:197)
    at javax.mail.Transport.send(Transport.java:124)
    at SendMail.main(SendMail.java:27)
Caused by: java.net.SocketException: Software caused connection abort: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(Unknown Source)
    at java.net.SocketOutputStream.write(Unknown Source)
    at com.sun.mail.util.TraceOutputStream.write(TraceOutputStream.java:114)
    at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
    at java.io.BufferedOutputStream.flush(Unknown Source)
    at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2104)
    ... 5 more


The sample code that generated the exception above is

import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;

public class SampleSMTPClient1 {

    public static void main(String args[]) throws Exception {

        Properties properties = new Properties();
        properties.setProperty("mail.smtp.host", "localhost" );
        Session session = Session.getDefaultInstance(properties);
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress("joe.smith@js.com"));
        message.addRecipient(Message.RecipientType.TO, new InternetAddress("jsmith@js.com"));
        message.setSubject("Wishes..!");
        message.setText("Have a great day!");

        System.out.println("Sending Message .....");
        Transport.send(message);
        System.out.println("Message Sent.....");
    }
}



By adding properties.put("mail.debug", "true"), your program can generate lots of debug information. I did so, and then I got all the below mentioned debug information.

DEBUG: JavaMail version 1.4.4
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc]}
DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]}
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
Sending Message .....
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "localhost", port 25, isSSL false
220 LOCALHOST Microsoft ESMTP MAIL Service ready at Thu, 2 Aug 2012 10:23:10 +0530
DEBUG SMTP: connected to host "localhost", port: 25

EHLO LOCALHOST
250-LOCALHOST Hello [10.xx.xx.xx]
250-SIZE
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-X-ANONYMOUSTLS
250-AUTH NTLM
250-X-EXPS GSSAPI NTLM
250-8BITMIME
250-BINARYMIME
250-CHUNKING
250-XEXCH50
250 XRDST
DEBUG SMTP: Found extension "SIZE", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "X-ANONYMOUSTLS", arg ""
DEBUG SMTP: Found extension "AUTH", arg "NTLM"
DEBUG SMTP: Found extension "X-EXPS", arg "GSSAPI NTLM"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "XEXCH50", arg ""
DEBUG SMTP: Found extension "XRDST", arg ""
DEBUG SMTP: use8bit false
MAIL FROM:<joe.smith@js.com>
530 5.7.1 Client was not authenticated
DEBUG SMTP: got response code 530, with response: 530 5.7.1 Client was not authenticated

RSET
DEBUG SMTP: EOF: [EOF]
com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.1 Client was not authenticated

    at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:2057)
    at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:1580)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1097)
    at javax.mail.Transport.send0(Transport.java:195)
    at javax.mail.Transport.send(Transport.java:124)
    at SendMail.main(SendMail.java:29)
QUIT

Now it is pretty much clear that client authentication is required. Otherwise your SMTP server will not allow you to send emails. Now, the question is - how do we pass the credentials required for the client authentication. While there may be other way possible, I have followed the below one and got it working.

You have to make two changes to the above code:
a) Add properties.put("mail.smtp.auth", "true");
b) Implement an authenticator class

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;

public class SMTPAuthenticator extends Authenticator { 
 
    protected PasswordAuthentication getPasswordAuthentication() { 
        return new PasswordAuthentication("username", "password"); 
    } 
} 


The modified mail client program is as below: -

import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;

public class SampleSMTPClient2 {

    public static void main(String args[]) throws Exception {

        Properties properties = new Properties();
        properties.setProperty("mail.smtp.host", "localhost" );

properties.put("mail.smtp.auth", "true");
        Session session = Session.getDefaultInstance(properties, new SMTPAuthenticator() );
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress("joe.smith@js.com"));
        message.addRecipient(Message.RecipientType.TO, new InternetAddress("jsmith@js.com"));
        message.setSubject("Wishes..!");
        message.setText("Have a great day!");

        System.out.println("Sending Message .....");
        Transport.send(message);
        System.out.println("Message Sent.....");
    }
}


Now rerun the program. Hope this works for you as well!