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.hardware.timer.ITimerEventListener; import simMPLS.utils.EIDGeneratorOverflow; import simMPLS.utils.TLongIDGenerator; import java.util.*; import org.jfree.chart.*; import org.jfree.data.*; /** * Esta clase implementa un enlace de la topologa que ser interno al dominio * MPLS. * @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 TInternalLink extends TLink implements ITimerEventListener, Runnable { /** * Crea una nueva instancia de TEnlaceInterno * @param identificador Identificador nico para este elemento en la topologa. * @param il Generador de identificadores para los eventos que genere este enlace externo. * @param t Topologia en la que se encuentra este enlace interno. * @since 1.0 */ public TInternalLink(int identificador, TLongIDGenerator il, TTopology t) { super(identificador, il, t); numeroDeLSPs = 0; numeroDeLSPsDeBackup = 0; paso = 0; } /** * Este mtodo devuelve el tipo el enlace. * @return TLink.INTERNAL, indicando que es un nodo interno. * @since 1.0 */ public int getLinkType() { return super.INTERNAL; } /** * Este mtodo recibe eventos de sincronizacin del reloj del simulador, que lo * sincroniza todo. * @param evt Evento de sincronizacin que el reloj del simulador enva a este enlace interno. * @since 1.0 */ public void receiveTimerEvent(simMPLS.hardware.timer.TTimerEvent evt) { this.setStepDouration(evt.getStepDuration()); this.setTimeInstant(evt.getUpperLimit()); paso = evt.getStepDuration(); this.startOperation(); } /** * Este mtodo establece si el enlace se puede considerar como caido o no. * @param ec TRUE, indica que queremos que el enlace caiga. FALSE indica que no lo queremos o * que queremos que se levante si est caido. * @since 1.0 */ public void ponerEnlaceCaido(boolean ec) { enlaceCaido = ec; if (ec) { try { this.numeroDeLSPs = 0; this.numeroDeLSPsDeBackup = 0; this.generateSimulationEvent( new TSELinkBroken(this, this.longIdentifierGenerator.getNextID(), this.getAvailableTime())); this.cerrojo.lock(); TAbstractPDU paquete = null; TLinkBufferEntry ebe = null; Iterator it = this.getBuffer().iterator(); while (it.hasNext()) { ebe = (TLinkBufferEntry) it.next(); paquete = ebe.obtenerPaquete(); if (paquete != null) { if (ebe.obtenerDestino() == 1) { this.generateSimulationEvent( new TSEPacketDiscarded(this.getEnd2(), this.longIdentifierGenerator.getNextID(), this.getAvailableTime(), paquete.getSubtype())); } else if (ebe.obtenerDestino() == 2) { this.generateSimulationEvent( new TSEPacketDiscarded(this.getEnd1(), this.longIdentifierGenerator.getNextID(), this.getAvailableTime(), paquete.getSubtype())); } } it.remove(); } this.cerrojo.unLock(); } catch (EIDGeneratorOverflow e) { e.printStackTrace(); } } else { try { this.generateSimulationEvent(new TSELinkRecovered(this, this.longIdentifierGenerator.getNextID(), this.getAvailableTime())); } catch (EIDGeneratorOverflow e) { e.printStackTrace(); } } } /** * Este mtodo se ejecuta cuando el hilo principal del enlace externo se ponne en * funcionamiento. Es el ncleo del enlace interno. * @since 1.0 */ public void run() { // Acciones a llevar a cabo durante el tic. this.actualizarTiemposDeEspera(); this.adelantarPaquetesEnTransito(); this.pasarPaquetesADestino(); // Acciones a llevar a cabo durante el tic. } /** * Este mtodo comprueba si sobre este enlace se ha establecido algn LSP. * @return TRUE, si se ha establecido algn LSP. FALSE en caso contrario. * @since 1.0 */ public boolean tieneLSPs() { if (numeroDeLSPs > 0) return true; return false; } /** * Este mtodo aade un LSP sobre este enlace. * @since 1.0 */ public void setLSPUp() { numeroDeLSPs++; try { this.generateSimulationEvent( new TSELSPEstablished(this, this.longIdentifierGenerator.getNextID(), this.getAvailableTime())); } catch (Exception e) { e.printStackTrace(); } } /** * Este mtodo quita un LSP establecido sobre este enlace. * @since 1.0 */ public void quitarLSP() { if (numeroDeLSPs > 0) { numeroDeLSPs--; try { this.generateSimulationEvent( new TSELSPRemoved(this, this.longIdentifierGenerator.getNextID(), this.getAvailableTime())); } catch (Exception e) { e.printStackTrace(); } } } /** * Este mtodo comprueba si sobre este enlace se ha establecido algn LSP de * respaldo. * @return TRUE, si se ha establecido algn LSP de respaldo. FALSE en caso contrario. * @since 1.0 */ public boolean tieneLSPsDeBackup() { if (numeroDeLSPsDeBackup > 0) return true; return false; } /** * Este mtodo aade un LSP de respaldo sobre este enlace. * @since 1.0 */ public void ponerLSPDeBackup() { numeroDeLSPsDeBackup++; } /** * Este mtodo quita un LSP de respaldo establecido sobre este enlace. * @since 1.0 */ public void setBackupLSPDown() { if (numeroDeLSPsDeBackup > 0) numeroDeLSPsDeBackup--; } /** * Este mtodo toma todos los paquetes que en ese momento se encuentren circulando * por el enlace interno y los avanza por el mismo hacia su destino. * @since 1.0 */ public void actualizarTiemposDeEspera() { cerrojo.lock(); Iterator it = getBuffer().iterator(); while (it.hasNext()) { TLinkBufferEntry ebe = (TLinkBufferEntry) it.next(); ebe.restarTiempoPaso(paso); long pctj = this.obtenerPorcentajeTransito(ebe.obtener100x100(), ebe.obtenerTiempoEspera()); if (ebe.obtenerDestino() == 1) pctj = 100 - pctj; try { if (ebe.obtenerPaquete().getType() == TAbstractPDU.TLDP) { this.generateSimulationEvent(new TSEPacketOnFly(this, this.longIdentifierGenerator.getNextID(), this.getAvailableTime(), TAbstractPDU.TLDP, pctj)); } else if (ebe.obtenerPaquete().getType() == TAbstractPDU.MPLS) { this.generateSimulationEvent(new TSEPacketOnFly(this, this.longIdentifierGenerator.getNextID(), this.getAvailableTime(), ebe.obtenerPaquete().getSubtype(), pctj)); } else if (ebe.obtenerPaquete().getType() == TAbstractPDU.GPSRP) { this.generateSimulationEvent(new TSEPacketOnFly(this, this.longIdentifierGenerator.getNextID(), this.getAvailableTime(), TAbstractPDU.GPSRP, pctj)); } else { this.generateSimulationEvent(new TSEPacketOnFly(this, this.longIdentifierGenerator.getNextID(), this.getAvailableTime(), ebe.obtenerPaquete().getSubtype(), pctj)); } } catch (EIDGeneratorOverflow e) { e.printStackTrace(); } } cerrojo.unLock(); } /** * Este mtodo toma todos los paquetes que se encuentren circulando por el enlace * interno y detecta todos aquellos que ya han llegado al destino. * @since 1.0 */ public void adelantarPaquetesEnTransito() { cerrojo.lock(); Iterator it = getBuffer().iterator(); while (it.hasNext()) { TLinkBufferEntry ebe = (TLinkBufferEntry) it.next(); if (ebe.obtenerTiempoEspera() <= 0) { this.cerrojoLlegados.lock(); bufferLlegadosADestino.add(ebe); this.cerrojoLlegados.unLock(); } } it = getBuffer().iterator(); while (it.hasNext()) { TLinkBufferEntry ebe = (TLinkBufferEntry) it.next(); if (ebe.obtenerTiempoEspera() <= 0) it.remove(); } cerrojo.unLock(); } /** * Este mtodo toma todos los paquetes que han llegado al destino y realiza la * insercion de los mismos en el puerto correspondiente de dicho destino. * @since 1.0 */ public void pasarPaquetesADestino() { this.cerrojoLlegados.lock(); Iterator it = bufferLlegadosADestino.iterator(); while (it.hasNext()) { TLinkBufferEntry ebe = (TLinkBufferEntry) it.next(); if (ebe.obtenerDestino() == TLink.END_NODE_1) { TNode nt = this.getEnd1(); nt.ponerPaquete(ebe.obtenerPaquete(), this.obtenerPuertoExtremo1()); } else { TNode nt = this.getEnd2(); nt.ponerPaquete(ebe.obtenerPaquete(), this.obtenerPuertoExtremo2()); } it.remove(); } this.cerrojoLlegados.unLock(); } /** * Este mtodo obtiene el peso del enlace interno que debe usar el algoritmo de * routing para calcular rutas. * @return El peso del enlace. * @since 1.0 */ public long obtenerPeso() { long peso = this.obtenerDelay(); return peso; } /** * Este mtodo devuelve si el enlace interno est bien configurado o no. * @return TRUE, si la configuracin actual del enlace es correcta. FALSE en caso * contrario. * @since 1.0 */ public boolean isWellConfigured() { return false; } /** * Este mtodo comprueba si el valor de todos los atributos configurables del * enlace interno es vlido o no. * @param t Topologa dentro de la cual se encuentra este enlace interno. * @return CORRECTA, si la configuracin es correcta. Un codigo de error en caso contrario. * @since 1.0 */ public int comprobar(TTopology t) { return 0; } /** * Este mtodo transforma en un mensaje legible el cdigo de error devuelto por el * mtodo <I>validateConfig(...)</I> * @param e El codigo de error que se quiere transformar. * @return El mensaje textual correspondiente a ese mensaje de error. * @since 1.0 */ public String getErrorMessage(int e) { return null; } /** * Este mtodo transforma el enlace interno en un representacin de texto que se * puede almacenar en disco sin problemas. * @return El equivalente en texto del enlace interno completo. * @since 1.0 */ @Override public String marshall() { String cadena = "#InternalLink#"; cadena += this.getID(); cadena += "#"; cadena += this.obtenerNombre().replace('#', ' '); cadena += "#"; cadena += this.obtenerMostrarNombre(); cadena += "#"; cadena += this.obtenerDelay(); cadena += "#"; cadena += this.getEnd1().getName(); cadena += "#"; cadena += this.obtenerPuertoExtremo1(); cadena += "#"; cadena += this.getEnd2().getName(); cadena += "#"; cadena += this.obtenerPuertoExtremo2(); cadena += "#"; return cadena; } /** * Este mtodo toma la representacin textual de un enlace interno completo y * configura el objeto con los valores que obtiene. * @param elemento Enlace interno en su representacin serializada. * @return TRUE, si se deserializa correctamente, FALSE en caso contrario. * @since 1.0 */ @Override public boolean unMarshall(String elemento) { TLinkConfig configEnlace = new TLinkConfig(); String valores[] = elemento.split("#"); if (valores.length != 10) { return false; } this.ponerIdentificador(Integer.parseInt(valores[2])); configEnlace.ponerNombre(valores[3]); configEnlace.ponerMostrarNombre(Boolean.parseBoolean(valores[4])); configEnlace.ponerDelay(Integer.parseInt(valores[5])); TNode ex1 = this.obtenerTopologia().setFirstNodeNamed(valores[6]); TNode ex2 = this.obtenerTopologia().setFirstNodeNamed(valores[8]); if (!((ex1 == null) || (ex2 == null))) { configEnlace.ponerNombreExtremo1(ex1.getName()); configEnlace.ponerNombreExtremo2(ex2.getName()); configEnlace.ponerPuertoExtremo1(Integer.parseInt(valores[7])); configEnlace.ponerPuertoExtremo2(Integer.parseInt(valores[9])); configEnlace.calcularTipo(this.topologia); } else { return false; } this.configurar(configEnlace, this.topologia, false); return true; } /** * Este mtodo reinicia los atributos de la clase, dejando la instancia como si se * acabase de crear por el constructor. * @since 1.0 */ public void reset() { this.cerrojo.lock(); Iterator it = this.getBuffer().iterator(); while (it.hasNext()) { it.next(); it.remove(); } this.cerrojo.unLock(); this.cerrojoLlegados.lock(); it = this.bufferLlegadosADestino.iterator(); while (it.hasNext()) { it.next(); it.remove(); } this.cerrojoLlegados.unLock(); numeroDeLSPs = 0; numeroDeLSPsDeBackup = 0; ponerEnlaceCaido(false); } public long obtenerPesoRABAN() { long peso = 0; long pesoD = this.obtenerDelay(); long pesoE1 = (long) ((double) (pesoD * 0.10)) * this.getEnd1().getRoutingWeight(); long pesoE2 = (long) ((double) (pesoD * 0.10)) * this.getEnd2().getRoutingWeight(); long pesoLSP = (long) ((double) (pesoD * 0.05)) * this.numeroDeLSPs; long pesoLSPB = (long) ((double) (pesoD * 0.05)) * this.numeroDeLSPsDeBackup; long pesoOnFly = (long) ((double) (pesoD * 0.10)) * this.getBuffer().size(); long subPeso = (long) (pesoE1 + pesoE2 + pesoLSP + pesoLSPB + pesoOnFly); peso = (long) ((pesoD * 0.5) + (subPeso * 0.5)); return peso; } private int numeroDeLSPs; private int numeroDeLSPsDeBackup; private long paso; }