package com.myselia.stem.communication; import java.io.IOException; import java.net.DatagramSocket; import java.net.SocketException; import java.util.ArrayList; import java.util.Iterator; import com.google.gson.Gson; import com.myselia.javacommon.communication.units.Transmission; import com.myselia.javacommon.communication.units.TransmissionBuilder; import com.myselia.javacommon.constants.opcode.ActionType; import com.myselia.javacommon.constants.opcode.ComponentType; import com.myselia.javacommon.constants.opcode.OpcodeBroker; import com.myselia.javacommon.constants.opcode.operations.StemOperation; import com.myselia.javacommon.topology.ComponentCertificate; import com.myselia.stem.communication.seekers.Seek; public class BroadcastTorch { private int BROADCAST_SLEEP = 1500; private volatile ArrayList<Seek> seekInterfaces; private byte[] seekProbeText; /* THIS IS IN JSON */ private static DatagramSocket discoverSocket; private static Gson jsonInterpreter = new Gson(); public ComponentType type; public BroadcastTorch( ComponentType type, ArrayList<Seek> seekers) { this.seekInterfaces = seekers; this.type = type; try { if (discoverSocket == null) discoverSocket = new DatagramSocket(CommunicationDock.Stem_Broadcast_Port); } catch (SocketException e) { System.err.println("Cant create a broadcast socket on port: " + CommunicationDock.Stem_Broadcast_Port); e.printStackTrace(); } } /* * ##############################| |############################## * ##############################| PUBLIC |############################## * ##############################| |############################## */ /** * Called at every tick of the BroadCaster. Discovers components using the seek implementations * located within the seekInterfaces list. * @throws InterruptedException * @throws IOException */ public void seek() throws InterruptedException, IOException { Iterator<Seek> iterator = seekInterfaces.iterator(); while (iterator.hasNext()) { Seek seeker = iterator.next(); //System.out.println(seeker.printStatus(type.name(), new String(seekProbeText))); seeker.discoverComponents(seekProbeText); } Thread.sleep(BROADCAST_SLEEP); //FOR TESTING, PREVENTS CONSOLE SPAM //Thread.yield(); //MUCH BETTER WHEN DEPLOYED! } /** * Called to setup the broadcast torch JUST before the actual broadcasting begins */ public synchronized void primeBroadcaster() { Iterator<Seek> iterator = seekInterfaces.iterator(); while (iterator.hasNext()) { Seek seeker = iterator.next(); if (!seeker.hasSocket()) seeker.setSocket(BroadcastTorch.discoverSocket); } seekProbeText = buildInfoPacket(); } /* * ##############################| |############################## * ##############################| PRIVATE |############################## * ##############################| |############################## */ /** * Used to build the JSON that will be sent in the UDP seek packets that components * will interpret internally. * @return A packet to be sent by the seeker accepting a particular type of component connection */ private byte[] buildInfoPacket() { String seekPacketString = null; switch (type) { case DAEMON: seekPacketString = seekPacket(ComponentType.DAEMON); break; case LENS: seekPacketString = seekPacket(ComponentType.LENS); break; case SANDBOXMASTER: seekPacketString = seekPacket(ComponentType.SANDBOXMASTER); break; case DATABASE: seekPacketString = seekPacket(ComponentType.DATABASE); break; case SANDBOXSLAVE: //Does not accept connections of this type break; case STEM: //Does not accept connections of this type....YET break; default: break; } return seekPacketString.getBytes(); } /* * TODO, ABSTRACT THIS */ private String seekPacket(ComponentType type) { ComponentCertificate stemCert = CommunicationDock.getStemCertificate(); TransmissionBuilder tb = new TransmissionBuilder(); String from = OpcodeBroker.make(ComponentType.STEM, stemCert.getUUID(), ActionType.SETUP, StemOperation.BROADCAST); String to = OpcodeBroker.make(type, null, ActionType.SETUP, StemOperation.BROADCAST); tb.newTransmission(from, to); tb.addAtom("stemCertificate", "componentCertificate", jsonInterpreter.toJson(stemCert)); tb.addAtom("port", "int", Integer.toString(CommunicationDock.Stem_Communication_Port)); tb.addAtom("type", "String", type.name()); Transmission t = tb.getTransmission(); return jsonInterpreter.toJson(t); } }