/* * Mobicents, Communications Middleware * * Copyright (c) 2008, Red Hat Middleware LLC or third-party * contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are * distributed under license by Red Hat Middleware LLC. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * This program 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 distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * * Boston, MA 02110-1301 USA */ package org.mobicents.slee.resource.diameter.sh.client; import net.java.slee.resource.diameter.base.DiameterAvpFactory; import net.java.slee.resource.diameter.base.NoSuchAvpException; import net.java.slee.resource.diameter.base.events.DiameterHeader; import net.java.slee.resource.diameter.base.events.DiameterMessage; import net.java.slee.resource.diameter.base.events.avp.AvpNotAllowedException; import net.java.slee.resource.diameter.base.events.avp.DiameterAvp; import net.java.slee.resource.diameter.base.events.avp.DiameterAvpCodes; import net.java.slee.resource.diameter.base.events.avp.DiameterIdentity; import net.java.slee.resource.diameter.base.events.avp.GroupedAvp; import net.java.slee.resource.diameter.sh.client.MessageFactory; import net.java.slee.resource.diameter.sh.client.ShClientMessageFactory; import net.java.slee.resource.diameter.sh.client.events.PushNotificationRequest; import net.java.slee.resource.diameter.sh.client.events.avp.DataReferenceType; import net.java.slee.resource.diameter.sh.client.events.avp.SubsReqType; import net.java.slee.resource.diameter.sh.client.events.avp.UserIdentityAvp; import net.java.slee.resource.diameter.sh.server.events.ProfileUpdateRequest; import net.java.slee.resource.diameter.sh.server.events.PushNotificationAnswer; import net.java.slee.resource.diameter.sh.server.events.SubscribeNotificationsRequest; import net.java.slee.resource.diameter.sh.server.events.UserDataRequest; import org.apache.log4j.Logger; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpSet; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.Session; import org.jdiameter.api.Stack; import org.jdiameter.client.impl.helpers.UIDGenerator; import org.mobicents.slee.resource.diameter.base.DiameterAvpFactoryImpl; import org.mobicents.slee.resource.diameter.base.DiameterMessageFactoryImpl; import org.mobicents.slee.resource.diameter.sh.server.events.ProfileUpdateRequestImpl; import org.mobicents.slee.resource.diameter.sh.server.events.PushNotificationAnswerImpl; import org.mobicents.slee.resource.diameter.sh.server.events.SubscribeNotificationsRequestImpl; import org.mobicents.slee.resource.diameter.sh.server.events.UserDataRequestImpl; /** * * Start time:16:43:52 2009-05-23<br> * Project: diameter-parent<br> * Implementation of sh client message factory. * @author <a href="mailto:baranowb@gmail.com">baranowb - Bartosz Baranowski * </a> * @author <a href="mailto:brainslog@gmail.com"> Alexandre Mendonca </a> * @see ShClientMessageFactory */ public class ShClientMessageFactoryImpl implements ShClientMessageFactory { protected Session session; protected Stack stack; protected DiameterMessageFactoryImpl baseFactory = null; protected DiameterAvpFactory baseAvpFactory = null; private static Logger logger = Logger.getLogger(ShClientMessageFactoryImpl.class); // Used for generating session id's protected static UIDGenerator uid = new UIDGenerator(); public ShClientMessageFactoryImpl(Session session, Stack stack) { super(); this.session = session; this.stack = stack; this.baseFactory = new DiameterMessageFactoryImpl(this.session, this.stack); this.baseAvpFactory = new DiameterAvpFactoryImpl(); } public ShClientMessageFactoryImpl(Stack stack) { super(); this.stack = stack; this.baseFactory = new DiameterMessageFactoryImpl(this.stack); this.baseAvpFactory = new DiameterAvpFactoryImpl(); } public ProfileUpdateRequest createProfileUpdateRequest(UserIdentityAvp userIdentity, DataReferenceType reference, byte[] userData) { ProfileUpdateRequest pur = this.createProfileUpdateRequest(); pur.setUserIdentity(userIdentity); pur.setDataReference(reference); pur.setUserData(new String(userData)); return pur; } public ProfileUpdateRequest createProfileUpdateRequest() { //ApplicationId applicationId = ApplicationId.createByAuthAppId(_SH_VENDOR_ID, _SH_APP_ID); //Message msg = createMessage(ProfileUpdateRequest.commandCode, applicationId, null); //msg.setRequest(true); DiameterAvp[] avps = new DiameterAvp[0]; if(session != null) { try { DiameterAvp sessionIdAvp = null; sessionIdAvp = baseAvpFactory.createAvp(0, DiameterAvpCodes.SESSION_ID, session.getSessionId()); avps = new DiameterAvp[]{sessionIdAvp}; } catch (NoSuchAvpException e) { logger.error( "Unexpected failure trying to create Session-Id AVP.", e ); } } Message msg = createShMessage(null, avps, ProfileUpdateRequest.commandCode); ProfileUpdateRequestImpl pur = new ProfileUpdateRequestImpl(msg); addOrigin(pur); return pur; } public PushNotificationAnswer createPushNotificationAnswer(PushNotificationRequest request,long resultCode, boolean isExperimentalResultCode) { PushNotificationAnswer pna = this.createPushNotificationAnswer(request); if (isExperimentalResultCode) { pna.setExperimentalResult(this.baseAvpFactory.createExperimentalResult(0, resultCode)); } else { pna.setResultCode(resultCode); } return pna; } public PushNotificationAnswer createPushNotificationAnswer(PushNotificationRequest request) { //ApplicationId applicationId = ApplicationId.createByAuthAppId(_SH_VENDOR_ID, _SH_APP_ID); //Message msg = createMessage(PushNotificationAnswer.commandCode, applicationId, null); //msg.setRequest(false); DiameterAvp[] avps = new DiameterAvp[0]; try { DiameterAvp sessionIdAvp = null; sessionIdAvp = baseAvpFactory.createAvp(0, DiameterAvpCodes.SESSION_ID, request.getSessionId()); avps = new DiameterAvp[]{sessionIdAvp}; } catch (NoSuchAvpException e) { logger.error( "Unexpected failure trying to create Session-Id AVP.", e ); } Message msg = createShMessage(request.getHeader(), avps, PushNotificationAnswer.commandCode); PushNotificationAnswerImpl pna = new PushNotificationAnswerImpl(msg); addOrigin(pna); return pna; } public SubscribeNotificationsRequest createSubscribeNotificationsRequest(UserIdentityAvp userIdentity, DataReferenceType reference, SubsReqType subscriptionType) { SubscribeNotificationsRequest snr=this.createSubscribeNotificationsRequest(); snr.setUserIdentity(userIdentity); snr.setDataReference(reference); snr.setSubsReqType(subscriptionType); return snr; } public SubscribeNotificationsRequest createSubscribeNotificationsRequest() { //ApplicationId applicationId = ApplicationId.createByAuthAppId(_SH_VENDOR_ID, _SH_APP_ID); //Message msg = createMessage(SubscribeNotificationsRequest.commandCode, applicationId, null); //msg.setRequest(true); DiameterAvp[] avps = new DiameterAvp[0]; if(session != null) { try { DiameterAvp sessionIdAvp = null; sessionIdAvp = baseAvpFactory.createAvp(0, DiameterAvpCodes.SESSION_ID, session.getSessionId()); avps = new DiameterAvp[]{sessionIdAvp}; } catch (NoSuchAvpException e) { logger.error( "Unexpected failure trying to create Session-Id AVP.", e ); } } Message msg = createShMessage(null, avps, SubscribeNotificationsRequest.commandCode); SubscribeNotificationsRequestImpl snr = new SubscribeNotificationsRequestImpl(msg); addOrigin(snr); return snr; } public UserDataRequest createUserDataRequest(UserIdentityAvp userIdentity, DataReferenceType reference) { UserDataRequest udr = this.createUserDataRequest(); udr.setUserIdentity(userIdentity); udr.setDataReference(reference); return udr; } public UserDataRequest createUserDataRequest() { // ApplicationId applicationId = ApplicationId.createByAuthAppId(_SH_VENDOR_ID, _SH_APP_ID); // Message msg = createMessage(UserDataRequest.commandCode, applicationId, null); // msg.setRequest(true); DiameterAvp[] avps = new DiameterAvp[0]; if(session!=null) { try { DiameterAvp sessionIdAvp = null; sessionIdAvp = baseAvpFactory.createAvp(0, DiameterAvpCodes.SESSION_ID, session.getSessionId()); avps = new DiameterAvp[]{sessionIdAvp}; } catch (NoSuchAvpException e) { logger.error( "Unexpected failure trying to create Session-Id AVP.", e ); } } Message msg = createShMessage(null, avps, UserDataRequest.commandCode); UserDataRequestImpl udr = new UserDataRequestImpl(msg); addOrigin(udr); return udr; } // // FIXME: This has been copied from base // protected Message createMessage(int commandCode, ApplicationId applicationId, DiameterAvp[] avps) { // Message msg = null; // // if (session == null) { // try { // msg = stack.getSessionFactory().getNewRawSession().createMessage(commandCode, applicationId); // } catch (InternalException e) { // // TODO Auto-generated catch block // logger.error("", e); // } catch (IllegalDiameterStateException e) { // // TODO Auto-generated catch block // logger.error("", e); // } // } else { // String destRealm = null; // String destHost = null; // if(avps!=null) // for (DiameterAvp avp : avps) { // if (avp.getCode() == Avp.DESTINATION_REALM) // destRealm = avp.octetStringValue(); // else if (avp.getCode() == Avp.DESTINATION_HOST) // destHost = avp.octetStringValue(); // } // // msg = destHost == null ? session.createRequest(commandCode, applicationId, destRealm) : session.createRequest(commandCode, applicationId, destRealm, destHost); // } // // if (avps != null) { // for (DiameterAvp avp : avps) { // addAvp(avp, msg.getAvps()); // } // } // // // Do we have a session-id already or shall we make one? // if (msg.getAvps().getAvp(Avp.SESSION_ID) == null) // msg.getAvps().addAvp(Avp.SESSION_ID, this.baseFactory.generateSessionId(), true, false, false); // // msg.setProxiable( true ); // // return msg; // } private Message createShMessage(DiameterHeader diameterHeader, DiameterAvp[] avps, int _commandCode) throws IllegalArgumentException { // List<DiameterAvp> list = (List<DiameterAvp>) this.avpList.clone(); boolean isRequest = diameterHeader == null; Message msg = null; if (!isRequest) { Message raw = createMessage(diameterHeader, avps,0); raw.setProxiable(true); raw.setRequest(false); msg = raw; } else { Message raw = createMessage(null, avps,_commandCode); raw.setProxiable(true); raw.setRequest(true); msg = raw; } // now now we msut add VendorSpecific? return msg; } protected Message createMessage(DiameterHeader header, DiameterAvp[] avps, int commandCode) throws AvpNotAllowedException { try { Message msg = createRawMessage(header,commandCode); AvpSet set = msg.getAvps(); for (DiameterAvp avp : avps) addAvp(avp, set); if (msg.getAvps().getAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID) == null) { DiameterAvp avpVendorId = this.baseAvpFactory.createAvp(Avp.VENDOR_ID, MessageFactory._SH_VENDOR_ID); DiameterAvp avpAcctApplicationId = this.baseAvpFactory.createAvp(Avp.ACCT_APPLICATION_ID, MessageFactory._SH_APP_ID); DiameterAvp vendorSpecific = this.baseAvpFactory.createAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID, new DiameterAvp[] { avpVendorId, avpAcctApplicationId }); msg.getAvps().addAvp(vendorSpecific.getCode(), vendorSpecific.byteArrayValue()); } return msg; } catch (Exception e) { e.printStackTrace(); } return null; } protected Message createRawMessage(DiameterHeader header, int _commandCode) { int commandCode = 0; long endToEndId = 0; long hopByHopId = 0; ApplicationId aid = null; if (header != null) { commandCode = header.getCommandCode(); endToEndId = header.getEndToEndId(); hopByHopId = header.getHopByHopId(); aid = ApplicationId.createByAuthAppId(header.getApplicationId()); } else { commandCode = _commandCode; //endToEndId = (long) (Math.random()*1000000); //hopByHopId = (long) (Math.random()*1000000)+1; aid = ApplicationId.createByAuthAppId(_SH_VENDOR_ID, _SH_APP_ID); } try { if(header!=null) return stack.getSessionFactory().getNewRawSession().createMessage(commandCode, aid, hopByHopId, endToEndId); else return stack.getSessionFactory().getNewRawSession().createMessage(commandCode, aid); } catch (InternalException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalDiameterStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } protected void addAvp(DiameterAvp avp, AvpSet set) { // FIXME: alexandre: Should we look at the types and add them with // proper function? if (avp instanceof GroupedAvp) { AvpSet avpSet = set.addGroupedAvp(avp.getCode(), avp.getVendorId(), avp.getMandatoryRule() == 1, avp.getProtectedRule() == 1); DiameterAvp[] groupedAVPs = ((GroupedAvp) avp).getExtensionAvps(); for (DiameterAvp avpFromGroup : groupedAVPs) { addAvp(avpFromGroup, avpSet); } } else if (avp != null) set.addAvp(avp.getCode(), avp.byteArrayValue(), avp.getVendorId(), avp.getMandatoryRule() == 1, avp.getProtectedRule() == 1); } //public DiameterMessageFactory getBaseMessageFactory() { // return this.baseFactory; //} private void addOrigin(DiameterMessage msg) { if(!msg.hasOriginHost()) msg.setOriginHost(new DiameterIdentity(stack.getMetaData().getLocalPeer().getUri().getFQDN().toString())); if(!msg.hasOriginRealm()) msg.setOriginRealm(new DiameterIdentity(stack.getMetaData().getLocalPeer().getRealmName())); } }