How do I change the port used for livetribe SLP? - java

I'm attempting to use LiveTribe SLP module (http://livetribe.codehaus.org/LiveTribe-SLP) to provide an SLP service for an application. I want to change the port from 427 to something else entirely. The documentation is sparse and even more confusing is that in the FAQ, it claims to link to an example that would show me exactly what I'm looking for. Unfortunately, it doesn't (unless I'm overlooking something). Does anyone know how to do this?

There is a client and server example here:
http://livetribe.org/SLP-Examples-JMX
(Link broken.)
These are the important lines on the server side:
// Allow this code to be run by non-root users on Linux/Unix
Settings settings = new MapSettings();
settings.put(Keys.PORT_KEY, 4427);
// Create the SLP ServiceAgent that advertises the JMX service
ServiceAgent serviceAgent = SLP.newServiceAgent(settings);
And on the client side:
// Allow this code to be run by non-root users on Linux/Unix
Settings settings = new MapSettings();
settings.put(Keys.PORT_KEY, 4427);
// Create the SLP UserAgentClient that discovers services
UserAgentClient userAgentClient = SLP.newUserAgentClient(settings);

Sorry about the bad documentation. We've had problems with it ever since we changed the L&F of the site to use Twitter Bootstrap.
The page should now fully render:
http://livetribe.org/SLP-Examples-JMX
Link broken.

Related

How can I get the enqueue and dequeue count for an ActiveMQ queue WITHIN my Java Spring app?

I have been scouring the internet for documentation on this and it's unbelievable how difficult it is to find. My goal is to create a REST endpoint where I can return queue details such as enqueue, dequeue, etc. counts for a custom dashboard I am making.
I keep seeing documentation such as this, this, and this, but I can't seem to figure out how to get these details in my actual program. I have gotten about as far as using the JMX GUI, but that really is not the direction I need to be going. Can anyone help me figure out how to get simple connection to a broker that will return these details? I really have tried to research this, but I have not been able to figure out a way to incorporate this information to my application in any meaningful away.
The way to monitor the broker is via the broker JMX endpionts and the management beans it exposes. Other means would be through the Jolokia REST API that exposes those same MBeans. One article showing how to use the Jolokia bits is here.
A brief example of using JMX with ActiveMQ is below.
// connection
String url = "service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi";
JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(url));
MBeanServerConnection connection = connector.getMBeanServerConnection();
// get queue size
ObjectName nameConsumers = new ObjectName("org.apache.activemq:type=Broker,brokerName=localhost,destinationType=Queue,destinationName=myqueue");
DestinationViewMBean mbView = MBeanServerInvocationHandler.newProxyInstance(connection, nameConsumers, DestinationViewMBean.class, true);
long queueSize = mbView.getQueueSize();

How to start CloudFoundry app using ReactorCloudFoundryClient?

I used StartApplicationRequest to create a sample request to start the application as given below:
StartApplicationRequest request = StartApplicationRequest.builder()
.applicationId("test-app-name")
.build();
Then, I used the ReactorCloudFoundryClient to start the application as shown below:
cloudFoundryClient.applicationsV3().start(request);
But my test application test-app-name is not getting started. I'm using latest Java CF client version (v4.5.0 RELEASE), but not seeing a way around to start the application.
Quite surprisingly, the outdated version seems to be working with the below code:
cfstatus = cfClient.startApplication("test-app-name"); //start app
cfstatus = cfClient.stopApplication("test-app-name"); //stop app
cfstatus = cfClient.restartApplication("test-app-name"); //stop app
I want to do the same with latest CF client library, but I don't see any useful reference. I referred to test cases written at CloudFoundry official Github repo. I derived to the below code after checking out a lot of docs:
StartApplicationRequest request = StartApplicationRequest.builder()
.applicationId("test-app-name")
.build();
cloudFoundryClient.applicationsV3().start(request);
Note that cloudFoundryClient is ReactorCloudFoundryClient instance as the latest library doesn't support the client class used with outdated code. I would like to do all operations (start/stop/restart) with latest library. The above code isn't working.
A couple things here...
Using the reactor based client, your call to cloudFoundryClient.applicationsV3().start(request) returns a Mono<StartApplicationResponse>. That's not the actual response, it's the possibility of one. You need to do something to get the response. See here for more details.
If you would like similar behavior to the original cf-java-client, you can call .block() on the Mono<StartApplicationResponse> and it will wait and turn into a response.
Ex:
client.applicationsV3()
.start(StartApplicationRequest.builder()
.applicationId("test-app-name")
.build())
.block()
The second thing is that it's .applicationId not applicationName. You need to pass in an application guid, not the name. As it is, you're going to get a 404 saying the application doesn't exist. You can use the client to fetch the guid, or you can use CloudFoundryOperations instead (see #3).
The CloudFoundryOperations interface is a higher-level API. It's easier to use, in general, and supports things like starting an app based on the name instead of the guid.
Ex:
ops.applications()
.start(StartApplicationRequest.builder()
.name("test-app-name").build())
.block();

