Sometimes you will end up in getting an exception like below when starting a server pointed to MySQL DB.
ERROR - DatabaseUtil Database Error - Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server
One possible reason can be since you have mapped, bind-address to an IP in /etc/mysql/my.cnf
The default is 0.0.0.0 which is all interfaces. This setting does not
restrict which IPs can access the server, unless you specified
127.0.0.1 for localhost only or some other IP.
bind-address = 0.0.0.0
Once this is done, restart mysql server.
sudo service mysql restart
Tuesday, July 7, 2015
Monday, May 11, 2015
Simple explaination for URL configurations done during IS as Key Manager in WSO2 API Manager
When you configure as IS as Key Manager, this document can be refereed. The below explanations for some of the URLs given in the configuration.
Make the following changes in the api-manager.xml file you just copied.
Why do we point to API Manager ? This is because this will call the Gateway node in API manager which points to the Key Manager
Why we point to the NIO/Passthru port ? This is because, here we will call the _RevokeAPI_.xml which is deployed in synapse folder of the Gateway. (In a distributed scenario, we point to the _RevokeAPI_.xml that resides in the Gateway worker node)
Note : So in a distributed scenario (APIM distributed scenario), In store if you call Revoke or Regenerate, store will call the key Manager/Validator and key Manager/Validator will call the gateway.
So in Store we have to configure KeyValidator/Key manager server url and in Key Manager/Validator we have to configure gateway server url (Passthru). Inside Gateway the apis will be called (NIO)
<ServerURL>https://${GATEWAY_SERVER_HOST}:{port}/services/</ServerURL>
Why we point to API Manager ? This is because this will call the Gateway node in API manager. This is to identify the gateway node.
Why we point to servlet port ? This is because it calls the admin services.
Note : This is same like as above explained. Since IS is the Key Validator/Manager it calls the gateway.
Why IS : This is because authentication will be done via Key manager/validator
Why we point to servlet port ? This is because it calls the admin services.
Why IS : This is because authentication will be done via Key manager/validator
Why we point to servlet ports : This is because it calls admin services
GW worker : Use when invoking - So only the passthrough/NIO ports will be used
Note : When you configure API endpoints in gateway (Which is in synapse folder (E.g., _AuthorizeAPI_.xml, _RevokeAPI_.xml, _TokenAPI_.xml), you should edit them only in gateway manager since it will depsync to workers. Otherwise it can cause issues.
In WSO2 IS Side :
Make the following changes in the api-manager.xml file you just copied.
- Change the <RevokeAPIURL> so that it points to the API Manager server. Note that if API Manager is running in distributed mode (has a separate node for the Gateway), you need to point this URL to the Gateway node. This is done so that when the token is revoked, the Gateway cache is updated as well. The port value you enter here must be the NIO port. See Default Ports of WSO2 Products for more information.
Why do we point to API Manager ? This is because this will call the Gateway node in API manager which points to the Key Manager
Why we point to the NIO/Passthru port ? This is because, here we will call the _RevokeAPI_.xml which is deployed in synapse folder of the Gateway. (In a distributed scenario, we point to the _RevokeAPI_.xml that resides in the Gateway worker node)
Note : So in a distributed scenario (APIM distributed scenario), In store if you call Revoke or Regenerate, store will call the key Manager/Validator and key Manager/Validator will call the gateway.
So in Store we have to configure KeyValidator/Key manager server url and in Key Manager/Validator we have to configure gateway server url (Passthru). Inside Gateway the apis will be called (NIO)
- Change the <ServerURL> occurring under the <APIGateway> (of the Key Manager/Key Validator node) section so that it points to the API Manager server. If you are using distributed mode, this needs to point to the Gateway node as well. This is done so that when the token is regenerated, the Gateway cache is updated as well. The port value you enter here must be the management transport port.
<ServerURL>https://${GATEWAY_SERVER_HOST}:{port}/services/</ServerURL>
Why we point to API Manager ? This is because this will call the Gateway node in API manager. This is to identify the gateway node.
Why we point to servlet port ? This is because it calls the admin services.
Note : This is same like as above explained. Since IS is the Key Validator/Manager it calls the gateway.
In WSO2 APIM Side :
Open the api-manager.xml file found in the <APIM_HOME>/repository/conf directory and change the following.- Change the ServerURL of the AuthManager to point to IS.
Why IS : This is because authentication will be done via Key manager/validator
Why we point to servlet port ? This is because it calls the admin services.
- Change the ServerURL of the APIKeyManager to point to IS.
Why IS : This is because authentication will be done via Key manager/validator
Why we point to servlet ports : This is because it calls admin services
Usage of ports in a gateway cluster when fronted by Nginx:
GW manager : Use to publish APIs - So only the servlet ports will be usedGW worker : Use when invoking - So only the passthrough/NIO ports will be used
Note : When you configure API endpoints in gateway (Which is in synapse folder (E.g., _AuthorizeAPI_.xml, _RevokeAPI_.xml, _TokenAPI_.xml), you should edit them only in gateway manager since it will depsync to workers. Otherwise it can cause issues.
Monday, April 27, 2015
How to Enable and test Custom SSL Profiles in WSO2 ESB used for SSL communicating
For this I have used WSO2 ESB 4.8.1 and WSO2 Application Server 5.2.1.
WSO2 ESB uses the truststore for SSL communicating and keystore-truststore pair for Mutual SSL communicating.
In here I have used a trust store for SSL communicating.
Configure App Server as backend
1. Use app server as backend
2. Create a new keystore in App server in <Appserver_Home>/repository/resources/security
keytool -genkey -alias appserver -keyalg RSA -keysize 1024 -keypass password -keystore appserver.jks -storepass password
3. Export in to a pem file by following command
keytool -export -alias appserver -keystore appserver.jks -storepass password -file appserver.pem
4. Edit the carbon.xml in appserver as below :
1. Created a new keystore.
keytool -genkey -alias esb -keyalg RSA -keysize 1024 -keypass password -keystore esb.jks -storepass password
2. Copy and paste appserver.pem in to the <ESB_HOME>repository/resources/security folder Import appserver.pem in to esb.jks by following command.
keytool -import -alias appservernewesb -file appserver.pem -keystore esb.jks -storepass password
3. Configure esb for custom profile in axis2.xml as below.
1. Restart Appserver (offset=0) and ESB (offset = 10) by the command :
"sh wso2server.sh" or "sh wso2server.sh -Djavax.net.debug=ssl:handshake " to view the detailed logs.
Following logs should be printed during restart.
[2015-04-27 18:33:19,397] INFO - ClientConnFactoryBuilder HTTPS Loading Identity Keystore from : repository/resources/security/wso2carbon.jks
[2015-04-27 18:33:19,400] INFO - ClientConnFactoryBuilder HTTPS Loading Trust Keystore from : repository/resources/security/client-truststore.jks
[2015-04-27 18:33:19,408] INFO - ClientConnFactoryBuilder HTTPS Loading custom SSL profiles for the HTTPS sender
[2015-04-27 18:33:19,408] INFO - ClientConnFactoryBuilder HTTPS Loading Trust Keystore from : repository/resources/security/esb.jks
[2015-04-27 18:33:19,409] INFO - ClientConnFactoryBuilder HTTPS Custom SSL profiles initialized for 1 servers
2. Create the below proxy in ESB.
3. Invoke the Proxy.
Following response will be received.
WSO2 ESB uses the truststore for SSL communicating and keystore-truststore pair for Mutual SSL communicating.
In here I have used a trust store for SSL communicating.
Configure App Server as backend
Configure backend :
1. Use app server as backend
2. Create a new keystore in App server in <Appserver_Home>/repository/resources/security
keytool -genkey -alias appserver -keyalg RSA -keysize 1024 -keypass password -keystore appserver.jks -storepass password
3. Export in to a pem file by following command
keytool -export -alias appserver -keystore appserver.jks -storepass password -file appserver.pem
4. Edit the carbon.xml in appserver as below :
<KeyStore>
<!-- Keystore file location-->
<Location>${carbon.home}/repository/resources/security/appserver.jks</Location>
<!-- Keystore type (JKS/PKCS12 etc.)-->
<Type>JKS</Type>
<!-- Keystore password-->
<Password>password</Password>
<!-- Private Key alias-->
<KeyAlias>appserver</KeyAlias>
<!-- Private Key password-->
<KeyPassword>password</KeyPassword>
</KeyStore>
Configure ESB :
1. Created a new keystore.
keytool -genkey -alias esb -keyalg RSA -keysize 1024 -keypass password -keystore esb.jks -storepass password
2. Copy and paste appserver.pem in to the <ESB_HOME>repository/resources/security folder Import appserver.pem in to esb.jks by following command.
keytool -import -alias appservernewesb -file appserver.pem -keystore esb.jks -storepass password
3. Configure esb for custom profile in axis2.xml as below.
<parameter name="customSSLProfiles">
<profile>
<servers>10.100.0.31:9443</servers>
<TrustStore>
<Location>repository/resources/security/esb.jks</Location>
<Type>JKS</Type>
<Password>password</Password>
</TrustStore>
</profile>
</parameter>
Invoke and Test :
1. Restart Appserver (offset=0) and ESB (offset = 10) by the command :
"sh wso2server.sh" or "sh wso2server.sh -Djavax.net.debug=ssl:handshake " to view the detailed logs.
Following logs should be printed during restart.
[2015-04-27 18:33:19,397] INFO - ClientConnFactoryBuilder HTTPS Loading Identity Keystore from : repository/resources/security/wso2carbon.jks
[2015-04-27 18:33:19,400] INFO - ClientConnFactoryBuilder HTTPS Loading Trust Keystore from : repository/resources/security/client-truststore.jks
[2015-04-27 18:33:19,408] INFO - ClientConnFactoryBuilder HTTPS Loading custom SSL profiles for the HTTPS sender
[2015-04-27 18:33:19,408] INFO - ClientConnFactoryBuilder HTTPS Loading Trust Keystore from : repository/resources/security/esb.jks
[2015-04-27 18:33:19,409] INFO - ClientConnFactoryBuilder HTTPS Custom SSL profiles initialized for 1 servers
2. Create the below proxy in ESB.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="SecureHello"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<outSequence>
<send/>
</outSequence>
<endpoint>
<address uri="https://localhost:9443/services/HelloService/"/>
</endpoint>
</target>
<publishWSDL uri="http://localhost:9763/services/HelloService?wsdl"/>
<description/>
</proxy>
3. Invoke the Proxy.
<body>
<p:greet xmlns:p="http://www.wso2.org/types">
<!--0 to 1 occurrence-->
<name>ushani</name>
</p:greet>
</body>
Following response will be received.
<ns:greetResponse xmlns:ns="http://www.wso2.org/types">
<return>Hello World, ushani !!!</return>
</ns:greetResponse>
Tuesday, March 17, 2015
How to monitor the created tcp connections for a particular proxy service in WSO2 ESB
As an example if we
want to monitor the number of tcp connections created during a proxy
invocation, the following steps can be performed.
1. Assume you need to
monitor the number of tcp connections created for the following proxy
service :
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="Proxy1"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<property name="NO_KEEPALIVE" value="true" scope="axis2"/>
<clone>
<target>
<sequence>
<send>
<endpoint>
<address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
</endpoint>
</send>
</sequence>
</target>
<target>
<sequence>
<send>
<endpoint>
<address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
</endpoint>
</send>
</sequence>
</target>
<target>
<sequence>
<send>
<endpoint>
<address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
</endpoint>
</send>
</sequence>
</target>
</clone>
</inSequence>
<outSequence>
<aggregate>
<completeCondition>
<messageCount/>
</completeCondition>
<onComplete xmlns:m0="http://services.samples" expression="//m0:getQuoteResponse">
<send/>
</onComplete>
</aggregate>
</outSequence>
</target>
<description/>
</proxy>
You will see there
are 5 clones. Therefore it should create only 5 tcp connections.
2. We have used
SimpleStockQuoteService service as the backend.
3. Since you need to
monitor the connections created, we should delay the response coming
from the backend. Therefore we need to change the code slightly in
the SimpleStockQuoteService.
We have include a
Thread.sleep() for 10 seconds until we monitor the number of
connections.
Therefore go to
<ESB_HOME>/samples/axis2Server/src/SimpleStockQuoteService/src/samples/services/SimpleStockQuoteService.java
and add the Thread.sleep(10000); as below to hold the response for sometime.
and add the Thread.sleep(10000); as below to hold the response for sometime.
public GetQuoteResponse getQuote(GetQuote request) throws Exception {
Thread.sleep(10000);
if ("ERR".equals(request.getSymbol())) {
throw new Exception("Invalid stock symbol : ERR");
}
System.out.println(new Date() + " " + this.getClass().getName() +
" :: Generating quote for : " + request.getSymbol());
return new GetQuoteResponse(request.getSymbol());
}
4. Build the
SimpleStockQuoteService once again by “ant” in here,
<ESB_HOME>/samples/axis2Server/src/SimpleStockQuoteService
5. Now start the
axis2server
6. Now you have to
open a terminal and provide the following netstat command to get the
process id.
sudo netstat --tcp --listening --programs
You will see the
relevant SimpleStockQuoteService which is up in port 9000 like below.
tcp6 0 0
[::]:9000 [::]:* LISTEN
20664/java
So your process ID
will be 20664.
7. Then open a terminal and provide the below command to view the tcp
connections for the particular process id.
watch -n1 -d "netstat -n -tap | grep 20664"
8. Now open your soapui and send the following request to Proxy1
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples" xmlns:xsd="http://services.samples/xsd">
<soapenv:Header/>
<soapenv:Body>
<ser:getQuote>
<!--Optional:-->
<ser:request>
<!--Optional:-->
<xsd:symbol>IBM</xsd:symbol>
</ser:request>
</ser:getQuote>
</soapenv:Body>
</soapenv:Envelope>
9. View the tcp connections created in the terminal which you have
been monitoring as soon as you send the request. You should be able
to view only 3 connections since we have configured like that in
proxy using clone mediator.
tcp6 0 0 127.0.0.1:9000 127.0.0.1:44218
ESTABLISHED 20664/java
tcp6 0 0 127.0.0.1:9000 127.0.0.1:44219
ESTABLISHED 20664/java
tcp6 0 0 127.0.0.1:9000 127.0.0.1:44217
ESTABLISHED 20664/java
Tuesday, February 17, 2015
A sample on a WSO2 ESB proxy with a DBLookup mediator and a dedicated faultSequence to excute during an error
Databases :
DB customer should be created with the required tables.
DB : customerDetails
table : customers
Proxy :
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="TestProxyUsh"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence onError="testError">
<dblookup>
<connection>
<pool>
<password>root</password>
<user>root</user>
<url>jdbc:mysql://host:3306/customerDetails</url>
<driver>com.mysql.jdbc.Driver</driver>
</pool>
</connection>
<statement>
<sql>SELECT * FROM customers WHERE name =?</sql>
<parameter value="WSO2" type="INTEGER"/>
<result name="company_id" column="id"/>
</statement>
</dblookup>
</inSequence>
<faultSequence>
<log level="custom">
<property name="text" value="An unexpected error occurred for the service"/>
</log>
</faultSequence>
</target>
<description/>
</proxy>
onError targeting sequence :
<sequence xmlns="http://ws.apache.org/ns/synapse" name="testError">
<log>
<property name="error" value="Error Occurred"/>
</log>
</sequence>
Invoke :
curl -v http://host:8280/services/TestProxyUsh
DB customer should be created with the required tables.
DB : customerDetails
table : customers
Proxy :
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="TestProxyUsh"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence onError="testError">
<dblookup>
<connection>
<pool>
<password>root</password>
<user>root</user>
<url>jdbc:mysql://host:3306/customerDetails</url>
<driver>com.mysql.jdbc.Driver</driver>
</pool>
</connection>
<statement>
<sql>SELECT * FROM customers WHERE name =?</sql>
<parameter value="WSO2" type="INTEGER"/>
<result name="company_id" column="id"/>
</statement>
</dblookup>
</inSequence>
<faultSequence>
<log level="custom">
<property name="text" value="An unexpected error occurred for the service"/>
</log>
</faultSequence>
</target>
<description/>
</proxy>
onError targeting sequence :
<sequence xmlns="http://ws.apache.org/ns/synapse" name="testError">
<log>
<property name="error" value="Error Occurred"/>
</log>
</sequence>
Invoke :
curl -v http://host:8280/services/TestProxyUsh
One possible reason and solution for getting Access denied for user 'username'@'host' in mysql when accessing from outside
Sometimes we might get the below exception when creating a DB connection.
{org.apache.synapse.mediators.db.DBLookupMediator}
org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Access denied for user 'username'@'203.94.95.133'
Reasons :
The particular IP might not be accessible from outside.
Therefore you need to grant priviledges by the below command in mysql :
GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
Sometimes you might try out below :
GRANT ALL PRIVILEGES ON *.* TO 'password'@'%' WITH GRANT OPTION;
Eventhough it says Query OK, still the issue can be there since you have not used the password.
Also you must do a Flush privileges to update it.
Hope this might help sometimes.
{org.apache.synapse.mediators.db.DBLookupMediator}
org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Access denied for user 'username'@'203.94.95.133'
Reasons :
The particular IP might not be accessible from outside.
Therefore you need to grant priviledges by the below command in mysql :
GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
Sometimes you might try out below :
GRANT ALL PRIVILEGES ON *.* TO 'password'@'%' WITH GRANT OPTION;
Eventhough it says Query OK, still the issue can be there since you have not used the password.
Also you must do a Flush privileges to update it.
Hope this might help sometimes.
Monday, February 16, 2015
A possible reason and solution for getting 400 Bad Request even when the synapse configuration in WSO2 ESB is correct
Sometimes you might spend lot of time in analyzing the reason for getting 400 bad request when you invoke an up and running backend service through WSO2 ESB.
When you configure and save the synapse configuration of your proxy, you will not see any issue. But sometimes there can a possible reason for this issue.
One good example is explained below :
Look at the below synapse configuration of WSO2 ESB proxy service.
<proxy name="statuscodeProxy"
transports="https http"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<log level="full"/>
<send>
<endpoint>
<address uri="http://10.100.0.31:8090"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<log level="full"/>
<send/>
</outSequence>
</target>
</proxy>
By the look of it, this is alright and you are good to configure it in WSO2 ESB. But the endpoint defined as : http://10.100.0.31:8090 is not exactly the endpoint the backend service expects.
Sometimes there can be missing parameters etc. But if you exactly know your backend service does not expect any parameters and still it throws a 400 bad reques, can you imagine the reason for this?
After spending hours, I accidently found a possible reason :
it was due to the backend expects a / at the end of the endpoint. So it expects :
http://10.100.0.31:8090/ except http://10.100.0.31:8090
If you configure a tcpmon in between ESB and the backend, you will see the difference as below :
http://10.100.0.31:8090 : GET HTTP/1.1 - 400 bad Request
http://10.100.0.31:8090/ : GET / HTTP/1.1 - 200 OK
So if you too come across this situation, please try out this option. Sometimes this might save your time! :)
When you configure and save the synapse configuration of your proxy, you will not see any issue. But sometimes there can a possible reason for this issue.
One good example is explained below :
Look at the below synapse configuration of WSO2 ESB proxy service.
<proxy name="statuscodeProxy"
transports="https http"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<log level="full"/>
<send>
<endpoint>
<address uri="http://10.100.0.31:8090"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<log level="full"/>
<send/>
</outSequence>
</target>
</proxy>
By the look of it, this is alright and you are good to configure it in WSO2 ESB. But the endpoint defined as : http://10.100.0.31:8090 is not exactly the endpoint the backend service expects.
Sometimes there can be missing parameters etc. But if you exactly know your backend service does not expect any parameters and still it throws a 400 bad reques, can you imagine the reason for this?
After spending hours, I accidently found a possible reason :
it was due to the backend expects a / at the end of the endpoint. So it expects :
http://10.100.0.31:8090/ except http://10.100.0.31:8090
If you configure a tcpmon in between ESB and the backend, you will see the difference as below :
http://10.100.0.31:8090 : GET HTTP/1.1 - 400 bad Request
http://10.100.0.31:8090/ : GET / HTTP/1.1 - 200 OK
So if you too come across this situation, please try out this option. Sometimes this might save your time! :)
Labels:
400 bad request,
Enterprise Service Bus,
ESB,
WSO
Subscribe to:
Posts (Atom)