Storing data for later retrieval

I have the code below which performs an http POST within the onWriteComplete handler. I would like to remove the hard coded callback URL.

  1. What would be the recommended approach for this?

I need to pass this url at the start of the process e.g. on connect or on publish as I need to ensure the http post is still made if the user disconnects unintentionally e.g. browser close, crash, etc.

  1. Is it best to pass the url (from Flash) using a param onConnect and store on app instance WMSProperties (I find that the property is always null within the onWriteComplete handler)?

  2. Can I pass the url (from Flash) on publish and store on the stream WMSProperties (I cannot see a params argument onPublish)?

  3. Can anyone post a suggestion with thread safe code?

Finally I would like to increase the security a notch by setting up authentication for the callback.

  1. How would I go about implementing Proxy-Authorization using setRequestProperty. For example I use this with curl
curl --data "foo=bar" "http://example.com/api/stream/processed" -u "username:password"

. What would be the recommended approach with HTTPUtils?

Thanks in advance.

import com.wowza.wms.application.IApplicationInstance;
import com.wowza.wms.module.ModuleBase;
import com.wowza.wms.stream.IMediaStream;
import com.wowza.wms.stream.IMediaWriterActionNotify;
import com.wowza.util.HTTPUtils;
import java.io.File;
import java.util.Map;
public class MediaWriteListener extends ModuleBase {
	class WriteListener implements IMediaWriterActionNotify {
		public void onFLVAddMetadata(IMediaStream stream, Map<String, Object> extraMetadata){}
		
		public void onWriteComplete(IMediaStream stream, File file) {
			getLogger().info("ModuleWriteListener.onWriteComplete[" + stream.getContextStr() + "]: " + file.getName());
			String callbackUrl = "http://example.com/api/stream/processed";
			HTTPUtils.HTTPRequestToByteArray(callbackUrl, "POST", "id=" + file.getName() + "&state=finished", null);
		}
	}
    
    public void onAppStart(IApplicationInstance appInstance) {	
		appInstance.addMediaWriterListener(new WriteListener());
	}
}

Hi,

The best way would be one of the alternatives that you have suggested, with passing in the url as params and then storing it in one of the WMSProperties containers.

If the params are passed on during the connection call then you can access the params in the onConnect method and store them in the client properties. PARAM1 will be your first param.

I don’t think there is a way to pass extra parameters when creating or publishing a stream so you would have to use a custom call handler on Wowza to set the url after the stream is created or published.

You could then store it in the stream properties and you should be able to access it from the onWriteComplete method by using the following.

String callbackUrl = ""; // or a default url.
WMSProperties props = stream.getProperties();
callbackUrl = props.getPropertyStr("callbackUrl", callbackUrl);
if(!callbackUrl.equals(""))
{
	// make http request here on a separate thread.
}

If you store it in client properties then you just need to adjust a bit to access the client properties container.

String callbackUrl = "";
IClient client = stream.getClient();
if(client != null)
{
	 WMSProperties props = client.getProperties();
	 callbackUrl = props.getPropertyStr("callbackUrl", callbackUrl);
}
if(!callbackUrl.equals(""))
{
	// make http request here on a separate thread.
}

In the above snippets, I mention to make the http request on a separate thread. This is important as the recorder thread that called the onWriteComplete method will be waiting for the method to return so it can continue. If the http call blocks fro some reason, it could lock up the thread until the http request times out. If there are chances that there may be multiple calls happening at the same time then you should probably create a thread pool that handles them so you don’t end up overwhelming either the Wowza server or the http server.

On the security side, HTTPUtils.HTTPRequestToByteArray is just a basic wrapper around URLConnection. It doesn’t provide any options handling authentication. You would need to implement your own URLConnection code.

Roger.

Thanks Roger that’s great.