/* * JBoss, Home of Professional Open Source * Copyright 2011, Red Hat, Inc. 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.slee.runtime.sbb; import javax.slee.ActivityContextInterface; import javax.slee.Address; import javax.slee.EventTypeID; import javax.slee.SLEEException; import javax.slee.SbbLocalObject; import javax.slee.ServiceID; import javax.slee.profile.ProfileID; import javax.slee.profile.UnrecognizedProfileNameException; import javax.slee.profile.UnrecognizedProfileTableNameException; import javax.slee.usage.UnrecognizedUsageParameterSetNameException; import org.apache.log4j.Logger; import org.mobicents.slee.container.SleeContainer; import org.mobicents.slee.container.activity.ActivityContext; import org.mobicents.slee.container.activity.ActivityContextHandle; import org.mobicents.slee.container.component.sbb.CMPFieldDescriptor; import org.mobicents.slee.container.component.sbb.GetProfileCMPMethodDescriptor; import org.mobicents.slee.container.event.EventContext; import org.mobicents.slee.container.event.EventContextHandle; import org.mobicents.slee.container.eventrouter.EventRoutingTransactionData; import org.mobicents.slee.container.management.ProfileManagement; import org.mobicents.slee.container.management.jmx.ServiceUsageMBeanImpl; import org.mobicents.slee.container.profile.ProfileLocalObject; import org.mobicents.slee.container.profile.ProfileTable; import org.mobicents.slee.container.sbb.SbbObjectState; import org.mobicents.slee.container.sbbentity.ChildRelation; import org.mobicents.slee.container.sbbentity.SbbEntity; import org.mobicents.slee.container.sbbentity.SbbEntityID; import org.mobicents.slee.container.transaction.SleeTransactionManager; import org.mobicents.slee.runtime.sbbentity.ProfileLocalObjectCmpValue; /** * The logic to implement sbb abstract methods. * * @author martins * */ public class SbbAbstractMethodHandler { private static final Logger logger = Logger.getLogger(SbbAbstractMethodHandler.class); private static final SleeContainer sleeContainer = SleeContainer.lookupFromJndi(); // CMP ACCESSORs private static final Boolean DEFAULT_CMP_VALUE_BOOLEAN = Boolean.FALSE; private static final Byte DEFAULT_CMP_VALUE_BYTE = Byte.valueOf((byte) 0); private static final Character DEFAULT_CMP_VALUE_CHAR = Character.valueOf((char) 0); private static final Double DEFAULT_CMP_VALUE_DOUBLE = Double.valueOf(0); private static final Float DEFAULT_CMP_VALUE_FLOAT = Float.valueOf(0); private static final Integer DEFAULT_CMP_VALUE_INTEGER = Integer.valueOf(0); private static final Long DEFAULT_CMP_VALUE_LONG = Long.valueOf(0); private static final Short DEFAULT_CMP_VALUE_SHORT = Short.valueOf((short)0); public static void setCMPFieldOfTypePrimitiveOrUnknown(SbbEntity sbbEntity, String cmpFieldName, char cmpFieldValue) { SbbAbstractMethodHandler.setCMPFieldOfTypePrimitiveOrUnknown(sbbEntity,cmpFieldName, Character.valueOf(cmpFieldValue)); } public static void setCMPFieldOfTypePrimitiveOrUnknown(SbbEntity sbbEntity, String cmpFieldName, byte cmpFieldValue) { SbbAbstractMethodHandler.setCMPFieldOfTypePrimitiveOrUnknown(sbbEntity,cmpFieldName, Byte.valueOf(cmpFieldValue)); } public static void setCMPFieldOfTypePrimitiveOrUnknown(SbbEntity sbbEntity, String cmpFieldName, short cmpFieldValue) { SbbAbstractMethodHandler.setCMPFieldOfTypePrimitiveOrUnknown(sbbEntity,cmpFieldName, Short.valueOf(cmpFieldValue)); } public static void setCMPFieldOfTypePrimitiveOrUnknown(SbbEntity sbbEntity, String cmpFieldName, int cmpFieldValue) { SbbAbstractMethodHandler.setCMPFieldOfTypePrimitiveOrUnknown(sbbEntity,cmpFieldName, Integer.valueOf(cmpFieldValue)); } public static void setCMPFieldOfTypePrimitiveOrUnknown(SbbEntity sbbEntity, String cmpFieldName, long cmpFieldValue) { SbbAbstractMethodHandler.setCMPFieldOfTypePrimitiveOrUnknown(sbbEntity,cmpFieldName, Long.valueOf(cmpFieldValue)); } public static void setCMPFieldOfTypePrimitiveOrUnknown(SbbEntity sbbEntity, String cmpFieldName, float cmpFieldValue) { SbbAbstractMethodHandler.setCMPFieldOfTypePrimitiveOrUnknown(sbbEntity,cmpFieldName, Float.valueOf(cmpFieldValue)); } public static void setCMPFieldOfTypePrimitiveOrUnknown(SbbEntity sbbEntity, String cmpFieldName, double cmpFieldValue) { SbbAbstractMethodHandler.setCMPFieldOfTypePrimitiveOrUnknown(sbbEntity,cmpFieldName, Double.valueOf(cmpFieldValue)); } public static void setCMPFieldOfTypePrimitiveOrUnknown(SbbEntity sbbEntity, String cmpFieldName, boolean cmpFieldValue) { SbbAbstractMethodHandler.setCMPFieldOfTypePrimitiveOrUnknown(sbbEntity,cmpFieldName, Boolean.valueOf(cmpFieldValue)); } /** * * @param sbbEntity * @param cmpFieldName * @param cmpFieldValue */ public static void setCMPFieldOfTypeActivityContextInterface(SbbEntity sbbEntity, String cmpFieldName, ActivityContextInterface cmpFieldValue) { if (cmpFieldValue == null) { sbbEntity.setCMPField(cmpFieldName, null); return; } org.mobicents.slee.container.activity.ActivityContextInterface aci = null; try { aci = (org.mobicents.slee.container.activity.ActivityContextInterface) cmpFieldValue; } catch (ClassCastException e) { throw new IllegalArgumentException("CMP value being set (" + cmpFieldValue + ") is an unknown ActivityContextInterface implementation"); } sbbEntity.setCMPField(cmpFieldName, aci.getActivityContext().getActivityContextHandle()); } /** * * @param sbbEntity * @param cmpFieldName * @param cmpFieldValue */ public static void setCMPFieldOfTypeEventContext(SbbEntity sbbEntity, String cmpFieldName, javax.slee.EventContext cmpFieldValue) { if (cmpFieldValue == null) { sbbEntity.setCMPField(cmpFieldName, null); return; } EventContext eventContextImpl = null; try { eventContextImpl = (EventContext) cmpFieldValue; } catch (ClassCastException e) { throw new IllegalArgumentException("CMP value being set (" + cmpFieldValue + ") is an unknown EventContext implementation"); } sbbEntity.setCMPField(cmpFieldName,eventContextImpl.getEventContextHandle()); } /** * * @param sbbEntity * @param cmpFieldName * @param cmpFieldValue */ public static void setCMPFieldOfTypePrimitiveOrUnknown(SbbEntity sbbEntity, String cmpFieldName, Object cmpFieldValue) { sbbEntity.setCMPField(cmpFieldName,cmpFieldValue); } /** * * @param sbbEntity * @param cmpFieldName * @param object */ public static void setCMPFieldOfTypeProfileLocalObject(SbbEntity sbbEntity, String cmpFieldName, javax.slee.profile.ProfileLocalObject cmpFieldValue) { if (cmpFieldValue == null) { sbbEntity.setCMPField(cmpFieldName, null); return; } ProfileLocalObject profileLocalObjectConcreteImpl = null; try { profileLocalObjectConcreteImpl = (ProfileLocalObject) cmpFieldValue; } catch (ClassCastException e) { throw new IllegalArgumentException("CMP value being set (" + cmpFieldValue + ") is an unknown ProfileLocalObject implementation"); } final ProfileLocalObjectCmpValue profileLocalObjectCmpValue = new ProfileLocalObjectCmpValue(profileLocalObjectConcreteImpl.getProfileTableName(),profileLocalObjectConcreteImpl.getProfileName()); sbbEntity.setCMPField(cmpFieldName, profileLocalObjectCmpValue); } /** * * @param sbbEntity * @param cmpFieldName * @param cmpFieldValue */ public static void setCMPFieldOfTypeSbbLocalObject(SbbEntity sbbEntity, String cmpFieldName, SbbLocalObject cmpFieldValue) { if (cmpFieldValue == null) { sbbEntity.setCMPField(cmpFieldName, null); return; } SbbLocalObjectImpl sbbLocalObjectImpl = null; try { sbbLocalObjectImpl = (SbbLocalObjectImpl) cmpFieldValue; } catch (ClassCastException e) { throw new IllegalArgumentException("CMP value being set ("+ cmpFieldValue+ ") is an unknown SbbLocalObject implementation"); } final CMPFieldDescriptor field = sbbEntity.getSbbComponent().getDescriptor().getCmpFields().get(cmpFieldName); if (field.getSbbRef() != null && !field.getSbbRef().equals(sbbLocalObjectImpl.getSbbEntity().getSbbComponent().getSbbID())) { throw new IllegalArgumentException("CMP value being set ("+ sbbLocalObjectImpl.getSbbEntity().getSbbComponent().getSbbID()+ ") is for a different sbb then the one expected ("+ field.getSbbRef() + ")"); } sbbEntity.setCMPField(cmpFieldName, sbbLocalObjectImpl.getSbbEntityId()); } /** * * @param cmpFieldName * @param returnType * @return */ public static Object getCMPFieldOfTypeUnknown(SbbEntity sbbEntity,String cmpFieldName) { return sbbEntity.getCMPField(cmpFieldName); } /** * * @param cmpFieldName * @return */ public static Integer getCMPFieldOfTypeInteger(SbbEntity sbbEntity,String cmpFieldName) { final Object cmpFieldValue = sbbEntity.getCMPField(cmpFieldName); if (cmpFieldValue == null) { return DEFAULT_CMP_VALUE_INTEGER; } else { return (Integer) cmpFieldValue; } } /** * * @param cmpFieldName * @return */ public static Boolean getCMPFieldOfTypeBoolean(SbbEntity sbbEntity,String cmpFieldName) { final Object cmpFieldValue = sbbEntity.getCMPField(cmpFieldName); if (cmpFieldValue == null) { return DEFAULT_CMP_VALUE_BOOLEAN; } else { return (Boolean) cmpFieldValue; } } /** * * @param cmpFieldName * @return */ public static Byte getCMPFieldOfTypeByte(SbbEntity sbbEntity,String cmpFieldName) { final Object cmpFieldValue = sbbEntity.getCMPField(cmpFieldName); if (cmpFieldValue == null) { return DEFAULT_CMP_VALUE_BYTE; } else { return (Byte) cmpFieldValue; } } /** * * @param cmpFieldName * @return */ public static Character getCMPFieldOfTypeChar(SbbEntity sbbEntity,String cmpFieldName) { final Object cmpFieldValue = sbbEntity.getCMPField(cmpFieldName); if (cmpFieldValue == null) { return DEFAULT_CMP_VALUE_CHAR; } else { return (Character) cmpFieldValue; } } /** * * @param cmpFieldName * @return */ public static Short getCMPFieldOfTypeShort(SbbEntity sbbEntity,String cmpFieldName) { final Object cmpFieldValue = sbbEntity.getCMPField(cmpFieldName); if (cmpFieldValue == null) { return DEFAULT_CMP_VALUE_SHORT; } else { return (Short) cmpFieldValue; } } /** * * @param cmpFieldName * @return */ public static Long getCMPFieldOfTypeLong(SbbEntity sbbEntity,String cmpFieldName) { final Object cmpFieldValue = sbbEntity.getCMPField(cmpFieldName); if (cmpFieldValue == null) { return DEFAULT_CMP_VALUE_LONG; } else { return (Long) cmpFieldValue; } } /** * * @param cmpFieldName * @return */ public static Double getCMPFieldOfTypeDouble(SbbEntity sbbEntity,String cmpFieldName) { final Object cmpFieldValue = sbbEntity.getCMPField(cmpFieldName); if (cmpFieldValue == null) { return DEFAULT_CMP_VALUE_DOUBLE; } else { return (Double) cmpFieldValue; } } /** * * @param cmpFieldName * @return */ public static Float getCMPFieldOfTypeFloat(SbbEntity sbbEntity,String cmpFieldName) { final Object cmpFieldValue = sbbEntity.getCMPField(cmpFieldName); if (cmpFieldValue == null) { return DEFAULT_CMP_VALUE_FLOAT; } else { return (Float) cmpFieldValue; } } /** * * @param sbbEntity * @param cmpFieldName * @return */ public static ActivityContextInterface getCMPFieldOfTypeActivityContextInterface(SbbEntity sbbEntity,String cmpFieldName) { final Object cmpFieldValue = sbbEntity.getCMPField(cmpFieldName); if (cmpFieldValue == null) { return null; } else { final ActivityContext ac = sleeContainer.getActivityContextFactory().getActivityContext((ActivityContextHandle) cmpFieldValue); if (ac != null) { return sbbEntity.asSbbActivityContextInterface(ac.getActivityContextInterface()); } else { return null; } } } /** * * @param sbbEntity * @param cmpFieldName * @return */ public static javax.slee.EventContext getCMPFieldOfTypeEventContext(SbbEntity sbbEntity,String cmpFieldName) { final Object cmpFieldValue = sbbEntity.getCMPField(cmpFieldName); if (cmpFieldValue == null) { return null; } else { return sleeContainer.getEventContextFactory().getEventContext((EventContextHandle)cmpFieldValue); } } /** * * @param sbbEntity * @param cmpFieldName * @return */ public static javax.slee.profile.ProfileLocalObject getCMPFieldOfTypeProfileLocalObject(SbbEntity sbbEntity,String cmpFieldName) { final Object cmpFieldValue = sbbEntity.getCMPField(cmpFieldName); if (cmpFieldValue == null) { return null; } else { final ProfileLocalObjectCmpValue profileLocalObjectCmpValue = (ProfileLocalObjectCmpValue) cmpFieldValue; try { final ProfileTable profileTable = sleeContainer.getSleeProfileTableManager().getProfileTable(profileLocalObjectCmpValue.getProfileTableName()); return profileTable.find(profileLocalObjectCmpValue.getProfileName()); } catch (UnrecognizedProfileTableNameException e) { return null; } } } /** * * @param sbbEntity * @param cmpFieldName * @return */ public static SbbLocalObject getCMPFieldOfTypeSbbLocalObject(SbbEntity sbbEntity,String cmpFieldName) { final Object cmpFieldValue = sbbEntity.getCMPField(cmpFieldName); if (cmpFieldValue == null) { return null; } else { final SbbEntity anotherSbbEntity = sleeContainer.getSbbEntityFactory().getSbbEntity((SbbEntityID) cmpFieldValue,false); if (anotherSbbEntity == null) return null; else if (anotherSbbEntity.isRemoved()) return null; else { return anotherSbbEntity.getSbbLocalObject(); } } } // CHILD RELATION GETTER /** * Retrieves the {@link ChildRelation} for the specified sbb entity and get * child relation method name */ public static ChildRelation getChildRelation(SbbEntity sbbEntity, String childRelationMethodName) { if (sbbEntity.getSbbObject().getState() != SbbObjectState.READY) throw new IllegalStateException( "Could not invoke getChildRelation Method, Sbb Object is not in the READY state!"); if (logger.isTraceEnabled()) { logger.trace("ChildRelation Interceptor:" + childRelationMethodName); } return sbbEntity.getChildRelation(childRelationMethodName); } // EVENT FIRING /** * The logic to fire an event from an SLEE 1.0 Sbb * * @param sbbEntity * an sbb entity with an object assigned * @param eventTypeID * the id of the event to fire * @param eventObject * the event object, can't be null * @param aci * the activity context where the event will be fired, can't be * null * @param address * the optional address to fire the event */ public static void fireEvent(SbbEntity sbbEntity, EventTypeID eventTypeID, Object eventObject, ActivityContextInterface aci, Address address) { fireEvent(sbbEntity, eventTypeID, eventObject, aci, address, null); } /** * The logic to fire an event from an SLEE 1.1 Sbb * * @param sbbEntity * an sbb entity with an object assigned * @param eventTypeID * the id of the event to fire * @param eventObject * the event object, can't be null * @param aci * the activity context where the event will be fired, can't be * null * @param address * the optional address to fire the event * @param serviceID * the optional service id to fire the event */ public static void fireEvent(SbbEntity sbbEntity, EventTypeID eventTypeID, Object eventObject, ActivityContextInterface aci, Address address, ServiceID serviceID) { if (sleeContainer.getCongestionControl().refuseFireEvent()) { throw new SLEEException("congestion control refused event"); } // JAIN SLEE (TM) specs - Section 8.4.1 // The SBB object must have an assigned SBB entity when it invokes this // method. // Otherwise, this method throws a java.lang.IllegalStateException. if (sbbEntity == null || sbbEntity.getSbbObject() == null || sbbEntity.getSbbObject().getState() != SbbObjectState.READY) throw new IllegalStateException("SbbObject not assigned!"); // JAIN SLEE (TM) specs - Section 8.4.1 // The event ... cannot be null. If ... argument is null, the fire // event method throws a java.lang.NullPointerException. if (eventObject == null) throw new NullPointerException( "JAIN SLEE (TM) specs - Section 8.4.1: The event ... cannot be null. If ... argument is null, the fire event method throws a java.lang.NullPointerException."); // JAIN SLEE (TM) specs - Section 8.4.1 // The activity ... cannot be null. If ... argument is null, the fire // event method throws a java.lang.NullPointerException. if (aci == null) throw new NullPointerException( "JAIN SLEE (TM) specs - Section 8.4.1: The activity ... cannot be null. If ... argument is null, the fire event method throws a java.lang.NullPointerException."); // JAIN SLEE (TM) specs - Section 8.4.1 // It is a mandatory transactional method (see Section 9.6.1). final SleeTransactionManager txManager = sleeContainer.getTransactionManager(); txManager.mandateTransaction(); // rebuild the ac from the aci in the 2nd argument of the invoked // method, check it's state ActivityContext ac = ((org.mobicents.slee.container.activity.ActivityContextInterface) aci) .getActivityContext(); if (logger.isTraceEnabled()) { logger.trace("invoke(): firing event on " + ac); } // exception not in specs by mandated by // tests/activities/activitycontext/Test560Test.xml , it's preferable to // do double check on here than have the aci fire method throwing it and // the ra slee endpoint having to translate it to activity ending // exception, it is not common to have custom event firing in sbbs if (ac.isEnding()) { throw new IllegalStateException("activity context " + ac.getActivityContextHandle() + " is ending"); } final EventRoutingTransactionData transactionData = txManager.getTransactionContext().getEventRoutingTransactionData(); if (transactionData != null) { final EventContext eventBeingDelivered = transactionData.getEventBeingDelivered(); if (eventBeingDelivered != null && eventBeingDelivered.getEvent() == eventObject) { // there is an event being delivered by this tx and it matches the event being fired, lets copy the ref handler // fire the event ac.fireEvent(eventTypeID, eventObject, (Address) address, serviceID, eventBeingDelivered); return; } } // seems it is not a refire ac.fireEvent(eventTypeID, eventObject, (Address) address, serviceID, null, null, null); } // GET PROFILE CMP METHODS /** * Retrieves a profile given the cmp method name and profile id */ public static Object getProfileCMPMethod(SbbEntity sbbEntity, String getProfileCMPMethodName, ProfileID profileID) throws UnrecognizedProfileTableNameException, UnrecognizedProfileNameException { GetProfileCMPMethodDescriptor mGetProfileCMPMethod = sbbEntity.getSbbComponent() .getDescriptor().getGetProfileCMPMethods().get( getProfileCMPMethodName); if (mGetProfileCMPMethod == null) throw new AbstractMethodError("Profile CMP Method not found"); if (sbbEntity.getSbbObject().getState() != SbbObjectState.READY) { throw new IllegalStateException( "Could not invoke getProfileCMP Method, Sbb Object is not in the READY state!"); } ProfileManagement sleeProfileManager = sleeContainer .getSleeProfileTableManager(); ProfileTable profileTable = sleeProfileManager.getProfileTable(profileID.getProfileTableName()); if (!profileTable.profileExists(profileID.getProfileName())) { throw new UnrecognizedProfileNameException(profileID.toString()); } return profileTable.getProfile(profileID.getProfileName()).getProfileCmpSlee10Wrapper(); } // SBB USAGE PARAMS public static Object getSbbUsageParameterSet(SbbEntity sbbEntity, String name) throws UnrecognizedUsageParameterSetNameException { if (logger.isTraceEnabled()) { logger.trace("getSbbUsageParameterSet(): serviceId = " + sbbEntity.getSbbEntityId().getServiceID() + " , sbbID = " + sbbEntity.getSbbId() + " , name = " + name); } return getServiceUsageMBeanImpl(sbbEntity.getSbbEntityId().getServiceID()) .getInstalledUsageParameterSet(sbbEntity.getSbbId(), name); } public static Object getDefaultSbbUsageParameterSet(SbbEntity sbbEntity) { if (logger.isTraceEnabled()) { logger.trace("getDefaultSbbUsageParameterSet(): " + sbbEntity.getSbbEntityId().getServiceID() + " sbbID = " + sbbEntity.getSbbId()); } return getServiceUsageMBeanImpl(sbbEntity.getSbbEntityId().getServiceID()) .getDefaultInstalledUsageParameterSet(sbbEntity.getSbbId()); } private static ServiceUsageMBeanImpl getServiceUsageMBeanImpl( ServiceID serviceID) { return (ServiceUsageMBeanImpl) sleeContainer .getComponentRepository().getComponentByID(serviceID) .getServiceUsageMBean(); } }