/*
* Copyright 2013-2014 High-Level Technologies
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.zodiark.service.wowza;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.atmosphere.cpr.AtmosphereResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zodiark.protocol.Envelope;
import org.zodiark.protocol.Message;
import org.zodiark.protocol.Paths;
import org.zodiark.server.Context;
import org.zodiark.server.EventBus;
import org.zodiark.server.Reply;
import javax.inject.Inject;
import org.zodiark.server.ReplyException;
import org.zodiark.server.annotation.On;
import org.zodiark.service.EndpointAdapter;
import org.zodiark.service.publisher.PublisherEndpoint;
import org.zodiark.service.publisher.PublisherResults;
import org.zodiark.service.session.StreamingSession;
import java.io.IOException;
import static org.zodiark.protocol.Paths.ACTION_START;
import static org.zodiark.protocol.Paths.PUBLISHER_ABOUT_READY;
import static org.zodiark.protocol.Paths.RETRIEVE_PUBLISHER;
import static org.zodiark.protocol.Paths.WOWZA_CONNECT;
import static org.zodiark.protocol.Paths.WOWZA_DEOBFUSCATE;
import static org.zodiark.protocol.Paths.WOWZA_DEOBFUSCATE_OK;
import static org.zodiark.protocol.Paths.WOWZA_OBFUSCATE;
import static org.zodiark.protocol.Paths.WOWZA_OBFUSCATE_OK;
/**
* A Service responsible for reacting to Wowza's messages and I/O Events.
*/
@On(Paths.SERVICE_WOWZA)
public class WowzaServiceImpl implements WowzaService {
private final Logger logger = LoggerFactory.getLogger(WowzaServiceImpl.class);
@Inject
public EventBus evenBus;
@Inject
public WowzaEndpointManager wowzaManager;
@Inject
public Context context;
@Inject
public ObjectMapper mapper;
@Override
public void reactTo(Envelope e, AtmosphereResource r, Reply reply) {
String uuid = e.getUuid();
switch (e.getMessage().getPath()) {
case WOWZA_OBFUSCATE_OK:
logger.debug("Obfuscation executed");
try {
final WowzaMessage w = mapper.readValue(e.getMessage().getData(), WowzaMessage.class);
evenBus.message(RETRIEVE_PUBLISHER, w.getPublisherUUID(), new Reply<PublisherEndpoint, String>() {
@Override
public void ok(PublisherEndpoint p) {
try {
AtmosphereResource r = p.resource();
Message m = new Message();
m.setPath(ACTION_START);
m.setData(mapper.writeValueAsString(new PublisherResults("OK", w.getPublisherUUID())));
Envelope newResponse = Envelope.newPublisherRequest(p.uuid(), m);
r.write(mapper.writeValueAsString(newResponse));
} catch (JsonProcessingException e) {
logger.debug("Unable to write {}", e);
}
}
@Override
public void fail(ReplyException replyException) {
logger.error("No Publisher found", w.getPublisherUUID());
}
});
} catch (IOException e1) {
logger.error("{}", e1);
}
break;
case WOWZA_DEOBFUSCATE_OK:
try {
final WowzaMessage w = mapper.readValue(e.getMessage().getData(), WowzaMessage.class);
evenBus.message(PUBLISHER_ABOUT_READY, w.getPublisherUUID());
} catch (IOException e1) {
logger.error("{}", e1);
}
break;
case WOWZA_CONNECT:
WowzaEndpoint endpoint = wowzaManager.lookup(uuid);
if (endpoint == null) {
connected(e, r);
}
}
}
@Override
public void reactTo(String path, Object message, Reply reply) {
switch (path) {
case WOWZA_OBFUSCATE:
StreamingSession session = StreamingSession.class.cast(message);
WowzaEndpoint w = wowzaManager.lookup(session.publisher().wowzaServerUUID());
if (w != null) {
w.obfuscate(session, reply);
} else {
reply.fail(ReplyException.DEFAULT);
}
break;
case WOWZA_DEOBFUSCATE:
session = StreamingSession.class.cast(message);
w = wowzaManager.lookup(session.publisher().wowzaServerUUID());
if (w != null) {
w.deobfuscate(session, reply);
} else {
reply.fail(ReplyException.DEFAULT);
}
break;
case WOWZA_CONNECT:
if (EndpointAdapter.class.isAssignableFrom(message.getClass())) {
EndpointAdapter p = EndpointAdapter.class.cast(message);
w = wowzaManager.lookup(p.wowzaServerUUID());
if (w != null) {
w.isEndpointConnected(p, reply);
} else {
reply.fail(ReplyException.DEFAULT);
}
}
break;
default:
logger.error("Unhandled event {}", path);
}
}
/**
* {@inheritDoc}
*/
@Override
public void connected(Envelope e, AtmosphereResource r) {
String uuid = e.getUuid();
// Message contains the geo-localisation of the client.
Message m = e.getMessage();
wowzaManager.bind(context.newInstance(WowzaEndpoint.class).uuid(uuid).message(m).resource(r));
Message responseMessage = new Message();
responseMessage.setPath(WOWZA_CONNECT);
try {
responseMessage.setData(mapper.writeValueAsString(new WowzaResults("OK")));
} catch (JsonProcessingException e1) {
;
}
response(e, r, responseMessage);
}
/**
* {@inheritDoc}
*/
@Override
public void response(Envelope e, AtmosphereResource r, Message m) {
Envelope newResponse = Envelope.newServerReply(e, m);
try {
r.write(mapper.writeValueAsString(newResponse));
} catch (JsonProcessingException e1) {
logger.debug("Unable to write {}", e);
}
}
}