WSO2 ESB + activeMQ - wso2

I'm new in wso2 esb and jms. I send some messages from soapUI to wso2 esb. In my wso sequence a processed message goes to the jms. Is there a possibility to set "time to live" of this message from wso2 esb? Or some other ways?
In AMQ I added this:
<policyEntry queue="myQueue">
<deadLetterStrategy>
<individualDeadLetterStrategy
queuePrefix="DLQ." useQueueForQueueMessages="true" />
</deadLetterStrategy>
Something like
<property name="JMSExpiration" value="today+hour_long_value" scope="transport" type="STRING"></property>
in sequence have no effect.

If you are using JMS Message Store you can just set property JMS_PROD_TIME_TO_LIVE.
<property name="JMS_PROD_TIME_TO_LIVE" value="15000" />
<store messageStore="my_jms_message_store" />
Tested with WSO2 ESB 4.9.0 (with synapse version 2.1.3-wso2v11)
You can find more information in JmsProducer code
Same way you can set for example message priority (property JMS_PROD_PRIORITY).

The only workable way, I found out, is to create own Mediator, which will set the time-to-live of a message and send it to the queue. The queue name is preset in a sequence, then called mediator:
<property xmlns="http://ws.apache.org/ns/synapse" name="qname" value="your_queue_name" scope="default" type="STRING"></property>
<class xmlns="http://ws.apache.org/ns/synapse" name="com.example.JMSMessageTimeToLiveMediator"></class>
A mediator class:
public class JMSMessageTimeToLiveMediator extends AbstractMediator implements
ManagedLifecycle {
private static String CON_FACTORY_NAME = "QueueConnectionFactory";
private static String DEF_PROP_QNAME = "qname";
private static long TIME_TO_LIVE = 60000;
private static QueueConnectionFactory cf;
public boolean mediate(MessageContext context) {
Connection connection = null;
Session session = null;
try {
connection = cf.createQueueConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
String queueName = (String) context.getProperty(DEF_PROP_QNAME);
Destination destination = session.createQueue(queueName);
MessageProducer producer = session.createProducer(destination);
producer.setTimeToLive(TIME_TO_LIVE);
TextMessage message = session.createTextMessage(context
.getEnvelope().toString());
producer.send(message);
} catch (JMSException e) {
log.error("ProduceJMS ERROR: " + e.getClass() + " "
+ e.getMessage());
} catch (Exception e) {
log.error("ProduceJMS ERROR: " + e.getClass() + " "
+ e.getMessage());
} finally {
try {
session.close();
connection.close();
} catch (JMSException e) {
log.error("ProduceJMS ERROR: " + e.getMessage());
}
}
return true;
}
public void init(SynapseEnvironment emvironment) {
Hashtable<String, Object> environment = new Hashtable<String, Object>();
environment.put("java.naming.factory.initial",
"org.apache.activemq.jndi.ActiveMQInitialContextFactory");
log.debug("ProduceJMS INIT");
try {
InitialContext ic = new InitialContext(environment);
cf = (QueueConnectionFactory) ic.lookup(CON_FACTORY_NAME);
} catch (NamingException e) {
log.error("ProduceJMS INIT ERROR: " + e.getMessage());
}
}
public void destroy() {
}
}

Related

wso2 identity server custom handler reading from properties file

