/* * TeleStax, Open Source Cloud Communications Copyright 2012. * and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.mobicents.protocols.ss7.oam.common.sctp; import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Map; import javolution.util.FastList; import javolution.util.FastMap; import org.mobicents.protocols.api.Association; import org.mobicents.protocols.api.CongestionListener; import org.mobicents.protocols.api.IpChannelType; import org.mobicents.protocols.api.Management; import org.mobicents.protocols.api.ManagementEventListener; import org.mobicents.protocols.api.Server; import org.mobicents.protocols.api.ServerListener; import org.mobicents.protocols.ss7.oam.common.alarm.AlarmListener; import org.mobicents.protocols.ss7.oam.common.alarm.AlarmListenerCollection; import org.mobicents.protocols.ss7.oam.common.alarm.AlarmMediator; import org.mobicents.protocols.ss7.oam.common.alarm.AlarmMessage; import org.mobicents.protocols.ss7.oam.common.alarm.AlarmMessageImpl; import org.mobicents.protocols.ss7.oam.common.alarm.AlarmSeverity; import org.mobicents.protocols.ss7.oam.common.alarm.CurrentAlarmList; import org.mobicents.protocols.ss7.oam.common.alarm.CurrentAlarmListImpl; import org.mobicents.protocols.ss7.oam.common.jmx.MBeanHost; import org.mobicents.protocols.ss7.oam.common.jmxss7.Ss7Layer; /** * * @author sergey vetyutnev * @author amit bhayani * */ public class SctpManagementJmx implements SctpManagementJmxMBean, ManagementEventListener, AlarmMediator, CongestionListener { private final MBeanHost ss7Management; private final Management wrappedSctpManagement; private FastList<Server> lstServers = new FastList<Server>(); private FastMap<String, Association> lstAssociations = new FastMap<String, Association>(); private AlarmListenerCollection alc = new AlarmListenerCollection(); public SctpManagementJmx(MBeanHost ss7Management, Management wrappedSctpManagement) { super(); this.ss7Management = ss7Management; this.wrappedSctpManagement = wrappedSctpManagement; } /** * SctpManagementJmxMBean Methods */ @Override public Association addAssociation(String hostAddress, int hostPort, String peerAddress, int peerPort, String assocName) throws Exception { this.wrappedSctpManagement.addAssociation(hostAddress, hostPort, peerAddress, peerPort, assocName); return null; } @Override public Association addAssociation(String hostAddress, int hostPort, String peerAddress, int peerPort, String assocName, IpChannelType ipChannelType, String[] extraHostAddresses) throws Exception { this.wrappedSctpManagement.addAssociation(hostAddress, hostPort, peerAddress, peerPort, assocName, ipChannelType, extraHostAddresses); return null; } @Override public Association addSctpAssociation(String hostAddress, int hostPort, String peerAddress, int peerPort, String assocName, String ipChannelType, String extraHostAddresses) throws Exception { this.wrappedSctpManagement.addAssociation(hostAddress, hostPort, peerAddress, peerPort, assocName, IpChannelType.valueOf(ipChannelType.toUpperCase()), (extraHostAddresses != null && !extraHostAddresses.isEmpty()) ? extraHostAddresses.split(",") : null); return null; } @Override public void addManagementEventListener(ManagementEventListener listener) { // throw new OperationNotSupportedException(); // TODO ? } @Override public Server addServer(String serverName, String hostAddress, int port) throws Exception { this.wrappedSctpManagement.addServer(serverName, hostAddress, port); return null; } @Override public Server addServer(String serverName, String hostAddress, int port, IpChannelType ipChannelType, String[] extraHostAddresses) throws Exception { this.wrappedSctpManagement.addServer(serverName, hostAddress, port, ipChannelType, extraHostAddresses); return null; } @Override public Server addServer(String serverName, String hostAddress, int port, IpChannelType ipChannelType, boolean acceptAnonymousConnections, int maxConcurrentConnectionsCount, String[] extraHostAddresses) throws Exception { this.wrappedSctpManagement.addServer(serverName, hostAddress, port, ipChannelType, acceptAnonymousConnections, maxConcurrentConnectionsCount, extraHostAddresses); return null; } // @Override // public Server addSctpServer(String serverName, String hostAddress, int port, IpChannelType ipChannelType, // boolean acceptAnonymousConnections, int maxConcurrentConnectionsCount, String extraHostAddresses) throws Exception { // this.wrappedSctpManagement.addServer(serverName, hostAddress, port, ipChannelType, acceptAnonymousConnections, // maxConcurrentConnectionsCount, // (extraHostAddresses != null && !extraHostAddresses.isEmpty()) ? extraHostAddresses.split(",") : null); // return null; // } @Override public Server addSctpServer(String serverName, String hostAddress, int port, String ipChannelType, boolean acceptAnonymousConnections, int maxConcurrentConnectionsCount, String extraHostAddresses) throws Exception { this.wrappedSctpManagement.addServer(serverName, hostAddress, port, IpChannelType.valueOf(ipChannelType.toUpperCase()), acceptAnonymousConnections, maxConcurrentConnectionsCount, (extraHostAddresses != null && !extraHostAddresses.isEmpty()) ? extraHostAddresses.split(",") : null); return null; } @Override public Association addServerAssociation(String peerAddress, int peerPort, String serverName, String assocName) throws Exception { this.wrappedSctpManagement.addServerAssociation(peerAddress, peerPort, serverName, assocName); return null; } @Override public Association addServerAssociation(String peerAddress, int peerPort, String serverName, String assocName, IpChannelType ipChannelType) throws Exception { this.wrappedSctpManagement.addServerAssociation(peerAddress, peerPort, serverName, assocName, ipChannelType); return null; } @Override public Association addSctpServerAssociation(String peerAddress, int peerPort, String serverName, String assocName, String ipChannelType) throws Exception { this.wrappedSctpManagement.addServerAssociation(peerAddress, peerPort, serverName, assocName, IpChannelType.valueOf(ipChannelType.toUpperCase())); return null; } @Override public Association getAssociation(String assocName) throws Exception { for (FastMap.Entry<String, Association> n = this.lstAssociations.head(), end = this.lstAssociations.tail(); (n = n .getNext()) != end;) { String key = n.getKey(); if (key.equals(assocName)) { return n.getValue(); } } return null; } @Override public Map<String, Association> getAssociations() { Map<String, Association> lstAssociationsTmp = new HashMap<String, Association>(); lstAssociationsTmp.putAll(this.lstAssociations); return lstAssociationsTmp; } @Override public int getConnectDelay() { return this.wrappedSctpManagement.getConnectDelay(); } @Override public String getName() { return this.wrappedSctpManagement.getName(); } @Override public String getPersistDir() { return this.wrappedSctpManagement.getPersistDir(); } @Override public ServerListener getServerListener() { // TODO Auto-generated method stub return null; } @Override public List<Server> getServers() { return this.lstServers.unmodifiable(); } @Override public int getWorkerThreads() { return this.wrappedSctpManagement.getWorkerThreads(); } @Override public int getBufferSize() { return this.wrappedSctpManagement.getBufferSize(); } @Override public boolean isSingleThread() { return this.wrappedSctpManagement.isSingleThread(); } @Override public boolean isStarted() { return this.wrappedSctpManagement.isStarted(); } @Override public void removeAllResourses() throws Exception { this.wrappedSctpManagement.removeAllResourses(); } @Override public void removeAssociation(String assocName) throws Exception { this.wrappedSctpManagement.removeAssociation(assocName); } @Override public void removeManagementEventListener(ManagementEventListener arg0) { // TODO Auto-generated method stub } @Override public void removeServer(String serverName) throws Exception { this.wrappedSctpManagement.removeServer(serverName); } @Override public void setConnectDelay(int connectDelay) throws Exception { this.wrappedSctpManagement.setConnectDelay(connectDelay); } @Override public void setPersistDir(String persistDir) { this.wrappedSctpManagement.setPersistDir(persistDir); } @Override public double getCongControl_BackToNormalDelayThreshold_1() { return this.wrappedSctpManagement.getCongControl_BackToNormalDelayThreshold_1(); } @Override public double getCongControl_BackToNormalDelayThreshold_2() { return this.wrappedSctpManagement.getCongControl_BackToNormalDelayThreshold_2(); } @Override public double getCongControl_BackToNormalDelayThreshold_3() { return this.wrappedSctpManagement.getCongControl_BackToNormalDelayThreshold_3(); } @Override public double getCongControl_DelayThreshold_1() { return this.wrappedSctpManagement.getCongControl_DelayThreshold_1(); } @Override public double getCongControl_DelayThreshold_2() { return this.wrappedSctpManagement.getCongControl_DelayThreshold_2(); } @Override public double getCongControl_DelayThreshold_3() { return this.wrappedSctpManagement.getCongControl_DelayThreshold_3(); } @Override public void setCongControl_BackToNormalDelayThreshold_1(double val) throws Exception { this.wrappedSctpManagement.setCongControl_BackToNormalDelayThreshold_1(val); } @Override public void setCongControl_BackToNormalDelayThreshold_2(double val) throws Exception { this.wrappedSctpManagement.setCongControl_BackToNormalDelayThreshold_2(val); } @Override public void setCongControl_BackToNormalDelayThreshold_3(double val) throws Exception { this.wrappedSctpManagement.setCongControl_BackToNormalDelayThreshold_3(val); } @Override public void setCongControl_DelayThreshold_1(double val) throws Exception { this.wrappedSctpManagement.setCongControl_DelayThreshold_1(val); } @Override public void setCongControl_DelayThreshold_2(double val) throws Exception { this.wrappedSctpManagement.setCongControl_DelayThreshold_2(val); } @Override public void setCongControl_DelayThreshold_3(double val) throws Exception { this.wrappedSctpManagement.setCongControl_DelayThreshold_3(val); } @Override public void setServerListener(ServerListener arg0) { // TODO Auto-generated method stub } @Override public void setSingleThread(boolean singleThread) throws Exception { this.wrappedSctpManagement.setSingleThread(singleThread); } @Override public void setWorkerThreads(int workerThreads) throws Exception { this.wrappedSctpManagement.setWorkerThreads(workerThreads); } @Override public void setBufferSize(int bufferSize) throws Exception { this.wrappedSctpManagement.setBufferSize(bufferSize); } @Override public Boolean getOptionSctpDisableFragments() { return this.wrappedSctpManagement.getOptionSctpDisableFragments(); } @Override public Integer getOptionSctpFragmentInterleave() { return this.wrappedSctpManagement.getOptionSctpFragmentInterleave(); } @Override public Boolean getOptionSctpNodelay() { return this.wrappedSctpManagement.getOptionSctpNodelay(); } @Override public Integer getOptionSoLinger() { return this.wrappedSctpManagement.getOptionSoLinger(); } @Override public Integer getOptionSoRcvbuf() { return this.wrappedSctpManagement.getOptionSoRcvbuf(); } @Override public Integer getOptionSoSndbuf() { return this.wrappedSctpManagement.getOptionSoSndbuf(); } @Override public void setOptionSctpDisableFragments(Boolean val) { this.wrappedSctpManagement.setOptionSctpDisableFragments(val); } @Override public void setOptionSctpFragmentInterleave(Integer val) { this.wrappedSctpManagement.setOptionSctpFragmentInterleave(val); } @Override public void setOptionSctpNodelay(Boolean val) { this.wrappedSctpManagement.setOptionSctpNodelay(val); } @Override public void setOptionSoLinger(Integer val) { this.wrappedSctpManagement.setOptionSoLinger(val); } @Override public void setOptionSoRcvbuf(Integer val) { this.wrappedSctpManagement.setOptionSoRcvbuf(val); } @Override public void setOptionSoSndbuf(Integer val) { this.wrappedSctpManagement.setOptionSoSndbuf(val); } @Override public Integer getOptionSctpInitMaxstreams_MaxInStreams() { return this.wrappedSctpManagement.getOptionSctpInitMaxstreams_MaxInStreams(); } @Override public Integer getOptionSctpInitMaxstreams_MaxOutStreams() { return this.wrappedSctpManagement.getOptionSctpInitMaxstreams_MaxOutStreams(); } @Override public void setOptionSctpInitMaxstreams_MaxInStreams(Integer val) { this.wrappedSctpManagement.setOptionSctpInitMaxstreams_MaxInStreams(val); } @Override public void setOptionSctpInitMaxstreams_MaxOutStreams(Integer val) { this.wrappedSctpManagement.setOptionSctpInitMaxstreams_MaxOutStreams(val); } @Override public void start() throws Exception { synchronized (this) { lstServers.clear(); lstAssociations.clear(); this.ss7Management.registerMBean(Ss7Layer.SCTP, SctpManagementType.MANAGEMENT, this.getName(), this); this.wrappedSctpManagement.addManagementEventListener(this); this.wrappedSctpManagement.addCongestionListener(this); List<Server> lstSrv = wrappedSctpManagement.getServers(); for (Server srv : lstSrv) { this.addServerToManagement(srv); } Map<String, Association> lstAss = wrappedSctpManagement.getAssociations(); for (String s : lstAss.keySet()) { Association asso = lstAss.get(s); this.addAssociationToManagement(asso); } } } @Override public void startAssociation(String assocName) throws Exception { this.wrappedSctpManagement.startAssociation(assocName); } @Override public void startServer(String serverName) throws Exception { this.wrappedSctpManagement.startServer(serverName); } @Override public void stop() throws Exception { this.removeAllResourcesFromManagement(); } @Override public void stopAssociation(String assocName) throws Exception { this.wrappedSctpManagement.stopAssociation(assocName); } @Override public void stopServer(String serverName) throws Exception { this.wrappedSctpManagement.stopServer(serverName); } /** * ManagementEventListener methods */ @Override public void onAssociationAdded(Association asso) { this.addAssociationToManagement(asso); } @Override public void onAssociationDown(Association asso) { if (asso.isStarted()) { AlarmMessage alm = this.generateAssociationAlarm(asso, false, false, "onAssociationDown"); this.alc.onAlarm(alm); } } @Override public void onAssociationRemoved(Association asso) { removeAssociationFromManagement(asso); } @Override public void onAssociationStarted(Association ass) { if (!ass.isConnected()) { AlarmMessage alm = this.generateAssociationAlarm(ass, false, false, "onAssociationStarted"); this.alc.onAlarm(alm); } } @Override public void onAssociationStopped(Association ass) { if (!ass.isConnected()) { AlarmMessage alm = this.generateAssociationAlarm(ass, true, false, "onAssociationStopped"); this.alc.onAlarm(alm); } } @Override public void onAssociationUp(Association ass) { if (ass.isStarted()) { AlarmMessage alm = this.generateAssociationAlarm(ass, true, false, "onAssociationUp"); this.alc.onAlarm(alm); } } @Override public void onRemoveAllResources() { this.removeAllResourcesFromManagement(); } @Override public void onServerAdded(Server srv) { this.addServerToManagement(srv); } @Override public void onServerRemoved(Server srv) { this.removeServerFromManagement(srv); } @Override public void onServiceStarted() { // TODO Auto-generated method stub } @Override public void onServiceStopped() { // TODO Auto-generated method stub } /** * AlarmMediator methods */ @Override public String getAlarmProviderObjectPath() { return this.alc.getAlarmProviderObjectPath(); } @Override public CurrentAlarmList getCurrentAlarmList() { CurrentAlarmListImpl al = new CurrentAlarmListImpl(); if (wrappedSctpManagement.isStarted()) { Map<String, Association> lstAss = wrappedSctpManagement.getAssociations(); for (Association ass : lstAss.values()) { if (ass.isStarted()) { if (!ass.isConnected()) { AlarmMessage alm = this.generateAssociationAlarm(ass, false, true, ""); this.alc.prepareAlarm(alm); al.addAlarm(alm); } int congLevel = ass.getCongestionLevel(); if (congLevel > 0) { AlarmMessage alm = this.generateCongestionAlarm(ass, congLevel, false, true, ""); this.alc.prepareAlarm(alm); al.addAlarm(alm); } } } } return al; } @Override public void registerAlarmListener(AlarmListener al) { this.alc.registerAlarmListener(al); } @Override public void setAlarmProviderObjectPath(String value) { this.alc.setAlarmProviderObjectPath(value); } @Override public void unregisterAlarmListener(AlarmListener al) { this.alc.unregisterAlarmListener(al); } /** * methods - private */ private void addAssociationToManagement(Association asso) { synchronized (this) { Association assBean = new SctpAssociationJmx(this, asso); this.ss7Management.registerMBean(Ss7Layer.SCTP, SctpManagementType.ASSOCIATION, asso.getName(), assBean); lstAssociations.put(asso.getName(), assBean); } } private AlarmMessage generateAssociationAlarm(Association ass, boolean isCleared, boolean isCurrentAlarmList, String event) { AlarmMessageImpl alm = new AlarmMessageImpl(); alm.setIsCleared(isCleared); alm.setAlarmSeverity(AlarmSeverity.minor); alm.setAlarmSource("SS7_SCTP_" + this.getName()); alm.setObjectName("Association: " + ass.getName()); alm.setObjectPath("/Sctp:" + this.getName() + "/Associations/Association:" + ass.getName()); alm.setProblemName("SCTP association is down"); alm.setCause(event); alm.setTimeAlarm(Calendar.getInstance()); if (!isCurrentAlarmList) { if (isCleared) alm.setCurentTimeClear(); else alm.setCurentTimeAlarm(); } return alm; } private AlarmMessage generateCongestionAlarm(Association ass, int congLevel, boolean isCleared, boolean isCurrentAlarmList, String event) { if (congLevel < 1 || congLevel > 3) return null; AlarmMessageImpl alm = new AlarmMessageImpl(); alm.setIsCleared(isCleared); switch (congLevel) { case 1: alm.setAlarmSeverity(AlarmSeverity.minor); alm.setProblemName("SCTP association congestion level 1 (minor)"); break; case 2: alm.setAlarmSeverity(AlarmSeverity.major); alm.setProblemName("SCTP association congestion level 2 (major)"); break; case 3: alm.setAlarmSeverity(AlarmSeverity.critical); alm.setProblemName("SCTP association congestion level 3 (critical)"); break; } alm.setAlarmSource("SS7_SCTP_" + this.getName()); alm.setObjectName("Association: " + ass.getName()); alm.setObjectPath("/Sctp:" + this.getName() + "/Associations/Association:" + ass.getName()); alm.setCause(event); alm.setTimeAlarm(Calendar.getInstance()); if (!isCurrentAlarmList) { if (isCleared) alm.setCurentTimeClear(); else alm.setCurentTimeAlarm(); } return alm; } private void removeAssociationFromManagement(Association asso) { synchronized (this) { lstAssociations.remove(asso.getName()); this.ss7Management.unregisterMBean(Ss7Layer.SCTP, SctpManagementType.ASSOCIATION, asso.getName()); } } private void removeAllResourcesFromManagement() { // TODO Logic is bad here. wrappedSctpManagement will no more have list // of server and associations any more synchronized (this) { Map<String, Association> lstAss = wrappedSctpManagement.getAssociations(); for (String s : lstAss.keySet()) { Association asso = lstAss.get(s); this.removeAssociationFromManagement(asso); } List<Server> lstServ = wrappedSctpManagement.getServers(); for (Server srv : lstServ) { this.removeServerFromManagement(srv); } } } private void removeServerFromManagement(Server srv) { synchronized (this) { Server srvBeanX = null; for (Server srvBean : lstServers) { if (srvBean.getName().equals(srv.getName())) { srvBeanX = srvBean; break; } } lstServers.remove(srvBeanX); this.ss7Management.unregisterMBean(Ss7Layer.SCTP, SctpManagementType.SERVER, srv.getName()); } } private void addServerToManagement(Server srv) { synchronized (this) { SctpServerJmx srvBean = new SctpServerJmx(this, srv); this.ss7Management.registerMBean(Ss7Layer.SCTP, SctpManagementType.SERVER, srv.getName(), srvBean); lstServers.add(srvBean); } } @Override public void addCongestionListener(CongestionListener listener) { // TODO Auto-generated method stub } @Override public void removeCongestionListener(CongestionListener listener) { // TODO Auto-generated method stub } @Override public void onCongLevelChanged(Association association, int oldCongLevel, int newCongLevel) { if (association.isStarted()) { if (oldCongLevel > 0) { AlarmMessage alm = this.generateCongestionAlarm(association, oldCongLevel, true, false, "onCongLevelChanged"); this.alc.onAlarm(alm); } if (newCongLevel > 0) { AlarmMessage alm = this.generateCongestionAlarm(association, newCongLevel, false, false, "onCongLevelChanged"); this.alc.onAlarm(alm); } } } }