package se.sics.gvod.bootstrap.msgs;
import io.netty.buffer.ByteBuf;
import java.util.List;
import java.util.Map;
import java.util.Set;
import se.sics.gvod.net.VodAddress;
import se.sics.gvod.common.VodDescriptor;
import se.sics.gvod.common.msgs.DirectMsgNetty;
import se.sics.gvod.common.msgs.MessageEncodingException;
import se.sics.gvod.net.Transport;
import se.sics.gvod.net.VodMsgFrameDecoder;
import se.sics.gvod.net.msgs.RewriteableMsg;
import se.sics.gvod.net.util.UserTypesEncoderFactory;
import se.sics.gvod.timer.TimeoutId;
/**
*
* @author jdowling
*/
public class BootstrapMsg {
public static final class GetPeersRequest extends DirectMsgNetty.Request {
private static final long serialVersionUID = 787143338863400423L;
private final int overlay;
private final int utility;
public GetPeersRequest(VodAddress source, VodAddress destination,
int overlay, int utility) {
super(source, destination);
this.overlay = overlay;
this.utility = utility;
}
public int getOverlay() {
return overlay;
}
public int getUtility() {
return utility;
}
@Override
public int getSize() {
return super.getHeaderSize()
+ 4 /* overlay */
+ 4 /* utility */;
}
@Override
public ByteBuf toByteArray() throws MessageEncodingException {
ByteBuf buf = createChannelBufferWithHeader();
buf.writeInt(overlay);
buf.writeInt(utility);
return buf;
}
@Override
public byte getOpcode() {
return VodMsgFrameDecoder.BOOTSTRAP_REQUEST;
}
@Override
public RewriteableMsg copy() {
GetPeersRequest gpr = new GetPeersRequest(vodSrc, vodDest, overlay, utility);
gpr.setTimeoutId(timeoutId);
return gpr;
}
}
public static final class GetPeersResponse extends DirectMsgNetty.Response {
private static final long serialVersionUID = -3661778191727187359L;
private final int overlayId;
private final List<VodDescriptor> peers;
public GetPeersResponse(VodAddress source,
VodAddress destination, TimeoutId timeoutId, int overlayId,
List<VodDescriptor> peers) {
super(source, destination, Transport.UDP, timeoutId);
this.overlayId = overlayId;
this.peers = peers;
}
public List<VodDescriptor> getPeers() {
return peers;
}
public int getOverlayId() {
return overlayId;
}
@Override
public int getSize() {
return super.getHeaderSize()
+ 4 /* overlayId */
+ UserTypesEncoderFactory.getListVodNodeDescriptorSize(peers);
}
@Override
public ByteBuf toByteArray() throws MessageEncodingException {
ByteBuf buffer = createChannelBufferWithHeader();
buffer.writeInt(overlayId);
UserTypesEncoderFactory.writeListVodNodeDescriptors(buffer, peers);
return buffer;
}
@Override
public byte getOpcode() {
return VodMsgFrameDecoder.BOOTSTRAP_RESPONSE;
}
@Override
public RewriteableMsg copy() {
return new GetPeersResponse(vodSrc, vodDest, timeoutId, overlayId, peers);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getVodSource()).append(" - ")
.append(getVodDestination()).append(" - ")
.append(overlayId).append(" - ")
.append(peers.size());
sb.append("( ");
for (VodDescriptor vd : peers) {
sb.append(vd).append(" , ");
}
sb.append(" )");
return sb.toString();
}
}
public static final class Heartbeat extends DirectMsgNetty.Oneway {
private static final long serialVersionUID = -6543349790434L;
private final boolean helper;
private final short mtu;
private final Set<Integer> seeders;
private final Map<Integer, Integer> downloaders;
public Heartbeat(VodAddress source, VodAddress destination,
boolean helper, short mtu,
Set<Integer> seeders, Map<Integer, Integer> downloaders) {
super(source, destination);
this.helper = helper;
this.seeders = seeders;
this.downloaders = downloaders;
this.mtu = mtu;
}
public boolean isHelper() {
return helper;
}
public short getMtu() {
return mtu;
}
public Set<Integer> getSeeders() {
return seeders;
}
public Map<Integer, Integer> getDownloaders() {
return downloaders;
}
@Override
public int getSize() {
return super.getHeaderSize()
+ 1 /* helper */
+ 2 /* mtu */
+ UserTypesEncoderFactory.getCollectionIntsLength(seeders)
+ UserTypesEncoderFactory.getMapIntIntsLength(downloaders)
;
}
@Override
public ByteBuf toByteArray() throws MessageEncodingException {
ByteBuf buf = createChannelBufferWithHeader();
UserTypesEncoderFactory.writeBoolean(buf, helper);
buf.writeShort(mtu);
UserTypesEncoderFactory.writeCollectionInts(buf, seeders);
UserTypesEncoderFactory.writeMapIntInts(buf, downloaders);
return buf;
}
@Override
public byte getOpcode() {
return VodMsgFrameDecoder.BOOTSTRAP_HEARTBEAT;
}
@Override
public RewriteableMsg copy() {
// neither seeders or downloaders will be modified, so this is safe.
Heartbeat hb = new Heartbeat(vodSrc, vodDest, helper, mtu, seeders, downloaders);
hb.setTimeoutId(timeoutId);
return hb;
}
}
public static final class AddOverlayReq extends DirectMsgNetty.Request {
private static final long serialVersionUID = -876591849790434L;
private final String overlayName;
private final int overlayId;
private final String description;
private final byte[] torrentData;
private final String imageUrl;
private final int part;
private final int numParts;
public AddOverlayReq(VodAddress source, VodAddress destination,
String overlayName, int overlayId, String description,
byte[] torrentData, String imageUrl, int part, int numParts) {
super(source, destination);
assert(overlayName != null);
this.overlayName = overlayName;
this.overlayId = overlayId;
if (description == null) {
this.description = "";
} else {
this.description = description;
}
this.torrentData = torrentData;
if (imageUrl == null) {
this.imageUrl = "";
} else {
this.imageUrl = imageUrl;
}
this.part = part;
this.numParts = numParts;
}
@Override
public int getSize() {
return super.getHeaderSize()
+ UserTypesEncoderFactory.getStringLength256(overlayName)
+ 4 /* overlayId */
+ UserTypesEncoderFactory.getStringLength65356(description)
+ 1000 /* guess of UserTypesEncoderFactory.getBytesLength65356(torrentData) */
+ UserTypesEncoderFactory.getStringLength256(imageUrl)
+ 1
+ 1;
}
public String getOverlayName() {
return overlayName;
}
public int getOverlayId() {
return overlayId;
}
public String getDescription() {
return description == null ? "" : description;
}
public byte[] getTorrentData() {
return torrentData;
}
public String getImageUrl() {
return imageUrl == null ? "" : imageUrl;
}
public int getPart() {
return part;
}
public int getNumParts() {
return numParts;
}
@Override
public ByteBuf toByteArray() throws MessageEncodingException {
ByteBuf buf = createChannelBufferWithHeader();
UserTypesEncoderFactory.writeStringLength256(buf, overlayName);
buf.writeInt(overlayId);
UserTypesEncoderFactory.writeStringLength256(buf, description);
UserTypesEncoderFactory.writeBytesLength65536(buf, torrentData);
UserTypesEncoderFactory.writeStringLength256(buf, imageUrl);
UserTypesEncoderFactory.writeUnsignedintAsOneByte(buf, part);
UserTypesEncoderFactory.writeUnsignedintAsOneByte(buf, numParts);
return buf;
}
@Override
public byte getOpcode() {
return VodMsgFrameDecoder.BOOTSTRAP_ADD_OVERLAY_REQUEST;
}
@Override
public RewriteableMsg copy() {
AddOverlayReq copy = new AddOverlayReq(vodSrc, vodDest, overlayName,
overlayId, description, torrentData, imageUrl, part, numParts);
copy.setTimeoutId(timeoutId);
return copy;
}
}
public static final class AddOverlayResp extends DirectMsgNetty.Response {
private static final long serialVersionUID = -333221149790434L;
private final int overlayId;
private final boolean success;
private final boolean finished;
public AddOverlayResp(VodAddress source, VodAddress destination,
int overlayId, boolean success, boolean finished, TimeoutId timeoutId) {
super(source, destination, timeoutId);
this.overlayId = overlayId;
this.success = success;
this.finished = finished;
}
@Override
public int getSize() {
return super.getHeaderSize()
+ 4 /* overlayId */
+ 1 /* success */
+ 1 /* finished*/
;
}
public boolean isSuccess() {
return success;
}
public int getOverlayId() {
return overlayId;
}
@Override
public ByteBuf toByteArray() throws MessageEncodingException {
ByteBuf buf = createChannelBufferWithHeader();
buf.writeInt(overlayId);
UserTypesEncoderFactory.writeBoolean(buf, success);
UserTypesEncoderFactory.writeBoolean(buf, finished);
return buf;
}
@Override
public byte getOpcode() {
return VodMsgFrameDecoder.BOOTSTRAP_ADD_OVERLAY_RESPONSE;
}
@Override
public RewriteableMsg copy() {
return new AddOverlayResp(vodSrc, vodDest, overlayId, success, finished, timeoutId);
}
}
public static final class HelperHeartbeat extends DirectMsgNetty.Oneway {
private static final long serialVersionUID = 433455863400423L;
private final boolean space;
public HelperHeartbeat(VodAddress source, VodAddress destination, boolean space) {
super(source, destination);
this.space = space;
}
@Override
public int getSize() {
return super.getHeaderSize()
+ 1 // space
;
}
@Override
public ByteBuf toByteArray() throws MessageEncodingException {
ByteBuf buf = createChannelBufferWithHeader();
UserTypesEncoderFactory.writeBoolean(buf, space);
return buf;
}
public boolean isSpace() {
return space;
}
@Override
public byte getOpcode() {
return VodMsgFrameDecoder.BOOTSTRAP_CLOUD_HELPER_HB;
}
@Override
public RewriteableMsg copy() {
HelperHeartbeat gpr = new HelperHeartbeat(vodSrc, vodDest, space);
return gpr;
}
}
public static final class HelperDownload extends DirectMsgNetty.Oneway {
private static final long serialVersionUID = -333221149790434L;
private final String url;
public HelperDownload(VodAddress source, VodAddress destination, String url) {
super(source, destination);
if (url == null) {
throw new NullPointerException("Url cannot be null for video to download");
}
this.url = url;
}
@Override
public int getSize() {
return super.getHeaderSize()
+ UserTypesEncoderFactory.getStringLength256(url)
;
}
public String getUrl() {
return url;
}
@Override
public ByteBuf toByteArray() throws MessageEncodingException {
ByteBuf buf = createChannelBufferWithHeader();
UserTypesEncoderFactory.writeStringLength256(buf, url);
return buf;
}
@Override
public byte getOpcode() {
return VodMsgFrameDecoder.BOOTSTRAP_CLOUD_HELPER_DOWNLOAD_REQUEST;
}
@Override
public RewriteableMsg copy() {
HelperDownload copy = new HelperDownload(vodSrc, vodDest, url);
copy.setTimeoutId(timeoutId);
return copy;
}
}
// public static final class HelperDownloadResponse extends DirectMsgNetty.Response {
//
// private static final long serialVersionUID = -74747474149790434L;
// final boolean success;
//
// public HelperDownloadResponse(VodAddress source, VodAddress destination,
// boolean success, TimeoutId timeoutId) {
// super(source, destination, timeoutId);
// this.success = success;
// }
//
// @Override
// public int getSize() {
// return super.getHeaderSize()
// + 1 /* success */
// ;
// }
//
// public boolean isSuccess() {
// return success;
// }
//
// @Override
// public ByteBuf toByteArray() throws MessageEncodingException {
// ByteBuf buf = createChannelBufferWithHeader();
// UserTypesEncoderFactory.writeBoolean(buf, success);
// return buf;
// }
//
// @Override
// public byte getOpcode() {
// return VodMsgFrameDecoder.BOOTSTRAP_CLOUD_HELPER_DOWNLOAD_RESPONSE;
// }
//
// @Override
// public RewriteableMsg copy() {
// return new HelperDownloadResponse(vodSrc, vodDest, success, timeoutId);
// }
// }
}