public class UserRegistrationCustomEventHandler extends AbstractEventHandler {
JSONObject jsonObject = null;
private static final Log log = LogFactory.getLog(UserRegistrationCustomEventHandler.class);
#Override
public String getName() {
return "customClaimUpdate";
}
if (IdentityEventConstants.Event.POST_SET_USER_CLAIMS.equals(event.getEventName())) {
String tenantDomain = (String) event.getEventProperties()
.get(IdentityEventConstants.EventProperty.TENANT_DOMAIN);
String userName = (String) event.getEventProperties().get(IdentityEventConstants.EventProperty.USER_NAME);
Map<String, Object> eventProperties = event.getEventProperties();
String eventName = event.getEventName();
UserStoreManager userStoreManager = (UserStoreManager) eventProperties.get(IdentityEventConstants.EventProperty.USER_STORE_MANAGER);
// String userStoreDomain = UserCoreUtil.getDomainName(userStoreManager.getRealmConfiguration());
#SuppressWarnings("unchecked")
Map<String, String> claimValues = (Map<String, String>) eventProperties.get(IdentityEventConstants.EventProperty
.USER_CLAIMS);
String emailId = claimValues.get("http://wso2.org/claims/emailaddress");
userName = "USERS/"+userName;
JSONObject json = new JSONObject();
json.put("userName",userName );
json.put("emailId",emailId );
log.info("JSON:::::::"+json);
// Sample API
//String apiValue = "http://192.168.1.X:8080/SomeService/user/updateUserEmail?email=sujith#gmail.com&userName=USERS/sujith";
try {
URL url = new URL(cityAppUrl) ;
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(5000);
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestMethod("POST");
log.info("CONN:::::::::::::"+con);
OutputStream os = con.getOutputStream();
os.write(cityAppUrl.toString().getBytes("UTF-8"));
os.close();
InputStream in = new BufferedInputStream(con.getInputStream());
String result = org.apache.commons.io.IOUtils.toString(in, "UTF-8");
jsonObject = new JSONObject(result);
log.info("JSON OBJECT:::::::::"+jsonObject);
}
catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void init(InitConfig configuration) throws IdentityRuntimeException {
super.init(configuration);
}
#Override
public int getPriority(MessageContext messageContext) {
return 250;
}
}
I'm using wso2 identity server 5.10.0 and have to push the updated claim value to an API so I'm using a custom handler and have subscribed to POST_SET_USER_CLAIMS, i have to read the API value from deployment.toml file in jave code of the custom handler. So can any one please help here to read the value from deployment file
I can fetch the updated claim value in logs but im not able to get the API value. So can anyone help me here to read the value from deployment file.
Since the API path is required inside your custom event handler, let's define the API path value as one of the properties of the event handler.
Add the deployment.toml config as follows.
[[event_handler]]
name= "UserRegistrationCustomEventHandler"
subscriptions =["POST_SET_USER_CLAIMS"]
properties.apiPath = "http://192.168.1.X:8080/SomeService/user/updateUserEmail"
Once you restart the server identity-event.properties file populates the given configs.
In your custom event handler java code needs to read the config from identity-event.properties file. The file reading is done at the server startup and every config is loaded to the memory.
By adding this to your java code, you can load to configured value in the property.
configs.getModuleProperties().getProperty("UserRegistrationCustomEventHandler.apiPath")
NOTE: property name needs to be defined as <event_handler_name>.<property_name>
Here is a reference to such event hanlder's property loading code snippet https://github.com/wso2-extensions/identity-governance/blob/68e3f2d5e246b6a75f48e314ee1019230c662b55/components/org.wso2.carbon.identity.password.policy/src/main/java/org/wso2/carbon/identity/password/policy/handler/PasswordPolicyValidationHandler.java#L128-L133

Unit Test for a Java Component accessing ActiveMq in Mule Flow

I have the below Java Class which retrieve messages from JMS queue. This class is invoked in a mule flow. Could you please advice on how I can write a Junit for this class? I have tried to create a standalone broker but I am having trouble
public Object getMessages(final MuleEventContext eventContext)
{
final String consumerID = eventContext.getMessage().getProperty("consumerID", PropertyScope.INVOCATION);
final String messageSelector = "ConsumerID = '" + consumerID + "'";
JmsConnector amqConnector = (JmsConnector) eventContext.getMuleContext().getRegistry().lookupConnector("Active_MQ");
ConnectionFactory factory = amqConnector.getConnectionFactory();
Connection connection = null;
List<String> listOfMessages = null;
try
{
connection = factory.createConnection();
//Consumer Settings
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue(queuename");
MessageConsumer consumer = session.createConsumer(queue, messageSelector);
//Browser Settings
Session sessionBrowser = amqConnector.getSession( false, false );
Queue queueBrowser = sessionBrowser.createQueue( queuename );
QueueBrowser qBrowser = sessionBrowser.createBrowser( queueBrowser, messageSelector );
Enumeration<Message> enumeration = qBrowser.getEnumeration();
connection.start();
listOfMessages = new ArrayList<String>();
while (enumeration.hasMoreElements())
{
enumeration.nextElement();
Message message = consumer.receive();
TextMessage msg = (TextMessage) message;
listOfMessages.add(msg.getText());
}
//Close Browser Settings
qBrowser.close(); sessionBrowser.close();
//Close Consumer Settings
consumer.close(); session.close();
//Close Connection
connection.close();
}
catch ( Exception e )
{
throw new RuntimeException("Unable to retrieve messages from Queue "+ e);
}
}
You can create FunctionalTestCase, and then:
Test the class directly by calling the method, or
Test the whole scenario by calling the flow
public class MessageServiceTest extends FunctionalTestCase {
#Test
public void testJavaClass() throws Exception {
MuleEventContext eventContext = MuleTestUtils.getTestEventContext("", MessageExchangePattern.REQUEST_RESPONSE, muleContext);
MessageService messageService = new MessageService();
assertNotNull(messageService.getMessages(eventContext));
}
#Test
public void testFlow() throws Exception {
MuleEvent event = runFlow("messageserviceFlow");
MuleMessage message = event.getMessage();
assertNotNull(message);
assertNotNull(message.getPayload());
}
protected String getConfigResources() {
return "messageservice.xml";
}
}

how to send and receive soap messages in attribute name/value format?

What needs to be set in a web service so that soap messages are sent and received in param attribute format? For example, I need to send soap requests with parameters in this attribute name/value format:
<param name="controller_name">CPA Central</param>
and receive them in a similar attribute name/value format:
<attribute name="channel_number">1</attribute>
I've googled literally for 14 hours and cannot find how to do it! I would be so appreciative if someone could point me in the right direction.
Here's how I ended up doing it. Seems ridiculous that you have to intercept the outgoing soap message and reformat it, rather than creating it in the correct format to begin with. But if your forced to use magic black boxes like JAX-WS like I was, your stuck with the auto-format they provide apparently.
public class InneoquestLogicalHandler implements LogicalHandler<LogicalMessageContext> {
private static Logger logger = Logger.getLogger(InneoquestSoapHandler.class);
#Override
public boolean handleMessage(LogicalMessageContext context) {
boolean isResponse = (Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if(!isResponse){
logger.debug("InneoquestLogicalHandler.handleMessage(): this is a soap request");
}
else {
logger.debug("InneoquestLogicalHandler.handleMessage(): this is a soap response");
try {
try {
transform(context);
} catch (TransformerConfigurationException ex) {
java.util.logging.Logger.getLogger(InneoquestLogicalHandler.class.getName()).log(Level.SEVERE, null, ex);
} catch (SOAPException ex) {
java.util.logging.Logger.getLogger(InneoquestLogicalHandler.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (TransformerException ex) {
java.util.logging.Logger.getLogger(InneoquestLogicalHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
return true;
}
private void transform(LogicalMessageContext context) throws TransformerConfigurationException, TransformerException, SOAPException {
LogicalMessage msg = context.getMessage();
Source source = msg.getPayload();
Transformer xFormer = TransformerFactory.newInstance().newTransformer();
xFormer.setOutputProperty("omit-xml-declaration", "yes");
DOMResult result = new DOMResult();
xFormer.transform(source,result);
Document doc = (Document) result.getNode();
transformNodeList(doc,doc.getChildNodes());
source = new DOMSource(doc);
msg.setPayload(source);
}
private void transformNodeList(Document doc, NodeList nodeList) {
for (int i=0; i< nodeList.getLength(); i++) {
Node childNode = nodeList.item(i);
if (childNode.getNodeName().equals("channel_number")) {
Element elem = (Element)childNode;
doc.renameNode(elem, elem.getNamespaceURI(), "attribute");
elem.setAttribute("name", "channel_number");
}
else if (childNode.getNodeName().equals("count")) {
Element elem = (Element)childNode;
doc.renameNode(elem, elem.getNamespaceURI(), "response");
elem.setAttribute("rows", elem.getTextContent());
elem.setTextContent("");
elem.setAttribute("type", "success");
}
NodeList children = childNode.getChildNodes();
if (children != null) {
transformNodeList(doc,children);
}
}
}

Activemq concurrency fail in Apache camel route

Trying to send multiple requests at same instant to camel activemq route, one request is serviced and the other request is not serviced and sent back as it is. The Jms messages are set with JMScorrelationId too before sending like below
textMessage.setJMSCorrelationID(UUID.randomUUID().toString());
below is my activemq route
from("activemq:queue:TEST_QUEUE?disableReplyTo=true")
.setExchangePattern(ExchangePattern.InOut)
.process(new Processor() {
public void process(Exchange e) throws Exception {
log.info("Request : "
+ MessageHelper.extractBodyAsString(e.getIn()));
/*Processing Logic*/
}
})
.beanRef("testBean","postDetails")
.inOnly("activemq:queue:TEST_QUEUE");
Multiple (Test for 2 requests) requests sent to the above route concurrently not serviced except one. The servicemix.log shows all recieved requests. But only one is serviced.
Below is the code what is sending request deployed in jboss 6.1 as part of web application.
public Message receive(String message, String queueName) {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
"tcp://localhost:61616");
String userName = "smx";
String password = "smx";
Connection connection;
Message response =null;
try {
connection = connectionFactory.createConnection(userName, password);
connection.start();
((ActiveMQConnectionFactory) connectionFactory)
.setDispatchAsync(false);
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
Queue destination = session.createQueue(queueName);
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
TextMessage textMessage = session.createTextMessage(message);
Queue tempQueue = session.createQueue(queueName);
textMessage.setJMSReplyTo(tempQueue);
producer.send(textMessage);
MessageConsumer consumer = session.createConsumer(tempQueue);
response = consumer.receive();
response.acknowledge();
session.close();
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
return response;
}
Is there some or the other parameter im missing?? please suggest.
Camel will auto send back a reply if the JMS message has a JMSReplyTo header, so your route should just be
from("activemq:queue:TEST_QUEUE")
.process(new Processor() {
public void process(Exchange e) throws Exception {
log.info("Request : "
+ MessageHelper.extractBodyAsString(e.getIn()));
/*Processing Logic*/
}
})
.beanRef("testBean","postDetails");
At the end of the route (eg after calling testBean) then the content of the message body is used as the reply message, that are sent back to the queue named defined in the JMSReplyTo header.

sending request to wso2 identity server

am trying to send a request to the identity server but don't know how to do it. I know that identity server can help you test your policy by generating a request for you within the identity server but I don't know how to do this outside the identity server. So my question is how do I sent requests to identity server in order to have it check the request against the policy and return to me a result. I have tried the blog at http://hasini-gunasinghe.blogspot.com/2011/12/entitlement-service-xacml-pdp-as-web.html and it is not working. thank you
I tried the code in the blogpost and could get it worked with the following settings with WSO2 Identity Server 4.1.0 in localhost. Don't forget to give correct path to the wso2carbon.jks.
import org.apache.axis2.AxisFault;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.transport.http.HTTPConstants;
import org.wso2.carbon.authenticator.stub.AuthenticationAdminStub;
import org.wso2.carbon.identity.entitlement.stub.EntitlementServiceStub;
import org.wso2.carbon.identity.entitlement.ui.client.EntitlementServiceClient;
public class EntitlementClient {
private static String serverUrl = "https://localhost:9443/services/";
private AuthenticationAdminStub authstub = null;
private static ConfigurationContext ctx;
private static String authCookie = null;
private static EntitlementServiceClient entitlementServiceClient;
private static EntitlementServiceStub stub;
//sample XACML request captured from TryIt tool of IdentityServer.
private static String sampleRequest = "<Request xmlns=\"urn:oasis:names:tc:xacml:2.0:context:schema:os\"\n" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
" <Resource>\n" +
" <Attribute AttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\"\n" +
" DataType=\"http://www.w3.org/2001/XMLSchema#string\">\n" +
" <AttributeValue>ABCResource</AttributeValue>\n" +
" </Attribute>\n" +
" </Resource>\n" +
" <Subject>\n" +
" <Attribute AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\"\n" +
" DataType=\"http://www.w3.org/2001/XMLSchema#string\">\n" +
" <AttributeValue>admin</AttributeValue>\n" +
" </Attribute>\n" +
" <Attribute AttributeId=\"http://wso2.org/claims/role\"\n" +
" DataType=\"http://www.w3.org/2001/XMLSchema#string\">\n" +
" <AttributeValue>admin</AttributeValue>\n" +
" </Attribute>\n" +
" </Subject>\n" +
" <Action>\n" +
" <Attribute AttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\"\n" +
" DataType=\"http://www.w3.org/2001/XMLSchema#string\">\n" +
" <AttributeValue>read</AttributeValue>\n" +
" </Attribute>\n" +
" </Action>\n" +
" <Environment/>\n" +
"</Request>";
public static void main(String[] args) {
try {
//set trust store properties required in SSL communication.
System.setProperty("javax.net.ssl.trustStore",
"/home/pushpalanka/Servers/wso2is-4.1.1/repository/resources/security/wso2carbon.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");
//initialize authentication admin stub
EntitlementClient remoteEntitlementClient = new EntitlementClient();
//login using authentication admin stub providing valid credentials
remoteEntitlementClient.login("admin", "admin");
//initialize entitlement service stub with obtained authentication cookie
remoteEntitlementClient.initEntitlementClient();
//invoke EntitlementService by passing the XACML request and obtain the authorization decision
String decision = entitlementServiceClient.getDecision(sampleRequest);
//print the authorization decision
System.out.println(decision);
} catch (Exception e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
public EntitlementClient() {
try {
ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(null, null);
String authEPR = serverUrl + "AuthenticationAdmin";
authstub = new AuthenticationAdminStub(ctx, authEPR);
ServiceClient client = authstub._getServiceClient();
Options options = client.getOptions();
options.setManageSession(true);
options.setProperty(org.apache.axis2.transport.http.HTTPConstants.COOKIE_STRING, authCookie);
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
public String login(String username, String password) throws Exception {
//String cookie = null;
boolean loggedIn = authstub.login(username, password, "127.0.0.1");
if (loggedIn) {
System.out.println("The user " + username + " logged in successfully.");
authCookie = (String) authstub._getServiceClient().getServiceContext().getProperty(
HTTPConstants.COOKIE_STRING);
} else {
System.out.println("Error logging in " + username);
}
return authCookie;
}
public void initEntitlementClient() throws AxisFault {
entitlementServiceClient = new EntitlementServiceClient(authCookie, serverUrl, ctx);
}
}
Reference - http://hasini-gunasinghe.blogspot.com/2011/12/entitlement-service-xacml-pdp-as-web.html