Single Sign-On with Java Client

I am looking for a Single Sign-On authentication in a Java client.
Since I am logged in to Windows using an AD, the main goal is that I do not have to enter username and password again. I want Java to use the Ticket I recieved at Windows-login. This code is the best I have for the purpose:
LoginContext lc = new LoginContext("com.sun.security.jgss.krb5.initiate", new DialogCallbackHandler());
lc.login();
Subject.doAs(lc.getSubject(), (PrivilegedExceptionAction<Void>) () -> {
System.out.println("This is privileged");
return null;
});
I've set the java.security.krb5.conf and java.security.auth.login.config properties with corresponding conf-files, but still a dialog asking for Username and Password pops up.
I also tried working with GSSName, but GSSManager.createCredential() is also asking for Username and Password (probably using the TextCallbackHandler()).
I tried to get along with Waffle, but did not get it working. Most examples and explanations are Server sided (I only found one example combining server and client side, but I was not able to split it up).
I know, there are Similar questions (e.g. this), but i did not get that working without entering a password.
PS: i know, that DialogCallbackHandler is depricated, I use it for test purposes only.
Ok, after several tries I found a solution. The problem was not in the code, but in the registry. As stated on this page, since Java 7 You can't access the ticket of Windows natively. To change this, You have to set an additional registry key. For this, go into the registry folder
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters
and add the key
Value Name: AllowTgtSessionKey
Value Type: REG_DWORD
Value: 0x01
To fully make this work you will need some additional settings:
The jaas configuration file
In the jaas configuration file you have to set up which security modules jaas should use. The part in front of the brackets names your configuration. If you use the GSS libraries you must name it com.sun.security.jgss.krb5.initiate. When you use the LoginContext you just pass the name of the configuration as first parameter. My jaas.conf look as follows:
com.sun.security.jgss.krb5.initiate {
com.sun.security.auth.module.Krb5LoginModule required
useTicketCache = true;
};
The kerberos configuration
You will also need a configuration for the Kerberos module. This mainly contains the realm address, but can hold additional information. A minimal working example:
[realms]
YOUR.REALM.COM = {
kdc = your.realm.com:88
default_domain = REALM.COM
}
Note, that this is case sensitive!
The System Properties
Finally, you have to set up Java to find this files. You do this either by giving the properties on startup or by calling System.setProperty():
System.setProperty("java.security.krb5.conf", "src/resources/krb5.conf");
System.setProperty("java.security.auth.login.config", "src/resources/jaas.conf");

Executing URI commands in Java

