Java tutorial
/* * Copyright 2015 (C) Manuel Domnguez Dorado - ingeniero@ManoloDominguez.com. * * 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 simMPLS.scenario; import simMPLS.protocols.TAbstractPDU; import simMPLS.protocols.TMPLSPDU; import simMPLS.protocols.TICMPPDU; import simMPLS.hardware.timer.TTimerEvent; import simMPLS.hardware.timer.ITimerEventListener; import simMPLS.hardware.ports.TFIFOPortSet; import simMPLS.hardware.ports.TPort; import simMPLS.hardware.ports.TPortSet; import simMPLS.utils.TLongIDGenerator; import java.awt.*; import java.util.logging.Level; import java.util.logging.Logger; import org.jfree.chart.*; import org.jfree.data.*; import simMPLS.utils.EIDGeneratorOverflow; /** * Esta clase implementa un nodo receptor de trfico. * @author <B>Manuel Domnguez Dorado</B><br><A * href="mailto:ingeniero@ManoloDominguez.com">ingeniero@ManoloDominguez.com</A><br><A href="http://www.ManoloDominguez.com" target="_blank">http://www.ManoloDominguez.com</A> * @version 1.0 */ public class TReceiverNode extends TNode implements ITimerEventListener, Runnable { /** * Crea una nueva instancia de TNodoReceptor * @param identificador Identificador unico para el nodo en la topologa. * @param d IP address of the node. * @param il Generador de identificadores para los eventos que tenga que genrar el nodo. * @param t Topologia dentro de la cual se encuentra el nodo. * @since 1.0 */ public TReceiverNode(int identificador, String d, TLongIDGenerator il, TTopology t) { super(identificador, d, il, t); this.setPorts(super.NUM_PUERTOS_RECEPTOR); this.ports.setUnlimitedBuffer(true); this.estadisticas = new TReceiverStats(); } /** * Este mtodo reinicia los atributos de la clase y los deja como recien creadops * por el constructor. * @since 1.0 */ public void reset() { this.ports.reset(); this.estadisticas.reset(); estadisticas.activateStats(this.isGeneratingStats()); } /** * Este mtodo devuelve el tipo del nodo. * @return TNode.RECEIVER, indicando que se trata de un nodo receptor. * @since 1.0 */ public int getNodeType() { return super.RECEIVER; } /** * Este mtodo permite obtener eventos enviados desde el reloj del simulador. * @param evt Evento enviado desde el reloj principal del simulador. * @since 1.0 */ public void receiveTimerEvent(TTimerEvent evt) { this.setStepDouration(evt.getStepDuration()); this.setTimeInstant(evt.getUpperLimit()); this.startOperation(); } /** * Este mtodo se llama automticamente cuando el hilo independiente del nodo se * pone en funcionamiento. En l se codifica toda la funcionalidad del nodo. * @since 1.0 */ @Override public void run() { // Acciones a llevar a cabo durante el tic. if (this.getPorts().isArtificiallyCongested()) { try { this.generateSimulationEvent(new TSENodeCongested(this, this.longIdentifierGenerator.getNextID(), this.getAvailableTime(), this.getPorts().getCongestionLevel())); } catch (Exception e) { e.printStackTrace(); } } recibirDatos(); estadisticas.consolidateData(this.getAvailableTime()); // Acciones a llevar a cabo durante el tic. } /** * This method will put the node to cengested mode * @since 2.0 */ @Override public void toCongest() { if (this.getPorts().isArtificiallyCongested()) { this.getPorts().setArtificiallyCongested(false); } else { this.getPorts().setArtificiallyCongested(true); } super.setSayCongested(true); } /** * Este mtodo lee mientras puede los paquetes que hay en el buffer de recepcin. * @since 1.0 */ public void recibirDatos() { TPort p = this.ports.getPort(0); TAbstractPDU paquete = null; if (p != null) { while (p.thereIsAPacketWaiting()) { paquete = p.getPacket(); this.contabilizarPaquete(paquete, true); if (paquete.getType() == TAbstractPDU.ICMP) { this.reply((TICMPPDU) paquete); } paquete = null; } } } /** * Este mtodo contabiliza en las estadsticas del nodo un paquete ledo. * @param paquete Paquete que se quiere contabilizar. * @param deEntrada TRUE, si el paquete entra en el nodo. FALSE si el paquete sale del nodo. * @since 1.0 */ public void contabilizarPaquete(TAbstractPDU paquete, boolean deEntrada) { if (deEntrada) { if (paquete.getSubtype() == TAbstractPDU.MPLS) { } else if (paquete.getSubtype() == TAbstractPDU.MPLS_GOS) { } else if (paquete.getSubtype() == TAbstractPDU.IPV4) { } else if (paquete.getSubtype() == TAbstractPDU.IPV4_GOS) { } } else { if (paquete.getSubtype() == TAbstractPDU.MPLS) { } else if (paquete.getSubtype() == TAbstractPDU.MPLS_GOS) { } else if (paquete.getSubtype() == TAbstractPDU.IPV4) { } else if (paquete.getSubtype() == TAbstractPDU.IPV4_GOS) { } } } /** * This method reply to the sender of an icmp request * @param packet Received ICMP packet * @since 2.0 */ public void reply(TICMPPDU packet) { try { TICMPPDU replyPacket = new TICMPPDU(this.longIdentifierGenerator.getNextID(), this.getIPAddress(), packet.getIPv4Header().getOriginIPAddress(), 0, 0); TPort pt = ports.getPort(0); if (pt != null) { if (!pt.isAvailable()) { this.generateSimulationEvent( new TSEPacketGenerated(this, this.longIdentifierGenerator.getNextID(), this.getAvailableTime(), replyPacket.getType(), replyPacket.getSize())); this.generateSimulationEvent(new TSEPacketSent(this, this.longIdentifierGenerator.getNextID(), this.getAvailableTime(), replyPacket.getType())); pt.putPacketOnLink(replyPacket, pt.getLink().getTargetNodeIDOfTrafficSentBy(this)); } else { discardPacket(replyPacket); } } } catch (EIDGeneratorOverflow ex) { Logger.getLogger(TReceiverNode.class.getName()).log(Level.SEVERE, null, ex); } } /** * Este mtoo permite acceder directamente a los ports del nodo. * @return El conjunto de ports del nodo. * @since 1.0 */ public TPortSet getPorts() { return this.ports; } /** * Este mtodo devuelve si el nodo tiene ports libres o no. * @return TRUE, si el nodo tiene ports libres. FALSE en caso contrario. * @since 1.0 */ public boolean hasAvailablePorts() { return this.ports.hasAvailablePorts(); } /** * Este mtodo devuelve el peso del nodo que debe ser tenido en cuenta por los * algoritmos de encaminamiento para el clculo de rutas. * @return En el caso de un nodo receptor, siempre es cero. * @since 1.0 */ public long getRoutingWeight() { return 0; } /** * Devuelve si el nodo est bien configurado o no. * @return TRUE, si el nodo esta bien configurado. FALSE en caso contrario. * @since 1.0 */ public boolean isWellConfigured() { return this.wellConfigured; } /** * Este mtodo comprueba la configuracin del nodo y devuelve un cdigo expresando * dicho estado. * @param t Topologa donde est el nodo. * @param recfg TRUE, si se est reconfigurando el nodo. FALSE si el nodo se est configurando * por primera vez. * @return CORRECTA, si el nodo est bien configurado. Un codigo de error en caso * contrario. * @since 1.0 */ public int validateConfig(TTopology t, boolean recfg) { this.setWellConfigured(false); if (this.getName().equals("")) return this.SIN_NOMBRE; if (this.getIPAddress().isEmpty() && recfg) return this.EMPTY_IP; boolean soloEspacios = true; for (int i = 0; i < this.getName().length(); i++) { if (this.getName().charAt(i) != ' ') soloEspacios = false; } if (soloEspacios) return this.SOLO_ESPACIOS; if (!recfg) { TNode tp = t.setFirstNodeNamed(this.getName()); if (tp != null) return this.NOMBRE_YA_EXISTE; } else { TNode tp = t.setFirstNodeNamed(this.getName()); if (tp != null) { if (this.topology.thereIsMoreThanANodeNamed(this.getName())) { return this.NOMBRE_YA_EXISTE; } } } this.setWellConfigured(true); estadisticas.activateStats(this.isGeneratingStats()); return this.CORRECTA; } /** * Este mtodo transforma el codigo de error de configuracin del nodo en un texto * entendible y explicativo. * @param e Codigo de error. * @return Texto explicativo del codigo de error. * @since 1.0 */ public String getErrorMessage(int e) { switch (e) { case SIN_NOMBRE: return (java.util.ResourceBundle.getBundle("simMPLS/lenguajes/lenguajes") .getString("TConfigReceptor.FALTA_NOMBRE")); case NOMBRE_YA_EXISTE: return (java.util.ResourceBundle.getBundle("simMPLS/lenguajes/lenguajes") .getString("TConfigReceptor.NOMBRE_REPETIDO")); case SOLO_ESPACIOS: return (java.util.ResourceBundle.getBundle("simMPLS/lenguajes/lenguajes") .getString("TNodoReceptor.NombreNoSoloEspacios")); case EMPTY_IP: return "IP Address of the node is not present"; } return (""); } /** * Este mtodo transforma el nodo en una representacin textual volcable a disco. * @return La representacin textual del nodo. * @since 1.0 */ @Override public String marshall() { String cadena = "#Receiver#"; cadena += this.getID(); cadena += "#"; cadena += this.getName().replace('#', ' '); cadena += "#"; cadena += this.getIPAddress(); cadena += "#"; cadena += this.getShowName(); cadena += "#"; cadena += this.isGeneratingStats(); cadena += "#"; cadena += this.obtenerPosicion().x; cadena += "#"; cadena += this.obtenerPosicion().y; cadena += "#"; return cadena; } /** * Este mtodo deserializa un nodo serializado pasado por parmetro, * reconstruyendolo en memoria en la instancia actual. * @param elemento Nodo receptor serializado. * @return TRUE, si se ha podido deserializar correctamente. FALSE en caso contrario. * @since 1.0 */ @Override public boolean unMarshall(String elemento) { String valores[] = elemento.split("#"); if (valores.length != 9) { return false; } this.setID(Integer.parseInt(valores[2])); this.setName(valores[3]); this.setIPAddress(valores[4]); this.setStatus(0); this.setShowName(Boolean.parseBoolean(valores[5])); this.setGenerateStats(Boolean.parseBoolean(valores[6])); int posX = Integer.parseInt(valores[7]); int posY = Integer.parseInt(valores[8]); this.setPosition(new Point(posX + 24, posY + 24)); return true; } @Override public boolean addTableEntry(String tableEntry) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public String saveTableEntry() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } /** * Este mtodo permite acceder directamente a las estadsticas del nodo. * @return Las estadsticas del nodo. * @since 1.0 */ public TStats getStats() { return this.estadisticas; } /** * Este mtodo permite establecer el nmero de ports que deseamos para el nodo. * @param num El nmero de ports del nodo. Como mucho 8. * @since 1.0 */ public synchronized void setPorts(int num) { ports = new TFIFOPortSet(num, this); } /** * Este mtodo permite descartar nu paquete en el nodo y reflejar este descarte en * las estadisticas. * @param paquete paquete que deseamos descartar. * @since 1.0 */ public void discardPacket(TAbstractPDU paquete) { // Un receptor no descarta paquetes, porque tiene un buffer // ilimitado y no analiza el trfico. Lo recibe y ya est. paquete = null; } /** * Este mtodo no hace nada en un Receptor. En un nodo activo permitir * solicitar a un nodo activo la retransmisin de un paquete. * @param paquete Paquete cuya retransmisin se est solicitando. * @param pSalida Puerto por el que se enviar la solicitud. * @since 1.0 */ public void runGoSPDUStoreAndRetransmitProtocol(TMPLSPDU paquete, int pSalida) { } /** * Esta constante identifica que la configuracin del nodo es correcta. * @since 1.0 */ public static final int CORRECTA = 0; /** * Esta constante identifica que el nodo no tiene nombre. * @since 1.0 */ public static final int SIN_NOMBRE = 1; /** * Esta constante identifica que el nombre del nodo ya existe con anterioridad. * @since 1.0 */ public static final int NOMBRE_YA_EXISTE = 2; /** * Esta constante identifica que el nombre del nodo est formado slo por espacios. * @since 1.0 */ public static final int SOLO_ESPACIOS = 3; /** * IP Address is empty * @since 1.0 */ public static final int EMPTY_IP = 4; private TReceiverStats estadisticas; }