I want to use Liferay Message bus in DXP. I have written the following code.
DemoSender.java
package demo.sender.portlet;
import demo.sender.constants.DemoSenderPortletKeys;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.Message;
import com.liferay.portal.kernel.messaging.MessageBus;
import com.liferay.portal.kernel.messaging.MessageBusUtil;
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.Portlet;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* #author parth.ghiya
*/
#Component(
immediate = true,
property = {
"com.liferay.portlet.display-category=category.sample",
"com.liferay.portlet.instanceable=true",
"javax.portlet.display-name=demo-sender Portlet",
"javax.portlet.init-param.template-path=/",
"javax.portlet.init-param.view-template=/view.jsp",
"javax.portlet.name=" + DemoSenderPortletKeys.DemoSender,
"javax.portlet.resource-bundle=content.Language",
"javax.portlet.security-role-ref=power-user,user"
},
service = Portlet.class
)
public class DemoSenderPortlet extends MVCPortlet {
#Activate
protected void activate(BundleContext bundleContext) {
_bundleContext = bundleContext;
}
public void sendMessage(
ActionRequest actionRequest, ActionResponse actionResponse) {
if (_log.isInfoEnabled()) {
_log.info("Sending message to DE Echo service");
}
Message message = new Message();
message.setDestinationName("MyEchoDestination");
message.setPayload("Hello World!");
message.setResponseDestinationName("MyEchoResponse");
_messageBus.sendMessage(message.getDestinationName(), message);
}
private static final Log _log = LogFactoryUtil.getLog(DemoSenderPortlet.class);
private BundleContext _bundleContext;
#Reference
private MessageBus _messageBus;
}
DemoReceiver.java
package demo.receiver.portlet;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.BaseMessageListener;
import com.liferay.portal.kernel.messaging.Message;
import com.liferay.portal.kernel.messaging.MessageBus;
import com.liferay.portal.kernel.messaging.MessageListener;
#Component(
immediate = true, property = {"destination.name=MyEchoDestination"},
service = MessageListener.class
)
public class DemoReceiverPortlet extends BaseMessageListener {
#Override
protected void doReceive(Message message) throws Exception {
if (_log.isInfoEnabled()) {
_log.info("Received: " + message);
}
String payload = (String)message.getPayload();
if (_log.isInfoEnabled()) {
_log.info("Message payload: " + payload);
}
/*
String responseDestinationName = message.getResponseDestinationName();
if ((responseDestinationName != null) &&
(responseDestinationName.length() > 0)) {
Message responseMessage = new Message();
responseMessage.setDestinationName(responseDestinationName);
responseMessage.setResponseId(message.getResponseId());
//This is just for demo purposes
responseMessage.setPayload(payload);
_messageBus.sendMessage(
message.getResponseDestinationName(), responseMessage);
}
*/
}
private static final Log _log = LogFactoryUtil.getLog(DemoReceiverPortlet.class);
#Reference
private volatile MessageBus _messageBus;
}
The problem is that my doReceive method is never getting called.
What configuration needs to be further added?
Regards
P.S : in DemoSender, i send some message on click of button
Edit # 1
I did added configurator code as follows.
package demo.receiver.portlet;
import java.util.Dictionary;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import com.liferay.portal.kernel.concurrent.DiscardOldestPolicy;
import com.liferay.portal.kernel.concurrent.RejectedExecutionHandler;
import com.liferay.portal.kernel.concurrent.ThreadPoolExecutor;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.Destination;
import com.liferay.portal.kernel.messaging.DestinationConfiguration;
import com.liferay.portal.kernel.messaging.DestinationFactory;
import com.liferay.portal.kernel.messaging.MessageBus;
import com.liferay.portal.kernel.util.HashMapDictionary;
#Component(
enabled = false, immediate = true,
service = DemoReceiverConfigurator.class
)
public class DemoReceiverConfigurator {
#Activate
protected void activate(ComponentContext componentContext) {
_bundleContext = componentContext.getBundleContext();
System.out.println("===demo===");
Dictionary<String, Object> properties =
componentContext.getProperties();
DestinationConfiguration destinationConfiguration =
new DestinationConfiguration(DestinationConfiguration.DESTINATION_TYPE_PARALLEL,"MyEchoDestination");
destinationConfiguration.setMaximumQueueSize(200);
RejectedExecutionHandler rejectedExecutionHandler =
new DiscardOldestPolicy() {
#Override
public void rejectedExecution(
Runnable runnable, ThreadPoolExecutor threadPoolExecutor) {
if (_log.isWarnEnabled()) {
_log.warn(
"The current thread will handle the request " +
"because the audit router's task queue is at " +
"its maximum capacity");
}
super.rejectedExecution(runnable, threadPoolExecutor);
}
};
destinationConfiguration.setRejectedExecutionHandler(
rejectedExecutionHandler);
Destination destination = _destinationFactory.createDestination(
destinationConfiguration);
Dictionary<String, Object> destinationProperties =
new HashMapDictionary<>();
destinationProperties.put("destination.name", destination.getName());
_destinationServiceRegistration = _bundleContext.registerService(
Destination.class, destination, destinationProperties);
}
#Deactivate
protected void deactivate() {
if (_destinationServiceRegistration != null) {
Destination destination = _bundleContext.getService(
_destinationServiceRegistration.getReference());
_destinationServiceRegistration.unregister();
destination.destroy();
}
_bundleContext = null;
}
#Reference(unbind = "-")
protected void setMessageBus(MessageBus messageBus) {
}
private static final Log _log = LogFactoryUtil.getLog(
DemoReceiverConfigurator.class);
private volatile BundleContext _bundleContext;
#Reference
private DestinationFactory _destinationFactory;
private volatile ServiceRegistration<Destination>
_destinationServiceRegistration;
}
But my Activate method aint getting called, i have enabledfalse in my message listener class and enabled = false, immediate = true in my Configurator class.
Dont know what i am missing.
Often in OSGi, this seemingly obvious configuration is enough. In this case though, it obviously isn't, because Liferay now knows about the message you're sending and that you're interested to receive, but the Messagebus doesn't know about this destination to be created.
It seems obvious - if there is a listener to a particular message, there probably needs to be a destination. But what type will it be? Parallel processing? How many parallel handlers? Synchronous? Queued? This is what you'll need to do.
While a quick search didn't find a documentation on how to do this, you can use this configurator as an example for creating the missing link.
MessageBus documentation was improved a few days ago, have a look to following page https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/message-bus
Related
I tried to get NexmoClient object without success.
I Fill in API_KEY and API_SECRET with the values I copied from the Nexmo Dashboard.
import com.nexmo.client.NexmoClient;
import com.nexmo.client.auth.AuthMethod;
import com.nexmo.client.auth.TokenAuthMethod;
import com.nexmo.client.sms.SmsSubmissionResult;
import com.nexmo.client.sms.messages.TextMessage;
public class SendSMS {
public static void main(String[] args) throws Exception {
AuthMethod auth = new TokenAuthMethod(1111,22222);
NexmoClient client = new NexmoClient(auth);
}
}
"
After the Gradle run, I was expected to NexmoClient object as they wrote in the docs https://www.nexmo.com/blog/2017/05/03/send-sms-messages-with-java-dr/
for continue to the next step, but I didn't know where to insert the following info
TextMessage message = new TextMessage(FROM_NUMBER, TO_NUMBER, "Hello from
Nexmo!");
SmsSubmissionResult[] responses =
client.getSmsClient().submitMessage(message);
for (SmsSubmissionResult response : responses) {
System.out.println(response);
}
You can put that code below where you initialize the client. Your whole class will then look like this:
import com.nexmo.client.NexmoClient;
import com.nexmo.client.auth.AuthMethod;
import com.nexmo.client.auth.TokenAuthMethod;
import com.nexmo.client.sms.messages.TextMessage;
public class SendSMS {
private static final String FROM_NUMBER = "";
private static final String TO_NUMBER = "";
public static void main(String[] args) throws Exception {
AuthMethod auth = new TokenAuthMethod(1111, 22222);
NexmoClient client = new NexmoClient(auth);
TextMessage message = new TextMessage(FROM_NUMBER, TO_NUMBER, "Hello from Nexmo !");
SmsSubmissionResult[] responses = client.getSmsClient().submitMessage(message);
for (SmsSubmissionResult response : responses) {
System.out.println(response);
}
}
}
This blog post is actually a bit old and suggests using an older version of the server SDK. There's an updated example on the developer portal as some things have changed in the newer versions of the SDK: https://developer.nexmo.com/messaging/sms/code-snippets/send-an-sms
I am new to Spring Integration and new to Stack Overflow. I am looking for some help in understanding Spring Integration as it relates to a request-reply pattern. From reading on the web, I am thinking that I should be using a Service Activator to enable this type of use case.
I am using JMS to facilitate the sending and receiving of XML based messages. Our underlining implementation is IBM Websphere MQ.
I am also using Spring Boot (version 1.3.6.RELEASE) and attempting to use a pure annotation based configuration approach (if that is possible). I have searched the web and see some example but nothing that so far I can see that helps me understand how it all fits together. The Spring Integration documentation is excellent but I am still struggling with how all the pieces fit together. I apologize in advance if there is something out there that I missed. I treat posting here as a last alternative.
Here is what I have for my configuration:
package com.daluga.spring.integration.configuration
import com.ibm.mq.jms.MQConnectionFactory;
import com.ibm.mq.jms.MQQueue;
import com.ibm.msg.client.wmq.WMQConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.InboundChannelAdapter;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.Poller;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.core.JmsTemplate;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
//import com.ibm.msg.client.services.Trace;
#Configuration
public class MQConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(MQConfiguration.class);
#Value("${host-name}")
private String hostName;
#Value("${port}")
private int port;
#Value("${channel}")
private String channel;
#Value("${time-to-live}")
private int timeToLive;
#Autowired
#Qualifier("MQConnectionFactory")
ConnectionFactory connectionFactory;
#Bean(name = "jmsTemplate")
public JmsTemplate provideJmsTemplate() {
JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
jmsTemplate.setExplicitQosEnabled(true);
jmsTemplate.setTimeToLive(timeToLive);
jmsTemplate.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
return jmsTemplate;
}
#Bean(name = "MQConnectionFactory")
public ConnectionFactory connectionFactory() {
CachingConnectionFactory ccf = new CachingConnectionFactory();
//Trace.setOn();
try {
MQConnectionFactory mqcf = new MQConnectionFactory();
mqcf.setHostName(hostName);
mqcf.setPort(port);
mqcf.setChannel(channel);
mqcf.setTransportType(WMQConstants.WMQ_CM_CLIENT);
ccf.setTargetConnectionFactory(mqcf);
ccf.setSessionCacheSize(2);
} catch (JMSException e) {
throw new RuntimeException(e);
}
return ccf;
}
#Bean(name = "requestQueue")
public Destination createRequestQueue() {
Destination queue = null;
try {
queue = new MQQueue("REQUEST.QUEUE");
} catch (JMSException e) {
throw new RuntimeException(e);
}
return queue;
}
#Bean(name = "replyQueue")
public Destination createReplyQueue() {
Destination queue = null;
try {
queue = new MQQueue("REPLY.QUEUE");
} catch (JMSException e) {
throw new RuntimeException(e);
}
return queue;
}
#Bean(name = "requestChannel")
public QueueChannel createRequestChannel() {
QueueChannel channel = new QueueChannel();
return channel;
}
#Bean(name = "replyChannel")
public QueueChannel createReplyChannel() {
QueueChannel channel = new QueueChannel();
return channel;
}
}
And here is my Service class:
package com.daluga.spring.integration.service
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.stereotype.Service;
#Service
public class MyRequestReplyService {
private static final Logger LOGGER = LoggerFactory.getLogger(MyRequestReplyService.class);
#ServiceActivator(inputChannel = "replyChannel")
public void sendAndReceive(String requestPayload) {
// How to get replyPayload
}
}
So, at this point, I am not quite sure how to glue all this together to make this work. I don't understand how to glue together my request and reply queues to the service activator to make this all work.
The service I am calling (JMS/Webshere MQ based) is using the typical message and correlation id so that I can properly tied the request to the corresponding response.
Can anyone provide me any guidance on how to get this to work? Please let me know what additional information I can provide to make this clear.
Thanks in advance for your help!
Dan
Gateways provide request/reply semantics.
Instead of using a JmsTemplate directly, you should be using Spring Integration's built-in JMS Support.
#Bean
#ServiceActivator(inputChannel="requestChannel")
public MessageHandler jmsOutGateway() {
JmsOutboundGateway outGateway = new JmsOutboundGateway();
// set properties
outGateway.setOutputChannel(replyChannel());
return outGateway;
}
If you want to roll your own, change the service activator method the return a reply type and use one of the template sendAndReceive() or convertSendAndReceive() methods.
The sample app uses XML configuration but should provide some additional guidance.
I am trying to implement the Apache Configuration 2 in my codebase
import java.io.File;
import java.util.concurrent.TimeUnit;
import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.builder.ConfigurationBuilderEvent;
import org.apache.commons.configuration2.builder.ReloadingFileBasedConfigurationBuilder;
import org.apache.commons.configuration2.builder.fluent.Parameters;
import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
import org.apache.commons.configuration2.event.EventListener;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.configuration2.reloading.PeriodicReloadingTrigger;
import org.apache.commons.configuration2.CompositeConfiguration;
public class Test {
private static final long DELAY_MILLIS = 10 * 60 * 5;
public static void main(String[] args) {
// TODO Auto-generated method stub
CompositeConfiguration compositeConfiguration = new CompositeConfiguration();
PropertiesConfiguration props = null;
try {
props = initPropertiesConfiguration(new File("/tmp/DEV.properties"));
} catch (ConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
compositeConfiguration.addConfiguration( props );
compositeConfiguration.addEventListener(ConfigurationBuilderEvent.ANY,
new EventListener<ConfigurationBuilderEvent>()
{
#Override
public void onEvent(ConfigurationBuilderEvent event)
{
System.out.println("Event:" + event);
}
});
System.out.println(compositeConfiguration.getString("property1"));
try {
Thread.sleep(14*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Have a script which changes the value of property1 in DEV.properties
System.out.println(compositeConfiguration.getString("property1"));
}
protected static PropertiesConfiguration initPropertiesConfiguration(File propsFile) throws ConfigurationException {
if(propsFile.exists()) {
final ReloadingFileBasedConfigurationBuilder<PropertiesConfiguration> builder =
new ReloadingFileBasedConfigurationBuilder<PropertiesConfiguration>(PropertiesConfiguration.class)
.configure(new Parameters().fileBased()
.setFile(propsFile)
.setReloadingRefreshDelay(DELAY_MILLIS)
.setThrowExceptionOnMissing(false)
.setListDelimiterHandler(new DefaultListDelimiterHandler(';')));
final PropertiesConfiguration propsConfiguration = builder.getConfiguration();
PeriodicReloadingTrigger trigger = new PeriodicReloadingTrigger(builder.getReloadingController(),
null, 1, TimeUnit.SECONDS);
trigger.start();
return propsConfiguration;
} else {
return new PropertiesConfiguration();
}
}
}
Here is a sample code that I using to check whether the Automatic Reloading works or not. However when the underlying property file is updated, the configuration doesn't reflect it.
As per the documentation :
One important point to keep in mind when using this approach to reloading is that reloads are only functional if the builder is used as central component for accessing configuration data. The configuration instance obtained from the builder will not change automagically! So if an application fetches a configuration object from the builder at startup and then uses it throughout its life time, changes on the external configuration file become never visible. The correct approach is to keep a reference to the builder centrally and obtain the configuration from there every time configuration data is needed.
https://commons.apache.org/proper/commons-configuration/userguide/howto_reloading.html#Reloading_File-based_Configurations
This is different from what the old implementation was.
I was able to successfully execute your sample code by making 2 changes :
make the builder available globally and access the configuration from the builder :
System.out.println(builder.getConfiguration().getString("property1"));
add the listener to the builder :
`builder.addEventListener(ConfigurationBuilderEvent.ANY, new EventListener() {
public void onEvent(ConfigurationBuilderEvent event) {
System.out.println("Event:" + event);
}
});
Posting my sample program, where I was able to successfully demonstrate it
import java.io.File;
import java.util.concurrent.TimeUnit;
import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.builder.ConfigurationBuilderEvent;
import org.apache.commons.configuration2.builder.ReloadingFileBasedConfigurationBuilder;
import org.apache.commons.configuration2.builder.fluent.Parameters;
import org.apache.commons.configuration2.event.EventListener;
import org.apache.commons.configuration2.reloading.PeriodicReloadingTrigger;
public class TestDynamicProps {
public static void main(String[] args) throws Exception {
Parameters params = new Parameters();
ReloadingFileBasedConfigurationBuilder<PropertiesConfiguration> builder =
new ReloadingFileBasedConfigurationBuilder<PropertiesConfiguration>(PropertiesConfiguration.class)
.configure(params.fileBased()
.setFile(new File("src/main/resources/override.properties")));
PeriodicReloadingTrigger trigger = new PeriodicReloadingTrigger(builder.getReloadingController(),
null, 1, TimeUnit.SECONDS);
trigger.start();
builder.addEventListener(ConfigurationBuilderEvent.ANY, new EventListener<ConfigurationBuilderEvent>() {
public void onEvent(ConfigurationBuilderEvent event) {
System.out.println("Event:" + event);
}
});
while (true) {
Thread.sleep(1000);
System.out.println(builder.getConfiguration().getString("property1"));
}
}
}
The problem with your implementation is, that the reloading is done on the ReloadingFileBasedConfigurationBuilder Object and is not being returned to the PropertiesConfiguration Object.
I am trying to connect my Desktop to the PHILIPS Hue light server using java.
When the code runs, it will flow into the Controller.java. When that happens, the FindBridges method in Controller.java runs. This is where the error occurs. In debugging, it displays a NullPointerException in thread "AWT-Event-Queue-0".
I presume that the server/lightbulb cannot be found at all, even though it is turned on and my android application can connect to it.
The error is stated below:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at com.philips.lighting.gui.DesktopView$1.actionPerformed(DesktopView.java:72)
Controller.java
package com.philips.lighting;
import java.util.List;
import java.util.Random;
import javax.swing.JDialog;
import com.philips.lighting.hue.sdk.upnp.*;
import com.philips.lighting.data.HueProperties;
import com.philips.lighting.gui.AccessPointList;
import com.philips.lighting.gui.DesktopView;
import com.philips.lighting.gui.LightColoursFrame;
import com.philips.lighting.gui.PushLinkFrame;
import com.philips.lighting.hue.sdk.PHAccessPoint;
import com.philips.lighting.hue.sdk.PHBridgeSearchManager;
import com.philips.lighting.hue.sdk.PHHueSDK;
import com.philips.lighting.hue.sdk.PHMessageType;
import com.philips.lighting.hue.sdk.PHSDKListener;
import com.philips.lighting.model.PHBridge;
import com.philips.lighting.model.PHBridgeResourcesCache;
import com.philips.lighting.model.PHHueError;
import com.philips.lighting.model.PHHueParsingError;
import com.philips.lighting.model.PHLight;
import com.philips.lighting.model.PHLightState;
public class Controller {
private PHHueSDK phHueSDK;
private DesktopView desktopView;
private PushLinkFrame pushLinkDialog;
private LightColoursFrame lightColoursFrame;
private static final int MAX_HUE=65535;
private Controller instance;
public Controller(DesktopView view) {
this.desktopView = view;
this.phHueSDK = PHHueSDK.getInstance(); // or phHueSDK = PHHueSDK.getInstance();
this.instance = this;
}
public void findBridges() {
//To uniquely identify your app in the bridge whitelist we recommend you set your app name, and the device
phHueSDK.setAppName("SmartShowroomApp"); // e.g. phHueSDK.setAppName("QuickStartApp");
phHueSDK.setDeviceName("SmartDevice"); // e.g. If you are programming for Android: phHueSDK.setDeviceName(android.os.Build.MODEL);
phHueSDK = PHHueSDK.getInstance();
PHBridgeSearchManager sm = (PHBridgeSearchManager) phHueSDK.getSDKService(PHHueSDK.SEARCH_BRIDGE);
sm.search(true, true);
//This starts a UPNP/Portal Search and takes around 10 seconds.
//The PHSDKListener (onAccessPointsFound) will be notified with the bridges found.
}
private PHSDKListener listener = new PHSDKListener() {
#Override
public void onAccessPointsFound(List<PHAccessPoint> accessPointsList) {
// Handle your bridge search results here.
//Typically if multiple results are returned you will want to display them in a list
// and let the user select their bridge.
//If one is found you may opt to connect automatically to that bridge.
phHueSDK = PHHueSDK.getInstance();
desktopView.getFindingBridgeProgressBar().setVisible(false);
if (accessPointsList != null && accessPointsList.size() > 0)
{
AccessPointList accessPointList = new AccessPointList(accessPointsList, instance);
accessPointList.setVisible(true);
accessPointList.setLocationRelativeTo(null); // Centre the AccessPointList Frame
phHueSDK.getAccessPointsFound().clear(); // Clear all connected access points
phHueSDK.getAccessPointsFound().addAll(accessPointsList); // Adds multiple results to the list
}
else
{
PHBridgeSearchManager sm = (PHBridgeSearchManager) phHueSDK.getSDKService(PHHueSDK.SEARCH_BRIDGE);
sm.search(false, false, true);
}
}
#Override
public void onAuthenticationRequired(PHAccessPoint accessPoint) {
// Start the Pushlink Authentication.
phHueSDK = PHHueSDK.getInstance();
desktopView.getFindingBridgeProgressBar().setVisible(false);
phHueSDK.startPushlinkAuthentication(accessPoint);
// Arriving here indicates that Pushlinking is required (to prove the User has physical access to the bridge).
//Typically here you will display a pushlink image (with a timer) indicating to to the user they need to push the button on their bridge within 30 seconds.
pushLinkDialog = new PushLinkFrame(instance);
pushLinkDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
pushLinkDialog.setModal(true);
pushLinkDialog.setLocationRelativeTo(null); // Center the dialog.
pushLinkDialog.setVisible(true);
}
#Override
public void onBridgeConnected(PHBridge bridge) {
phHueSDK = PHHueSDK.getInstance();
phHueSDK.setSelectedBridge(bridge);
phHueSDK.enableHeartbeat(bridge, PHHueSDK.HB_INTERVAL);
// Here it is recommended to set your connected bridge in your sdk object (as above) and start the heartbeat.
// At this point you are connected to a bridge so you should pass control to your main program/activity.
// Also it is recommended you store the connected IP Address/ Username in your app here.
//This will allow easy automatic connection on subsequent use.
// Remember to disable the heartbeat when exiting your app
//phHueSDK.disableAllHeartbeat();
//If you are only interested in a particular resource (e.g. Lights), you can enable the multi resource heartbeat as follows:
//PHHeartbeatManager heartbeatManager = PHHeartbeatManager.getInstance();
//heartbeatManager.enableLightsHeartbeat(bridge, PHHueSDK.HB_INTERVAL);
// To stop the heartbeat you can use either of the below
//heartbeatManager.disableLightsHeartbeat(bridge);
//heartbeatManager.disableAllHeartbeats(bridge);
desktopView.getFindingBridgeProgressBar().setVisible(false);
String username = HueProperties.getUsername();
String lastIpAddress = bridge.getResourceCache().getBridgeConfiguration().getIpAddress();
System.out.println("On connected: IP " + lastIpAddress);
HueProperties.storeUsername(username);
HueProperties.storeLastIPAddress(lastIpAddress);
HueProperties.saveProperties();
// Update the GUI.
desktopView.getLastConnectedIP().setText(lastIpAddress);
desktopView.getLastUserName().setText(username);
// Close the PushLink dialog (if it is showing).
if (pushLinkDialog!=null && pushLinkDialog.isShowing()) {
pushLinkDialog.setVisible(false);
}
// Enable the Buttons/Controls to change the hue bulbs.s
desktopView.getRandomLightsButton().setEnabled(true);
desktopView.getSetLightsButton().setEnabled(true);
}
#Override
public void onCacheUpdated(List cacheNotificationsList, PHBridge bridge) {
// Here you receive notifications that the BridgeResource Cache was updated. Use the PHMessageType to
// check which cache was updated, e.g.
if (cacheNotificationsList.contains(PHMessageType.LIGHTS_CACHE_UPDATED)) {
System.out.println("Lights Cache Updated ");
}
}
#Override
public void onConnectionLost(PHAccessPoint accessPoint) {
// Here you would handle the loss of connection to your bridge.
phHueSDK = PHHueSDK.getInstance();
if (accessPoint == null)
{
System.out.println("Please reconnect to your bridge.");
}
}
#Override
public void onConnectionResumed(PHBridge bridge) {
PHHueSDK phHueSDK = PHHueSDK.getInstance();
for (int i = 0; i < phHueSDK.getDisconnectedAccessPoint().size(); i++)
{
if (phHueSDK.getDisconnectedAccessPoint().get(i).getIpAddress()
.equals(bridge.getResourceCache().getBridgeConfiguration().getIpAddress())) {
phHueSDK.getDisconnectedAccessPoint().remove(i);
}
}
}
#Override
public void onError(int code, final String message) {
// Here you can handle events such as Bridge Not Responding, Authentication Failed and Bridge Not Found.
if (code == PHHueError.BRIDGE_NOT_RESPONDING) {
desktopView.getFindingBridgeProgressBar().setVisible(false);
desktopView.getFindBridgesButton().setEnabled(true);
desktopView.getConnectToLastBridgeButton().setEnabled(true);
desktopView.showDialog(message);
}
else if (code == PHMessageType.PUSHLINK_BUTTON_NOT_PRESSED) {
pushLinkDialog.incrementProgress();
}
else if (code == PHMessageType.PUSHLINK_AUTHENTICATION_FAILED) {
if (pushLinkDialog.isShowing()) {
pushLinkDialog.setVisible(false);
desktopView.showDialog(message);
}
else {
desktopView.showDialog(message);
}
desktopView.getFindBridgesButton().setEnabled(true);
}
else if (code == PHMessageType.BRIDGE_NOT_FOUND) {
desktopView.getFindingBridgeProgressBar().setVisible(false);
desktopView.getFindBridgesButton().setEnabled(true);
desktopView.showDialog(message);
}
}
#Override
public void onParsingErrors(List<PHHueParsingError> parsingErrorsList) {
// Any JSON parsing errors are returned here.
//Typically your program should never return these.
for (PHHueParsingError parsingError: parsingErrorsList) {
System.out.println("ParsingError : " + parsingError.getMessage());
}
}
};
public PHSDKListener getListener() {
return listener;
}
public void setListener(PHSDKListener listener) {
this.listener = listener;
}
public void randomLights() {
PHBridge bridge = phHueSDK.getSelectedBridge();
PHBridgeResourcesCache cache = bridge.getResourceCache();
// And now you can get any resource you want, for example:
List<PHLight> allLights = cache.getAllLights();
Random rand = new Random();
for (PHLight light : allLights) {
PHLightState lightState = new PHLightState();
lightState.setHue(rand.nextInt(MAX_HUE));
bridge.updateLightState(light, lightState); // If no bridge response is required then use this simpler form.
}
}
public void showControlLightsWindow() {
if (lightColoursFrame == null) {
lightColoursFrame = new LightColoursFrame();
}
lightColoursFrame.setLocationRelativeTo(null); // Centre window
lightColoursFrame.setVisible(true);
}
/**
* Connect to the last known access point.
* This method is triggered by the Connect to Bridge button but it can equally be used to automatically connect to a bridge.
*
*/
public boolean connectToLastKnownAccessPoint() {
String username = HueProperties.getUsername();
String lastIpAddress = HueProperties.getLastConnectedIP();
if (username==null || lastIpAddress == null) {
desktopView.showDialog("Missing Last Username or Last IP. Last known connection not found.");
return false;
}
//Obviously, every time a user opens up their Android hue app or application you don't want them to have to select their bridge, authenticate pushlink everytime.
//The recommended way to overcome this issue is to store the connected IP Address/Username (using your preferred method storage) and if set try to connect automatically.
PHAccessPoint accessPoint = new PHAccessPoint();
accessPoint.setIpAddress(lastIpAddress);
accessPoint.setUsername(username);
phHueSDK.connect(accessPoint);
return true;
//Note that the .connect method returns control to your PHSDKListener, so when connected the onBridgeConnected will be called again, and if your users Bridge IP has changed for example, onError will be called and can be handled programatically.
}
public void enableFindBridgesButton() {
desktopView.getFindBridgesButton().setEnabled(true);
}
public void showProgressBar() {
desktopView.getFindingBridgeProgressBar().setVisible(true);
}
}
DesktopView.java
package com.philips.lighting.gui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import layout.TableLayout;
import com.philips.lighting.Controller;
import com.philips.lighting.data.HueProperties;
/**
* DesktopView.java
*
* The main GUI showing last connected IP/Username and buttons for Finding Bridges and Changing the Hue Lights, once connected to a bridge.
*
*/
public class DesktopView extends JFrame {
private static final long serialVersionUID = -7469471678945429320L;
private Controller controller;
private JButton setLightsButton;
private JButton randomLightsButton;
private JButton findBridgesButton;
private JButton connectToLastBridgeButton;
private JProgressBar findingBridgeProgressBar;
private JTextField lastConnectedIP;
private JTextField lastUserName;
public DesktopView(){
setTitle("Hue Desktop");
JPanel mainPanel = new JPanel();
// TODO - Move to another class
JPanel controls = new JPanel();
controls.setLayout(new GridLayout(2,3));
findingBridgeProgressBar = new JProgressBar();
findingBridgeProgressBar.setBorderPainted(false);
findingBridgeProgressBar.setIndeterminate(true);
findingBridgeProgressBar.setVisible(false);
//Set up components preferred size
String lastUsername = HueProperties.getUsername();
String lastConnectedIPStr = HueProperties.getLastConnectedIP();
JLabel labelLastConIP = new JLabel("Last Connected IP:");
lastConnectedIP = new JTextField(lastConnectedIPStr);
lastConnectedIP.setEditable(false);
JLabel labelLastUsername = new JLabel("Last UserName:");
lastUserName = new JTextField(lastUsername);
lastUserName.setEditable(false);
findBridgesButton = new JButton("Find New Bridges");
findBridgesButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
findBridgesButton.setEnabled(false);
connectToLastBridgeButton.setEnabled(false);
controller.findBridges();
findingBridgeProgressBar.setBorderPainted(true);
findingBridgeProgressBar.setVisible(true);
}
});
connectToLastBridgeButton = new JButton("Auto Connect");
connectToLastBridgeButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if (controller.connectToLastKnownAccessPoint()) {
connectToLastBridgeButton.setEnabled(false);
findBridgesButton.setEnabled(false);
findingBridgeProgressBar.setBorderPainted(true);
findingBridgeProgressBar.setVisible(true);
}
}
});
setLightsButton = new JButton("Change Light Colours");
setLightsButton.setEnabled(false);
setLightsButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
controller.showControlLightsWindow();
}
});
randomLightsButton = new JButton("Randomize Lights");
randomLightsButton.setEnabled(false);
randomLightsButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
controller.randomLights();
}
});
double border = 10;
double size[][] =
{{border, 160, 20, 300, 20, 160}, // Columns
{border, 26, 10, 26, 26, 26,6,26}}; // Rows
mainPanel.setLayout (new TableLayout(size));
mainPanel.add(labelLastConIP, " 1, 1");
mainPanel.add(lastConnectedIP, " 3, 1");
mainPanel.add(labelLastUsername, " 1, 3");
mainPanel.add(lastUserName, " 3, 3");
mainPanel.add(findingBridgeProgressBar, " 3, 5");
mainPanel.add(connectToLastBridgeButton, " 5, 1");
mainPanel.add(findBridgesButton, " 5, 3");
mainPanel.add(randomLightsButton, " 5, 5");
mainPanel.add(setLightsButton, " 5, 7");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(700,270));
getContentPane().add(new JLabel(" An example Java/Swing Desktop Application to control your Hue Lights."), BorderLayout.NORTH);
getContentPane().add(mainPanel, BorderLayout.CENTER);
//4. Size the frame.
pack();
setLocationRelativeTo(null); // Centre the window.
setVisible(true);
}
public void setController(Controller controller) {
this.controller = controller;
}
public JButton getSetLightsButton() {
return setLightsButton;
}
public JButton getRandomLightsButton() {
return randomLightsButton;
}
public JButton getFindBridgesButton() {
return findBridgesButton;
}
public JButton getConnectToLastBridgeButton() {
return connectToLastBridgeButton;
}
public void showDialog(String message) {
JOptionPane.showMessageDialog(this, message);
}
public JProgressBar getFindingBridgeProgressBar() {
return findingBridgeProgressBar;
}
public JTextField getLastConnectedIP() {
return lastConnectedIP;
}
public JTextField getLastUserName() {
return lastUserName;
}
}
HueDesktop.java
package com.philips.lighting;
import com.philips.lighting.data.HueProperties;
import com.philips.lighting.gui.DesktopView;
import com.philips.lighting.hue.sdk.PHHueSDK;
/**
* HueDesktop.java
* An example Java/Swing Desktop application illustrating how to connect to a bridge and change your Hue lights
* using a Java Desktop Application.
*
* For more information on programming for Hue see:
* http://developers.meethue.com
*
*/
class HueDesktop {
public static void main(String args[]) {
new HueDesktop();
}
public HueDesktop() {
PHHueSDK phHueSDK = PHHueSDK.create();
// Load in HueProperties, if first time use a properties file is created.
HueProperties.loadProperties();
// Set Up the View (A JFrame, MenuBar and Console).
DesktopView desktopView = new DesktopView();
// Bind the Model and View
Controller controller = new Controller(desktopView);
desktopView.setController(controller);
// Register the PHSDKListener to receive callbacks from the bridge.
phHueSDK.getNotificationManager().registerSDKListener(controller.getListener());
}
}
Did you ever solve this? In future it is probably best to post hue Java SDK issues on the GitHub site. https://github.com/PhilipsHue/PhilipsHueSDK-Java-MultiPlatform-Android/issues
I would have seen this sooner on here (I wrote this code btw so am possibly the culprit).
I do remember seeing a similar issue before, am pretty sure it was related to Macs and the JDK Compiler level used (I possibly used an incompatible Swing component on Mac and JDK 1.6). Can you let me know your OS and JDK Compiler level and I will check this further?
I want to create a java client for version proxy service present in wso2 esb. I have secured the version proxy with Username Token Authentication scenario. Now i have started creating the java client to invoke this secured proxy service and my client code is:
package org.wso2.carbon.security.ws;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.description.AxisBinding;
import org.apache.axis2.description.AxisEndpoint;
import org.apache.axis2.rpc.client.RPCServiceClient;
import org.apache.neethi.Policy;
import javax.xml.namespace.QName;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Map;
public class HelloServiceClient {
static {
System.setProperty("javax.net.ssl.trustStore", "/path/to/keystore" + File.separator+ "wso2carbon.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");
}
public static void main(String[] args) {
try {
int securityScenario = getSecurityScenario();
String repository = "/path/to/repo" + File.separator + "repository";
ConfigurationContext confContext =
ConfigurationContextFactory.
createConfigurationContextFromFileSystem(repository, null);
String endPoint = "HelloServiceHttpSoap12Endpoint";
if(securityScenario == 1){
endPoint = "HelloServiceHttpsSoap12Endpoint"; // scenario 1 uses HelloServiceHttpsSoap12Endpoint
}
RPCServiceClient dynamicClient =
new RPCServiceClient(confContext,
new URL("http://pc213712:8281/services/Version?wsdl"),
new QName("http://version.services.core.carbon.wso2.org", "Version"),
endPoint);
//Engage Modules
dynamicClient.engageModule("rampart");
dynamicClient.engageModule("addressing");
//TODO : Change the port to monitor the messages through TCPMon
if(securityScenario != 1){
dynamicClient.getOptions().setTo(new EndpointReference("http://pc213712:8281/services/Version/"));
}
//Get the policy from the binding and append the rampartconfig assertion
Map endPoints = dynamicClient.getAxisService().getEndpoints();
AxisBinding axisBinding = ((AxisEndpoint) endPoints.values().iterator().next()).getBinding();
Policy policy = axisBinding.getEffectivePolicy();
**policy.addAssertion(RampartConfigBuilder.createRampartConfig(securityScenario));**
axisBinding.applyPolicy(policy);
//Invoke the service
Object[] returnArray = dynamicClient.invokeBlocking(new QName("http://www.wso2.org/types","greet"),
new Object[]{"Alice"},
new Class[]{String.class});
System.out.println((String) returnArray[0]);
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static int getSecurityScenario() {
int scenarioNumber = 0;
while (scenarioNumber < 1 || scenarioNumber > 15) {
System.out.print("Insert the security scenario no : ");
String inputString = readOption();
try {
scenarioNumber = new Integer(inputString);
} catch (Exception e) {
System.out.println("invalid input, insert a integer between 1 and 15");
}
if(scenarioNumber < 1 || scenarioNumber > 15){
System.out.println("Scenario number should be between 1 and 15");
}
}
return scenarioNumber;
}
private static String readOption() {
try {
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
String str;
while ((str = console.readLine()).equals("")) {
}
return str;
} catch (Exception e) {
return null;
}
}
}
But in the above code i am struck at one line that is :
policy.addAssertion(RampartConfigBuilder.createRampartConfig(securityScenario));
Here in my rampart_core jar I am getting RampartConfigBuilder class but inside this class there is no such method called createRampartConfig. So i am unable to create Rampart configurations. What can i do to solve this issue? looking forward to your solutions. Thanks in advance