One way that Steam lets users launch games and perform many other operations, is by using URI protocols, for example (from Valve developer community):
steam://run/<id> will launch the game that corresponds to the specified ID.
steam://validate/<id> will validate the game files of the specified ID.
How can I get Java to 'run' these? I don't even know what you call it, i.e. do you 'run' URIs, or 'execute' them, or what? Because persumably these URIs don't have anything to return, and the URI class in Java doesn't have anything related to 'executing' them, however URL does, but it doesn't work!
I've tried this:
...
try
{
URI testURI = URI.create("steam://run/240");
URL testURL = joinURI.toURL();
// URL testURL = new URL("steam://run/240") doesn't work either
joinURL.openConnection(); // Doesn't work
// joinURL.openStream() doesn't work either
}
catch (MalformedURLException e)
{
System.err.println(e.getMessage());
}
...
Each combination gives the error: unknown protocol: steam.
The system that Steam uses to handle the URIs is definitely working, because for example, I can type the above URI into Firefox and it works.
My eternal gratitude to the person who provides the answer!
Thanks
Try Desktop.browse(URI), this should start the "default action" which is the Steam client for a steam:// URI, e.g.
URI uri = new URI("steam://store/240");
if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().browse(uri);
}
The system that Steam uses to handle the URIs is definitely working, because for example, I can type the above URI into Firefox and it works.
It is working because Firefox (or other browsers) can associate unkown protocols with applications. When you load steam://xxx for the first time, Firefox asks you which application you want to open. If it didn't ask you, steam probably installed a browser plugin for that.
A Uniform Resource Identifier (URI) just identifies a resource, it doesn't necessarily describe how to access it. Moreover, for custom protocols, such as "steam" the vendor can define any underlying access conventions which compatible client programs must know to interact.
In order to "execute" a URI like this you need to know exactly how the protocol is implemented (is it over HTTP? TCP? UDP?) and how to speak with the server at the other end.
The Valve Developer Community wiki page might have some useful information.

How to use Javapns to Support Apple's Enhanced Notification Format

Greetings,
I am creating a Java based server to create push notifications for Apple's iOS APNs service. I have found Javapns on google code which seems to provide a simple basic framework to communicate with APNs, and which seems to be fairly wide used.
http://code.google.com/p/javapns/
However, reading Apple's docs, there is an "enhanced format" for notifications which supports "expiry" i.e. setting a time (well, in seconds) for a notification to expire if it hasn't yet been delivered. I do not see any way to set this using Javapns, and I am unsure how the APNs service handles expiry of notifications if you do not explicitly set it. So,
Does anyone know how to support the enhanced notification format of APNs specifically how to set the expiry?
Does anyone know how Apple handles notification expiry if it isn't explicitly set?
Does anyone have any suggestions that don't require me to start from scratch, as the server is currently functional as is?
Thanks in advance.
Andrew
I have recently made substantial contributions to the JavaPNS project, which lead to the release of JavaPNS 2.0 a few days ago. That version provides full support for the enhanced notification format, including the ability to set your own expiry.
Sylvain
Nice that you found the java library... to bad you didn't read the docs there.
I'll post some of the highlights below:
The existing code uses the 'Simple notification format' which does not return an error EVER.
See docs at:
http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html
I've tried updating to the 'Enhanced notification format' which is supposed to return an error, but I'm unable to get any errors back from the APNS. (also in the link above)
With the Enhanced format, the connection isn't being dropped immediately after sending data, but I'm not getting anything back from my socket.getInputSocket.read() call.
This issue will have to be tabled until I have more time to troubleshoot.
(Someone else commented)
Thanks a lot for looking into it.
I got the same result as yours. Maybe it has something to do with Apple Gateway.
So... you could:
1) Build your own
2) Help improve the existing library
3) Try another library like: https://github.com/notnoop/java-apns
4) Do nothing
Enhanced ios push here.
To send a notification, you can do it in three steps:
Setup the connection
ApnsService service =
APNS.newService()
.withCert("/path/to/certificate.p12", "MyCertPassword")
.withSandboxDestination()
.build();
Create and send the message
String payload = APNS.newPayload().alertBody("Can't be simpler than this!").build();
String token = "fedfbcfb....";
service.push(token, payload);
To query the feedback service for inactive devices:
Map<String, Date> inactiveDevices = service.getInactiveDevices();
for (String deviceToken : inactiveDevices.keySet()) {
Date inactiveAsOf = inactiveDevices.get(deviceToken);
...
}

Categories